Browse Source

Merge pull request #5095 from Lperlind/temp-collisions

os2: Resolve temp allocator collisions
gingerBill 3 months ago
parent
commit
4a4294c2af

+ 42 - 41
core/os/os2/allocators.odin

@@ -8,43 +8,13 @@ file_allocator :: proc() -> runtime.Allocator {
 	return heap_allocator()
 	return heap_allocator()
 }
 }
 
 
-temp_allocator_proc :: runtime.arena_allocator_proc
-
 @(private="file")
 @(private="file")
 MAX_TEMP_ARENA_COUNT :: 2
 MAX_TEMP_ARENA_COUNT :: 2
-
+@(private="file")
+MAX_TEMP_ARENA_COLLISIONS :: MAX_TEMP_ARENA_COUNT - 1
 @(private="file", thread_local)
 @(private="file", thread_local)
 global_default_temp_allocator_arenas: [MAX_TEMP_ARENA_COUNT]runtime.Arena
 global_default_temp_allocator_arenas: [MAX_TEMP_ARENA_COUNT]runtime.Arena
 
 
-@(private="file", thread_local)
-global_default_temp_allocator_index: uint
-
-
-@(require_results)
-temp_allocator :: proc() -> runtime.Allocator {
-	arena := &global_default_temp_allocator_arenas[global_default_temp_allocator_index]
-	if arena.backing_allocator.procedure == nil {
-		arena.backing_allocator = heap_allocator()
-	}
-
-	return runtime.Allocator{
-		procedure = temp_allocator_proc,
-		data      = arena,
-	}
-}
-
-
-
-@(require_results)
-temp_allocator_temp_begin :: proc(loc := #caller_location) -> (temp: runtime.Arena_Temp) {
-	temp = runtime.arena_temp_begin(&global_default_temp_allocator_arenas[global_default_temp_allocator_index], loc)
-	return
-}
-
-temp_allocator_temp_end :: proc(temp: runtime.Arena_Temp, loc := #caller_location) {
-	runtime.arena_temp_end(temp, loc)
-}
-
 @(fini, private)
 @(fini, private)
 temp_allocator_fini :: proc() {
 temp_allocator_fini :: proc() {
 	for &arena in global_default_temp_allocator_arenas {
 	for &arena in global_default_temp_allocator_arenas {
@@ -53,18 +23,49 @@ temp_allocator_fini :: proc() {
 	global_default_temp_allocator_arenas = {}
 	global_default_temp_allocator_arenas = {}
 }
 }
 
 
-TEMP_ALLOCATOR_GUARD_END :: proc(temp: runtime.Arena_Temp, loc := #caller_location) {
-	runtime.arena_temp_end(temp, loc)
-	if temp.arena != nil {
-		global_default_temp_allocator_index = (global_default_temp_allocator_index-1)%MAX_TEMP_ARENA_COUNT
-	}
+Temp_Allocator :: struct {
+	using arena: ^runtime.Arena,
+	using allocator: runtime.Allocator,
+	tmp: runtime.Arena_Temp,
+	loc: runtime.Source_Code_Location,
+}
+	
+TEMP_ALLOCATOR_GUARD_END :: proc(temp: Temp_Allocator) {
+	runtime.arena_temp_end(temp.tmp, temp.loc)
 }
 }
 
 
 @(deferred_out=TEMP_ALLOCATOR_GUARD_END)
 @(deferred_out=TEMP_ALLOCATOR_GUARD_END)
-TEMP_ALLOCATOR_GUARD :: #force_inline proc(loc := #caller_location) -> (runtime.Arena_Temp, runtime.Source_Code_Location) {
-	global_default_temp_allocator_index = (global_default_temp_allocator_index+1)%MAX_TEMP_ARENA_COUNT
-	tmp := temp_allocator_temp_begin(loc)
-	return tmp, loc
+TEMP_ALLOCATOR_GUARD :: #force_inline proc(collisions: []runtime.Allocator, loc := #caller_location) -> Temp_Allocator {
+	assert(len(collisions) <= MAX_TEMP_ARENA_COLLISIONS, "Maximum collision count exceeded. MAX_TEMP_ARENA_COUNT must be increased!")
+	good_arena: ^runtime.Arena
+	for i in 0..<MAX_TEMP_ARENA_COUNT {
+		good_arena = &global_default_temp_allocator_arenas[i]
+		for c in collisions {
+			if good_arena == c.data {
+				good_arena = nil
+			}
+		}
+		if good_arena != nil {
+			break
+		}
+	}
+	assert(good_arena != nil)
+	if good_arena.backing_allocator.procedure == nil {
+		good_arena.backing_allocator = heap_allocator()
+	}
+	tmp := runtime.arena_temp_begin(good_arena, loc)
+	return { good_arena, runtime.arena_allocator(good_arena), tmp, loc }
+}
+
+temp_allocator_begin :: runtime.arena_temp_begin
+temp_allocator_end :: runtime.arena_temp_end
+@(deferred_out=_temp_allocator_end)
+temp_allocator_scope :: proc(tmp: Temp_Allocator) -> (runtime.Arena_Temp) {
+	return temp_allocator_begin(tmp.arena)
+}
+@(private="file")
+_temp_allocator_end :: proc(tmp: runtime.Arena_Temp) {
+	temp_allocator_end(tmp)
 }
 }
 
 
 @(init, private)
 @(init, private)

+ 7 - 7
core/os/os2/dir.odin

@@ -18,12 +18,12 @@ read_directory :: proc(f: ^File, n: int, allocator: runtime.Allocator) -> (files
 		size = 100
 		size = 100
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	it := read_directory_iterator_create(f)
 	it := read_directory_iterator_create(f)
 	defer _read_directory_iterator_destroy(&it)
 	defer _read_directory_iterator_destroy(&it)
 
 
-	dfi := make([dynamic]File_Info, 0, size, temp_allocator())
+	dfi := make([dynamic]File_Info, 0, size, temp_allocator)
 	defer if err != nil {
 	defer if err != nil {
 		for fi in dfi {
 		for fi in dfi {
 			file_info_delete(fi, allocator)
 			file_info_delete(fi, allocator)
@@ -202,13 +202,13 @@ copy_directory :: proc(dst, src: string, dst_perm := 0o755) -> Error {
 		return err
 		return err
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	file_infos := read_all_directory_by_path(src, temp_allocator()) or_return
+	file_infos := read_all_directory_by_path(src, temp_allocator) or_return
 	for fi in file_infos {
 	for fi in file_infos {
-		TEMP_ALLOCATOR_GUARD()
+		temp_allocator_scope(temp_allocator)
 
 
-		dst_path := join_path({dst, fi.name}, temp_allocator()) or_return
+		dst_path := join_path({dst, fi.name}, temp_allocator) or_return
 		src_path := fi.fullpath
 		src_path := fi.fullpath
 
 
 		if fi.type == .Directory {
 		if fi.type == .Directory {
@@ -218,4 +218,4 @@ copy_directory :: proc(dst, src: string, dst_perm := 0o755) -> Error {
 		}
 		}
 	}
 	}
 	return nil
 	return nil
-}
+}

+ 2 - 1
core/os/os2/dir_linux.odin

@@ -78,7 +78,8 @@ _read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info
 	it.impl.prev_fi = fi
 	it.impl.prev_fi = fi
 
 
 	if err != nil {
 	if err != nil {
-		path, _ := _get_full_path(entry_fd, temp_allocator())
+		temp_allocator := TEMP_ALLOCATOR_GUARD({})
+		path, _ := _get_full_path(entry_fd, temp_allocator)
 		read_directory_iterator_set_error(it, path, err)
 		read_directory_iterator_set_error(it, path, err)
 	}
 	}
 
 

+ 5 - 5
core/os/os2/dir_windows.odin

@@ -14,7 +14,9 @@ find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW, al
 	if d.cFileName[0] == '.' && d.cFileName[1] == '.' && d.cFileName[2] == 0 {
 	if d.cFileName[0] == '.' && d.cFileName[1] == '.' && d.cFileName[2] == 0 {
 		return
 		return
 	}
 	}
-	path := concatenate({base_path, `\`, win32_wstring_to_utf8(raw_data(d.cFileName[:]), temp_allocator()) or_else ""}, allocator) or_return
+
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	path := concatenate({base_path, `\`, win32_wstring_to_utf8(raw_data(d.cFileName[:]), temp_allocator) or_else ""}, allocator) or_return
 
 
 	handle := win32.HANDLE(_open_internal(path, {.Read}, 0o666) or_else 0)
 	handle := win32.HANDLE(_open_internal(path, {.Read}, 0o666) or_else 0)
 	defer win32.CloseHandle(handle)
 	defer win32.CloseHandle(handle)
@@ -49,8 +51,6 @@ Read_Directory_Iterator_Impl :: struct {
 
 
 @(require_results)
 @(require_results)
 _read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info, index: int, ok: bool) {
 _read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info, index: int, ok: bool) {
-	TEMP_ALLOCATOR_GUARD()
-
 	for !it.impl.no_more_files {
 	for !it.impl.no_more_files {
 		err: Error
 		err: Error
 		file_info_delete(it.impl.prev_fi, file_allocator())
 		file_info_delete(it.impl.prev_fi, file_allocator())
@@ -116,9 +116,9 @@ _read_directory_iterator_init :: proc(it: ^Read_Directory_Iterator, f: ^File) {
 		wpath = impl.wname[:i]
 		wpath = impl.wname[:i]
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	wpath_search := make([]u16, len(wpath)+3, temp_allocator())
+	wpath_search := make([]u16, len(wpath)+3, temp_allocator)
 	copy(wpath_search, wpath)
 	copy(wpath_search, wpath)
 	wpath_search[len(wpath)+0] = '\\'
 	wpath_search[len(wpath)+0] = '\\'
 	wpath_search[len(wpath)+1] = '*'
 	wpath_search[len(wpath)+1] = '*'

+ 7 - 7
core/os/os2/env_posix.odin

@@ -12,9 +12,9 @@ _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string
 		return
 		return
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	ckey := strings.clone_to_cstring(key, temp_allocator())
+	ckey := strings.clone_to_cstring(key, temp_allocator)
 	cval := posix.getenv(ckey)
 	cval := posix.getenv(ckey)
 	if cval == nil {
 	if cval == nil {
 		return
 		return
@@ -27,10 +27,10 @@ _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string
 }
 }
 
 
 _set_env :: proc(key, value: string) -> (err: Error) {
 _set_env :: proc(key, value: string) -> (err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	ckey := strings.clone_to_cstring(key, temp_allocator()) or_return
-	cval := strings.clone_to_cstring(value, temp_allocator()) or_return
+	ckey := strings.clone_to_cstring(key, temp_allocator) or_return
+	cval := strings.clone_to_cstring(value, temp_allocator) or_return
 
 
 	if posix.setenv(ckey, cval, true) != nil {
 	if posix.setenv(ckey, cval, true) != nil {
 		err = _get_platform_error_from_errno()
 		err = _get_platform_error_from_errno()
@@ -39,9 +39,9 @@ _set_env :: proc(key, value: string) -> (err: Error) {
 }
 }
 
 
 _unset_env :: proc(key: string) -> (ok: bool) {
 _unset_env :: proc(key: string) -> (ok: bool) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	ckey := strings.clone_to_cstring(key, temp_allocator())
+	ckey := strings.clone_to_cstring(key, temp_allocator)
 
 
 	ok = posix.unsetenv(ckey) == .OK
 	ok = posix.unsetenv(ckey) == .OK
 	return
 	return

+ 2 - 2
core/os/os2/env_wasi.odin

@@ -39,9 +39,9 @@ build_env :: proc() -> (err: Error) {
 	g_env_buf = make([]byte, size_of_envs, file_allocator()) or_return
 	g_env_buf = make([]byte, size_of_envs, file_allocator()) or_return
 	defer if err != nil { delete(g_env_buf, file_allocator()) }
 	defer if err != nil { delete(g_env_buf, file_allocator()) }
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	envs := make([]cstring, num_envs, temp_allocator()) or_return
+	envs := make([]cstring, num_envs, temp_allocator) or_return
 
 
 	_err = wasi.environ_get(raw_data(envs), raw_data(g_env_buf))
 	_err = wasi.environ_get(raw_data(envs), raw_data(g_env_buf))
 	if _err != nil {
 	if _err != nil {

+ 10 - 10
core/os/os2/env_windows.odin

@@ -8,8 +8,8 @@ _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string
 	if key == "" {
 	if key == "" {
 		return
 		return
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
-	wkey, _ := win32_utf8_to_wstring(key, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	wkey, _ := win32_utf8_to_wstring(key, temp_allocator)
 
 
 	n := win32.GetEnvironmentVariableW(wkey, nil, 0)
 	n := win32.GetEnvironmentVariableW(wkey, nil, 0)
 	if n == 0 {
 	if n == 0 {
@@ -20,7 +20,7 @@ _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string
 		return "", true
 		return "", true
 	}
 	}
 
 
-	b := make([]u16, n+1, temp_allocator())
+	b := make([]u16, n+1, temp_allocator)
 
 
 	n = win32.GetEnvironmentVariableW(wkey, raw_data(b), u32(len(b)))
 	n = win32.GetEnvironmentVariableW(wkey, raw_data(b), u32(len(b)))
 	if n == 0 {
 	if n == 0 {
@@ -37,9 +37,9 @@ _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string
 }
 }
 
 
 _set_env :: proc(key, value: string) -> Error {
 _set_env :: proc(key, value: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	k := win32_utf8_to_wstring(key,   temp_allocator()) or_return
-	v := win32_utf8_to_wstring(value, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	k := win32_utf8_to_wstring(key,   temp_allocator) or_return
+	v := win32_utf8_to_wstring(value, temp_allocator) or_return
 
 
 	if !win32.SetEnvironmentVariableW(k, v) {
 	if !win32.SetEnvironmentVariableW(k, v) {
 		return _get_platform_error()
 		return _get_platform_error()
@@ -48,14 +48,14 @@ _set_env :: proc(key, value: string) -> Error {
 }
 }
 
 
 _unset_env :: proc(key: string) -> bool {
 _unset_env :: proc(key: string) -> bool {
-	TEMP_ALLOCATOR_GUARD()
-	k, _ := win32_utf8_to_wstring(key, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	k, _ := win32_utf8_to_wstring(key, temp_allocator)
 	return bool(win32.SetEnvironmentVariableW(k, nil))
 	return bool(win32.SetEnvironmentVariableW(k, nil))
 }
 }
 
 
 _clear_env :: proc() {
 _clear_env :: proc() {
-	TEMP_ALLOCATOR_GUARD()
-	envs, _ := environ(temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	envs, _ := environ(temp_allocator)
 	for env in envs {
 	for env in envs {
 		for j in 1..<len(env) {
 		for j in 1..<len(env) {
 			if env[j] == '=' {
 			if env[j] == '=' {

+ 2 - 2
core/os/os2/errors.odin

@@ -108,12 +108,12 @@ error_string :: proc(ferr: Error) -> string {
 }
 }
 
 
 print_error :: proc(f: ^File, ferr: Error, msg: string) {
 print_error :: proc(f: ^File, ferr: Error, msg: string) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 	err_str := error_string(ferr)
 	err_str := error_string(ferr)
 
 
 	// msg + ": " + err_str + '\n'
 	// msg + ": " + err_str + '\n'
 	length := len(msg) + 2 + len(err_str) + 1
 	length := len(msg) + 2 + len(err_str) + 1
-	buf := make([]u8, length, temp_allocator())
+	buf := make([]u8, length, temp_allocator)
 
 
 	copy(buf, msg)
 	copy(buf, msg)
 	buf[len(msg)] = ':'
 	buf[len(msg)] = ':'

+ 4 - 4
core/os/os2/file.odin

@@ -291,8 +291,8 @@ exists :: proc(path: string) -> bool {
 
 
 @(require_results)
 @(require_results)
 is_file :: proc(path: string) -> bool {
 is_file :: proc(path: string) -> bool {
-	TEMP_ALLOCATOR_GUARD()
-	fi, err := stat(path, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	fi, err := stat(path, temp_allocator)
 	if err != nil {
 	if err != nil {
 		return false
 		return false
 	}
 	}
@@ -303,8 +303,8 @@ is_dir :: is_directory
 
 
 @(require_results)
 @(require_results)
 is_directory :: proc(path: string) -> bool {
 is_directory :: proc(path: string) -> bool {
-	TEMP_ALLOCATOR_GUARD()
-	fi, err := stat(path, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	fi, err := stat(path, temp_allocator)
 	if err != nil {
 	if err != nil {
 		return false
 		return false
 	}
 	}

+ 29 - 29
core/os/os2/file_linux.odin

@@ -66,8 +66,8 @@ _standard_stream_init :: proc() {
 }
 }
 
 
 _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) {
 _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 
 
 	// Just default to using O_NOCTTY because needing to open a controlling
 	// Just default to using O_NOCTTY because needing to open a controlling
 	// terminal would be incredibly rare. This has no effect on files while
 	// terminal would be incredibly rare. This has no effect on files while
@@ -299,8 +299,8 @@ _truncate :: proc(f: ^File, size: i64) -> Error {
 }
 }
 
 
 _remove :: proc(name: string) -> Error {
 _remove :: proc(name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 
 
 	if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS + {.NOFOLLOW}); errno == .NONE {
 	if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS + {.NOFOLLOW}); errno == .NONE {
 		linux.close(fd)
 		linux.close(fd)
@@ -311,25 +311,25 @@ _remove :: proc(name: string) -> Error {
 }
 }
 
 
 _rename :: proc(old_name, new_name: string) -> Error {
 _rename :: proc(old_name, new_name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	old_name_cstr := temp_cstring(old_name) or_return
-	new_name_cstr := temp_cstring(new_name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	old_name_cstr := clone_to_cstring(old_name, temp_allocator) or_return
+	new_name_cstr := clone_to_cstring(new_name, temp_allocator) or_return
 
 
 	return _get_platform_error(linux.rename(old_name_cstr, new_name_cstr))
 	return _get_platform_error(linux.rename(old_name_cstr, new_name_cstr))
 }
 }
 
 
 _link :: proc(old_name, new_name: string) -> Error {
 _link :: proc(old_name, new_name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	old_name_cstr := temp_cstring(old_name) or_return
-	new_name_cstr := temp_cstring(new_name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	old_name_cstr := clone_to_cstring(old_name, temp_allocator) or_return
+	new_name_cstr := clone_to_cstring(new_name, temp_allocator) or_return
 
 
 	return _get_platform_error(linux.link(old_name_cstr, new_name_cstr))
 	return _get_platform_error(linux.link(old_name_cstr, new_name_cstr))
 }
 }
 
 
 _symlink :: proc(old_name, new_name: string) -> Error {
 _symlink :: proc(old_name, new_name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	old_name_cstr := temp_cstring(old_name) or_return
-	new_name_cstr := temp_cstring(new_name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	old_name_cstr := clone_to_cstring(old_name, temp_allocator) or_return
+	new_name_cstr := clone_to_cstring(new_name, temp_allocator) or_return
 	return _get_platform_error(linux.symlink(old_name_cstr, new_name_cstr))
 	return _get_platform_error(linux.symlink(old_name_cstr, new_name_cstr))
 }
 }
 
 
@@ -352,14 +352,14 @@ _read_link_cstr :: proc(name_cstr: cstring, allocator: runtime.Allocator) -> (st
 }
 }
 
 
 _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, e: Error) {
 _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, e: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	return _read_link_cstr(name_cstr, allocator)
 	return _read_link_cstr(name_cstr, allocator)
 }
 }
 
 
 _chdir :: proc(name: string) -> Error {
 _chdir :: proc(name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	return _get_platform_error(linux.chdir(name_cstr))
 	return _get_platform_error(linux.chdir(name_cstr))
 }
 }
 
 
@@ -369,8 +369,8 @@ _fchdir :: proc(f: ^File) -> Error {
 }
 }
 
 
 _chmod :: proc(name: string, mode: int) -> Error {
 _chmod :: proc(name: string, mode: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)(u32(mode))))
 	return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)(u32(mode))))
 }
 }
 
 
@@ -381,15 +381,15 @@ _fchmod :: proc(f: ^File, mode: int) -> Error {
 
 
 // NOTE: will throw error without super user priviledges
 // NOTE: will throw error without super user priviledges
 _chown :: proc(name: string, uid, gid: int) -> Error {
 _chown :: proc(name: string, uid, gid: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	return _get_platform_error(linux.chown(name_cstr, linux.Uid(uid), linux.Gid(gid)))
 	return _get_platform_error(linux.chown(name_cstr, linux.Uid(uid), linux.Gid(gid)))
 }
 }
 
 
 // NOTE: will throw error without super user priviledges
 // NOTE: will throw error without super user priviledges
 _lchown :: proc(name: string, uid, gid: int) -> Error {
 _lchown :: proc(name: string, uid, gid: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	return _get_platform_error(linux.lchown(name_cstr, linux.Uid(uid), linux.Gid(gid)))
 	return _get_platform_error(linux.lchown(name_cstr, linux.Uid(uid), linux.Gid(gid)))
 }
 }
 
 
@@ -400,8 +400,8 @@ _fchown :: proc(f: ^File, uid, gid: int) -> Error {
 }
 }
 
 
 _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
 _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	times := [2]linux.Time_Spec {
 	times := [2]linux.Time_Spec {
 		{
 		{
 			uint(atime._nsec) / uint(time.Second),
 			uint(atime._nsec) / uint(time.Second),
@@ -431,8 +431,8 @@ _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
 }
 }
 
 
 _exists :: proc(name: string) -> bool {
 _exists :: proc(name: string) -> bool {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr, _ := temp_cstring(name)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	name_cstr, _ := clone_to_cstring(name, temp_allocator)
 	return linux.access(name_cstr, linux.F_OK) == .NONE
 	return linux.access(name_cstr, linux.F_OK) == .NONE
 }
 }
 
 
@@ -440,8 +440,8 @@ _exists :: proc(name: string) -> bool {
 _read_entire_pseudo_file :: proc { _read_entire_pseudo_file_string, _read_entire_pseudo_file_cstring }
 _read_entire_pseudo_file :: proc { _read_entire_pseudo_file_string, _read_entire_pseudo_file_cstring }
 
 
 _read_entire_pseudo_file_string :: proc(name: string, allocator: runtime.Allocator) -> (b: []u8, e: Error) {
 _read_entire_pseudo_file_string :: proc(name: string, allocator: runtime.Allocator) -> (b: []u8, e: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := clone_to_cstring(name, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 	return _read_entire_pseudo_file_cstring(name_cstr, allocator)
 	return _read_entire_pseudo_file_cstring(name_cstr, allocator)
 }
 }
 
 

+ 36 - 35
core/os/os2/file_posix.odin

@@ -69,8 +69,8 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err
 	if .Trunc       in flags { sys_flags += {.TRUNC} }
 	if .Trunc       in flags { sys_flags += {.TRUNC} }
 	if .Inheritable in flags { sys_flags -= {.CLOEXEC} }
 	if .Inheritable in flags { sys_flags -= {.CLOEXEC} }
 
 
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 
 
 	fd := posix.open(cname, sys_flags, transmute(posix.mode_t)posix._mode_t(perm))
 	fd := posix.open(cname, sys_flags, transmute(posix.mode_t)posix._mode_t(perm))
 	if fd < 0 {
 	if fd < 0 {
@@ -183,39 +183,39 @@ _truncate :: proc(f: ^File, size: i64) -> Error {
 	return nil
 	return nil
 }
 }
 
 
-_remove :: proc(name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+_remove :: proc(name: string) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 	if posix.remove(cname) != 0 {
 	if posix.remove(cname) != 0 {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-_rename :: proc(old_path, new_path: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cold := temp_cstring(old_path)
-	cnew := temp_cstring(new_path)
+_rename :: proc(old_path, new_path: string) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cold := clone_to_cstring(old_path, temp_allocator) or_return
+	cnew := clone_to_cstring(new_path, temp_allocator) or_return
 	if posix.rename(cold, cnew) != 0 {
 	if posix.rename(cold, cnew) != 0 {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-_link :: proc(old_name, new_name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cold := temp_cstring(old_name)
-	cnew := temp_cstring(new_name)
+_link :: proc(old_name, new_name: string) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cold := clone_to_cstring(old_name, temp_allocator) or_return
+	cnew := clone_to_cstring(new_name, temp_allocator) or_return
 	if posix.link(cold, cnew) != .OK {
 	if posix.link(cold, cnew) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-_symlink :: proc(old_name, new_name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cold := temp_cstring(old_name)
-	cnew := temp_cstring(new_name)
+_symlink :: proc(old_name, new_name: string) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cold := clone_to_cstring(old_name, temp_allocator) or_return
+	cnew := clone_to_cstring(new_name, temp_allocator) or_return
 	if posix.symlink(cold, cnew) != .OK {
 	if posix.symlink(cold, cnew) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
@@ -223,8 +223,8 @@ _symlink :: proc(old_name, new_name: string) -> Error {
 }
 }
 
 
 _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, err: Error) {
 _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	cname := clone_to_cstring(name, temp_allocator) or_return
 
 
 	buf: [dynamic]byte
 	buf: [dynamic]byte
 	buf.allocator = allocator
 	buf.allocator = allocator
@@ -268,9 +268,9 @@ _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, er
 	}
 	}
 }
 }
 
 
-_chdir :: proc(name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+_chdir :: proc(name: string) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 	if posix.chdir(cname) != .OK {
 	if posix.chdir(cname) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
@@ -291,9 +291,9 @@ _fchmod :: proc(f: ^File, mode: int) -> Error {
 	return nil
 	return nil
 }
 }
 
 
-_chmod :: proc(name: string, mode: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+_chmod :: proc(name: string, mode: int) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 	if posix.chmod(cname, transmute(posix.mode_t)posix._mode_t(mode)) != .OK {
 	if posix.chmod(cname, transmute(posix.mode_t)posix._mode_t(mode)) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
@@ -307,9 +307,9 @@ _fchown :: proc(f: ^File, uid, gid: int) -> Error {
 	return nil
 	return nil
 }
 }
 
 
-_chown :: proc(name: string, uid, gid: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+_chown :: proc(name: string, uid, gid: int) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 	if posix.chown(cname, posix.uid_t(uid), posix.gid_t(gid)) != .OK {
 	if posix.chown(cname, posix.uid_t(uid), posix.gid_t(gid)) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
@@ -317,15 +317,15 @@ _chown :: proc(name: string, uid, gid: int) -> Error {
 }
 }
 
 
 _lchown :: proc(name: string, uid, gid: int) -> Error {
 _lchown :: proc(name: string, uid, gid: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 	if posix.lchown(cname, posix.uid_t(uid), posix.gid_t(gid)) != .OK {
 	if posix.lchown(cname, posix.uid_t(uid), posix.gid_t(gid)) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-_chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
+_chtimes :: proc(name: string, atime, mtime: time.Time) -> (err: Error) {
 	times := [2]posix.timeval{
 	times := [2]posix.timeval{
 		{
 		{
 			tv_sec  = posix.time_t(atime._nsec/1e9),           /* seconds */
 			tv_sec  = posix.time_t(atime._nsec/1e9),           /* seconds */
@@ -337,8 +337,8 @@ _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
 		},
 		},
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 
 
 	if posix.utimes(cname, &times) != .OK {
 	if posix.utimes(cname, &times) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
@@ -365,8 +365,9 @@ _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
 }
 }
 
 
 _exists :: proc(path: string) -> bool {
 _exists :: proc(path: string) -> bool {
-	TEMP_ALLOCATOR_GUARD()
-	cpath := temp_cstring(path)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cpath, err := clone_to_cstring(path, temp_allocator)
+	if err != nil { return false }
 	return posix.access(cpath) == .OK
 	return posix.access(cpath) == .OK
 }
 }
 
 

+ 2 - 2
core/os/os2/file_posix_other.odin

@@ -7,8 +7,8 @@ import "base:runtime"
 import "core:sys/posix"
 import "core:sys/posix"
 
 
 _posix_absolute_path :: proc(fd: posix.FD, name: string, allocator: runtime.Allocator) -> (path: cstring, err: Error) {
 _posix_absolute_path :: proc(fd: posix.FD, name: string, allocator: runtime.Allocator) -> (path: cstring, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	cname := clone_to_cstring(name, temp_allocator)
 
 
 	buf: [posix.PATH_MAX]byte
 	buf: [posix.PATH_MAX]byte
 	path = posix.realpath(cname, raw_data(buf[:]))
 	path = posix.realpath(cname, raw_data(buf[:]))

+ 18 - 18
core/os/os2/file_windows.odin

@@ -109,9 +109,9 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u
 		err = .Not_Exist
 		err = .Not_Exist
 		return
 		return
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	path := _fix_long_path(name, temp_allocator()) or_return
+	path := _fix_long_path(name, temp_allocator) or_return
 	access: u32
 	access: u32
 	switch flags & {.Read, .Write} {
 	switch flags & {.Read, .Write} {
 	case {.Read}:         access = win32.FILE_GENERIC_READ
 	case {.Read}:         access = win32.FILE_GENERIC_READ
@@ -580,8 +580,8 @@ _truncate :: proc(f: ^File, size: i64) -> Error {
 }
 }
 
 
 _remove :: proc(name: string) -> Error {
 _remove :: proc(name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	p := _fix_long_path(name, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	p := _fix_long_path(name, temp_allocator) or_return
 	err, err1: Error
 	err, err1: Error
 	if !win32.DeleteFileW(p) {
 	if !win32.DeleteFileW(p) {
 		err = _get_platform_error()
 		err = _get_platform_error()
@@ -618,9 +618,9 @@ _remove :: proc(name: string) -> Error {
 }
 }
 
 
 _rename :: proc(old_path, new_path: string) -> Error {
 _rename :: proc(old_path, new_path: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	from := _fix_long_path(old_path, temp_allocator()) or_return
-	to   := _fix_long_path(new_path, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	from := _fix_long_path(old_path, temp_allocator) or_return
+	to   := _fix_long_path(new_path, temp_allocator) or_return
 	if win32.MoveFileExW(from, to, win32.MOVEFILE_REPLACE_EXISTING) {
 	if win32.MoveFileExW(from, to, win32.MOVEFILE_REPLACE_EXISTING) {
 		return nil
 		return nil
 	}
 	}
@@ -629,9 +629,9 @@ _rename :: proc(old_path, new_path: string) -> Error {
 }
 }
 
 
 _link :: proc(old_name, new_name: string) -> Error {
 _link :: proc(old_name, new_name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	o := _fix_long_path(old_name, temp_allocator()) or_return
-	n := _fix_long_path(new_name, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	o := _fix_long_path(old_name, temp_allocator) or_return
+	n := _fix_long_path(new_name, temp_allocator) or_return
 	if win32.CreateHardLinkW(n, o, nil) {
 	if win32.CreateHardLinkW(n, o, nil) {
 		return nil
 		return nil
 	}
 	}
@@ -692,9 +692,9 @@ _normalize_link_path :: proc(p: []u16, allocator: runtime.Allocator) -> (str: st
 		return "", _get_platform_error()
 		return "", _get_platform_error()
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buf := make([]u16, n+1, temp_allocator())
+	buf := make([]u16, n+1, temp_allocator)
 	n = win32.GetFinalPathNameByHandleW(handle, raw_data(buf), u32(len(buf)), win32.VOLUME_NAME_DOS)
 	n = win32.GetFinalPathNameByHandleW(handle, raw_data(buf), u32(len(buf)), win32.VOLUME_NAME_DOS)
 	if n == 0 {
 	if n == 0 {
 		return "", _get_platform_error()
 		return "", _get_platform_error()
@@ -718,9 +718,9 @@ _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, er
 	@thread_local
 	@thread_local
 	rdb_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]byte
 	rdb_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]byte
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	p      := _fix_long_path(name, temp_allocator()) or_return
+	p      := _fix_long_path(name, temp_allocator) or_return
 	handle := _open_sym_link(p) or_return
 	handle := _open_sym_link(p) or_return
 	defer win32.CloseHandle(handle)
 	defer win32.CloseHandle(handle)
 
 
@@ -785,8 +785,8 @@ _fchown :: proc(f: ^File, uid, gid: int) -> Error {
 }
 }
 
 
 _chdir :: proc(name: string) -> Error {
 _chdir :: proc(name: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	p := _fix_long_path(name, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	p := _fix_long_path(name, temp_allocator) or_return
 	if !win32.SetCurrentDirectoryW(p) {
 	if !win32.SetCurrentDirectoryW(p) {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
@@ -834,8 +834,8 @@ _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
 }
 }
 
 
 _exists :: proc(path: string) -> bool {
 _exists :: proc(path: string) -> bool {
-	TEMP_ALLOCATOR_GUARD()
-	wpath, _ := _fix_long_path(path, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	wpath, _ := _fix_long_path(path, temp_allocator)
 	attribs := win32.GetFileAttributesW(wpath)
 	attribs := win32.GetFileAttributesW(wpath)
 	return attribs != win32.INVALID_FILE_ATTRIBUTES
 	return attribs != win32.INVALID_FILE_ATTRIBUTES
 }
 }

+ 0 - 5
core/os/os2/internal_util.odin

@@ -43,11 +43,6 @@ clone_to_cstring :: proc(s: string, allocator: runtime.Allocator) -> (res: cstri
 	return cstring(&buf[0]), nil
 	return cstring(&buf[0]), nil
 }
 }
 
 
-@(require_results)
-temp_cstring :: proc(s: string) -> (cstring, runtime.Allocator_Error) #optional_allocator_error {
-	return clone_to_cstring(s, temp_allocator())
-}
-
 @(require_results)
 @(require_results)
 string_from_null_terminated_bytes :: proc(b: []byte) -> (res: string) {
 string_from_null_terminated_bytes :: proc(b: []byte) -> (res: string) {
 	s := string(b)
 	s := string(b)

+ 4 - 4
core/os/os2/path.odin

@@ -119,11 +119,11 @@ clean_path :: proc(path: string, allocator: runtime.Allocator) -> (cleaned: stri
 		return strings.clone(".", allocator)
 		return strings.clone(".", allocator)
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	// The extra byte is to simplify appending path elements by letting the
 	// The extra byte is to simplify appending path elements by letting the
 	// loop to end each with a separator. We'll trim the last one when we're done.
 	// loop to end each with a separator. We'll trim the last one when we're done.
-	buffer := make([]u8, len(path) + 1, temp_allocator()) or_return
+	buffer := make([]u8, len(path) + 1, temp_allocator) or_return
 
 
 	// This is the only point where Windows and POSIX differ, as Windows has
 	// This is the only point where Windows and POSIX differ, as Windows has
 	// alphabet-based volumes for root paths.
 	// alphabet-based volumes for root paths.
@@ -326,8 +326,8 @@ For example, `join_path({"/home", "foo", "bar.txt"})` will result in `"/home/foo
 join_path :: proc(elems: []string, allocator: runtime.Allocator) -> (joined: string, err: Error) {
 join_path :: proc(elems: []string, allocator: runtime.Allocator) -> (joined: string, err: Error) {
 	for e, i in elems {
 	for e, i in elems {
 		if e != "" {
 		if e != "" {
-			TEMP_ALLOCATOR_GUARD()
-			p := strings.join(elems[i:], Path_Separator_String, temp_allocator()) or_return
+			temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+			p := strings.join(elems[i:], Path_Separator_String, temp_allocator) or_return
 			return clean_path(p, allocator)
 			return clean_path(p, allocator)
 		}
 		}
 	}
 	}

+ 11 - 9
core/os/os2/path_linux.odin

@@ -18,8 +18,8 @@ _is_path_separator :: proc(c: byte) -> bool {
 }
 }
 
 
 _mkdir :: proc(path: string, perm: int) -> Error {
 _mkdir :: proc(path: string, perm: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	path_cstr := temp_cstring(path) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	path_cstr := clone_to_cstring(path, temp_allocator) or_return
 	return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)u32(perm)))
 	return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)u32(perm)))
 }
 }
 
 
@@ -52,9 +52,9 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 		}
 		}
 		return _get_platform_error(errno)
 		return _get_platform_error(errno)
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 	// need something we can edit, and use to generate cstrings
 	// need something we can edit, and use to generate cstrings
-	path_bytes := make([]u8, len(path) + 1, temp_allocator())
+	path_bytes := make([]u8, len(path) + 1, temp_allocator)
 
 
 	// zero terminate the byte slice to make it a valid cstring
 	// zero terminate the byte slice to make it a valid cstring
 	copy(path_bytes, path)
 	copy(path_bytes, path)
@@ -129,8 +129,8 @@ _remove_all :: proc(path: string) -> Error {
 		return nil
 		return nil
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
-	path_cstr := temp_cstring(path) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	path_cstr := clone_to_cstring(path, temp_allocator) or_return
 
 
 	fd, errno := linux.open(path_cstr, _OPENDIR_FLAGS)
 	fd, errno := linux.open(path_cstr, _OPENDIR_FLAGS)
 	#partial switch errno {
 	#partial switch errno {
@@ -168,14 +168,16 @@ _get_working_directory :: proc(allocator: runtime.Allocator) -> (string, Error)
 }
 }
 
 
 _set_working_directory :: proc(dir: string) -> Error {
 _set_working_directory :: proc(dir: string) -> Error {
-	dir_cstr := temp_cstring(dir) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+
+	dir_cstr := clone_to_cstring(dir, temp_allocator) or_return
 	return _get_platform_error(linux.chdir(dir_cstr))
 	return _get_platform_error(linux.chdir(dir_cstr))
 }
 }
 
 
 _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
 _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buf := make([dynamic]byte, 1024, temp_allocator()) or_return
+	buf := make([dynamic]byte, 1024, temp_allocator) or_return
 	for {
 	for {
 		n, errno := linux.readlink("/proc/self/exe", buf[:])
 		n, errno := linux.readlink("/proc/self/exe", buf[:])
 		if errno != .NONE {
 		if errno != .NONE {

+ 2 - 2
core/os/os2/path_netbsd.odin

@@ -5,9 +5,9 @@ import "base:runtime"
 import "core:sys/posix"
 import "core:sys/posix"
 
 
 _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
 _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buf := make([dynamic]byte, 1024, temp_allocator()) or_return
+	buf := make([dynamic]byte, 1024, temp_allocator) or_return
 	for {
 	for {
 		n := posix.readlink("/proc/curproc/exe", raw_data(buf), len(buf))
 		n := posix.readlink("/proc/curproc/exe", raw_data(buf), len(buf))
 		if n < 0 {
 		if n < 0 {

+ 3 - 3
core/os/os2/path_openbsd.odin

@@ -35,11 +35,11 @@ _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err
 		return real(arg, allocator)
 		return real(arg, allocator)
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buf := strings.builder_make(temp_allocator())
+	buf := strings.builder_make(temp_allocator)
 
 
-	paths := get_env("PATH", temp_allocator())
+	paths := get_env("PATH", temp_allocator)
 	for dir in strings.split_iterator(&paths, ":") {
 	for dir in strings.split_iterator(&paths, ":") {
 		strings.builder_reset(&buf)
 		strings.builder_reset(&buf)
 		strings.write_string(&buf, dir)
 		strings.write_string(&buf, dir)

+ 13 - 13
core/os/os2/path_posix.odin

@@ -14,9 +14,9 @@ _is_path_separator :: proc(c: byte) -> bool {
 	return c == _Path_Separator
 	return c == _Path_Separator
 }
 }
 
 
-_mkdir :: proc(name: string, perm: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name)
+_mkdir :: proc(name: string, perm: int) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cname := clone_to_cstring(name, temp_allocator) or_return
 	if posix.mkdir(cname, transmute(posix.mode_t)posix._mode_t(perm)) != .OK {
 	if posix.mkdir(cname, transmute(posix.mode_t)posix._mode_t(perm)) != .OK {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
@@ -28,13 +28,13 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 		return .Invalid_Path
 		return .Invalid_Path
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
 	if exists(path) {
 	if exists(path) {
 		return .Exist
 		return .Exist
 	}
 	}
 
 
-	clean_path := clean_path(path, temp_allocator()) or_return
+	clean_path := clean_path(path, temp_allocator) or_return
 	return internal_mkdir_all(clean_path, perm)
 	return internal_mkdir_all(clean_path, perm)
 
 
 	internal_mkdir_all :: proc(path: string, perm: int) -> Error {
 	internal_mkdir_all :: proc(path: string, perm: int) -> Error {
@@ -52,9 +52,9 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 	}
 	}
 }
 }
 
 
-_remove_all :: proc(path: string) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	cpath := temp_cstring(path)
+_remove_all :: proc(path: string) -> (err: Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cpath := clone_to_cstring(path, temp_allocator) or_return
 
 
 	dir := posix.opendir(cpath)
 	dir := posix.opendir(cpath)
 	if dir == nil {
 	if dir == nil {
@@ -78,7 +78,7 @@ _remove_all :: proc(path: string) -> Error {
 			continue
 			continue
 		}
 		}
 
 
-		fullpath, _ := concatenate({path, "/", string(cname), "\x00"}, temp_allocator())
+		fullpath, _ := concatenate({path, "/", string(cname), "\x00"}, temp_allocator)
 		if entry.d_type == .DIR {
 		if entry.d_type == .DIR {
 			_remove_all(fullpath[:len(fullpath)-1]) or_return
 			_remove_all(fullpath[:len(fullpath)-1]) or_return
 		} else {
 		} else {
@@ -95,10 +95,10 @@ _remove_all :: proc(path: string) -> Error {
 }
 }
 
 
 _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
 _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	buf: [dynamic]byte
 	buf: [dynamic]byte
-	buf.allocator = temp_allocator()
+	buf.allocator = temp_allocator
 	size := uint(posix.PATH_MAX)
 	size := uint(posix.PATH_MAX)
 
 
 	cwd: cstring
 	cwd: cstring
@@ -116,8 +116,8 @@ _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, er
 }
 }
 
 
 _set_working_directory :: proc(dir: string) -> (err: Error) {
 _set_working_directory :: proc(dir: string) -> (err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	cdir := temp_cstring(dir)
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	cdir := clone_to_cstring(dir, temp_allocator) or_return
 	if posix.chdir(cdir) != .OK {
 	if posix.chdir(cdir) != .OK {
 		err = _get_platform_error()
 		err = _get_platform_error()
 	}
 	}

+ 2 - 2
core/os/os2/path_posixfs.odin

@@ -31,8 +31,8 @@ _get_absolute_path :: proc(path: string, allocator: runtime.Allocator) -> (absol
 	if rel == "" {
 	if rel == "" {
 		rel = "."
 		rel = "."
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
-	rel_cstr := strings.clone_to_cstring(rel, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	rel_cstr := strings.clone_to_cstring(rel, temp_allocator)
 	path_ptr := posix.realpath(rel_cstr, nil)
 	path_ptr := posix.realpath(rel_cstr, nil)
 	if path_ptr == nil {
 	if path_ptr == nil {
 		return "", Platform_Error(posix.errno())
 		return "", Platform_Error(posix.errno())

+ 2 - 2
core/os/os2/path_wasi.odin

@@ -28,13 +28,13 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 		return .Invalid_Path
 		return .Invalid_Path
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
 	if exists(path) {
 	if exists(path) {
 		return .Exist
 		return .Exist
 	}
 	}
 
 
-	clean_path := clean_path(path, temp_allocator())
+	clean_path := clean_path(path, temp_allocator)
 	return internal_mkdir_all(clean_path)
 	return internal_mkdir_all(clean_path)
 
 
 	internal_mkdir_all :: proc(path: string) -> Error {
 	internal_mkdir_all :: proc(path: string) -> Error {

+ 18 - 18
core/os/os2/path_windows.odin

@@ -14,8 +14,8 @@ _is_path_separator :: proc(c: byte) -> bool {
 }
 }
 
 
 _mkdir :: proc(name: string, perm: int) -> Error {
 _mkdir :: proc(name: string, perm: int) -> Error {
-	TEMP_ALLOCATOR_GUARD()
-	if !win32.CreateDirectoryW(_fix_long_path(name, temp_allocator()) or_return, nil) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	if !win32.CreateDirectoryW(_fix_long_path(name, temp_allocator) or_return, nil) {
 		return _get_platform_error()
 		return _get_platform_error()
 	}
 	}
 	return nil
 	return nil
@@ -33,9 +33,9 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 		return p, false, nil
 		return p, false, nil
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	dir_stat, err := stat(path, temp_allocator())
+	dir_stat, err := stat(path, temp_allocator)
 	if err == nil {
 	if err == nil {
 		if dir_stat.type == .Directory {
 		if dir_stat.type == .Directory {
 			return nil
 			return nil
@@ -63,7 +63,7 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 
 
 	err = mkdir(path, perm)
 	err = mkdir(path, perm)
 	if err != nil {
 	if err != nil {
-		new_dir_stat, err1 := lstat(path, temp_allocator())
+		new_dir_stat, err1 := lstat(path, temp_allocator)
 		if err1 == nil && new_dir_stat.type == .Directory {
 		if err1 == nil && new_dir_stat.type == .Directory {
 			return nil
 			return nil
 		}
 		}
@@ -82,8 +82,8 @@ _remove_all :: proc(path: string) -> Error {
 		return nil
 		return nil
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
-	dir := win32_utf8_to_wstring(path, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	dir := win32_utf8_to_wstring(path, temp_allocator) or_return
 
 
 	empty: [1]u16
 	empty: [1]u16
 
 
@@ -109,10 +109,10 @@ _remove_all :: proc(path: string) -> Error {
 _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
 _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
 	win32.AcquireSRWLockExclusive(&cwd_lock)
 	win32.AcquireSRWLockExclusive(&cwd_lock)
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	sz_utf16 := win32.GetCurrentDirectoryW(0, nil)
 	sz_utf16 := win32.GetCurrentDirectoryW(0, nil)
-	dir_buf_wstr := make([]u16, sz_utf16, temp_allocator()) or_return
+	dir_buf_wstr := make([]u16, sz_utf16, temp_allocator) or_return
 
 
 	sz_utf16 = win32.GetCurrentDirectoryW(win32.DWORD(len(dir_buf_wstr)), raw_data(dir_buf_wstr))
 	sz_utf16 = win32.GetCurrentDirectoryW(win32.DWORD(len(dir_buf_wstr)), raw_data(dir_buf_wstr))
 	assert(int(sz_utf16)+1 == len(dir_buf_wstr)) // the second time, it _excludes_ the NUL.
 	assert(int(sz_utf16)+1 == len(dir_buf_wstr)) // the second time, it _excludes_ the NUL.
@@ -123,8 +123,8 @@ _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, er
 }
 }
 
 
 _set_working_directory :: proc(dir: string) -> (err: Error) {
 _set_working_directory :: proc(dir: string) -> (err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	wstr := win32_utf8_to_wstring(dir, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	wstr := win32_utf8_to_wstring(dir, temp_allocator) or_return
 
 
 	win32.AcquireSRWLockExclusive(&cwd_lock)
 	win32.AcquireSRWLockExclusive(&cwd_lock)
 
 
@@ -138,9 +138,9 @@ _set_working_directory :: proc(dir: string) -> (err: Error) {
 }
 }
 
 
 _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
 _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buf := make([dynamic]u16, 512, temp_allocator()) or_return
+	buf := make([dynamic]u16, 512, temp_allocator) or_return
 	for {
 	for {
 		ret := win32.GetModuleFileNameW(nil, raw_data(buf), win32.DWORD(len(buf)))
 		ret := win32.GetModuleFileNameW(nil, raw_data(buf), win32.DWORD(len(buf)))
 		if ret == 0 {
 		if ret == 0 {
@@ -222,10 +222,10 @@ _fix_long_path_internal :: proc(path: string) -> string {
 		return path
 		return path
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
 	PREFIX :: `\\?`
 	PREFIX :: `\\?`
-	path_buf := make([]byte, len(PREFIX)+len(path)+1, temp_allocator())
+	path_buf := make([]byte, len(PREFIX)+len(path)+1, temp_allocator)
 	copy(path_buf, PREFIX)
 	copy(path_buf, PREFIX)
 	n := len(path)
 	n := len(path)
 	r, w := 0, len(PREFIX)
 	r, w := 0, len(PREFIX)
@@ -297,14 +297,14 @@ _get_absolute_path :: proc(path: string, allocator: runtime.Allocator) -> (absol
 	if rel == "" {
 	if rel == "" {
 		rel = "."
 		rel = "."
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
-	rel_utf16 := win32.utf8_to_utf16(rel, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	rel_utf16 := win32.utf8_to_utf16(rel, temp_allocator)
 	n := win32.GetFullPathNameW(raw_data(rel_utf16), 0, nil, nil)
 	n := win32.GetFullPathNameW(raw_data(rel_utf16), 0, nil, nil)
 	if n == 0 {
 	if n == 0 {
 		return "", Platform_Error(win32.GetLastError())
 		return "", Platform_Error(win32.GetLastError())
 	}
 	}
 
 
-	buf := make([]u16, n, temp_allocator()) or_return
+	buf := make([]u16, n, temp_allocator) or_return
 	n = win32.GetFullPathNameW(raw_data(rel_utf16), u32(n), raw_data(buf), nil)
 	n = win32.GetFullPathNameW(raw_data(rel_utf16), u32(n), raw_data(buf), nil)
 	if n == 0 {
 	if n == 0 {
 		return "", Platform_Error(win32.GetLastError())
 		return "", Platform_Error(win32.GetLastError())

+ 24 - 24
core/os/os2/process_linux.odin

@@ -50,7 +50,7 @@ _get_ppid :: proc() -> int {
 
 
 @(private="package")
 @(private="package")
 _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error) {
 _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	dir_fd, errno := linux.open("/proc/", _OPENDIR_FLAGS)
 	dir_fd, errno := linux.open("/proc/", _OPENDIR_FLAGS)
 	#partial switch errno {
 	#partial switch errno {
@@ -68,9 +68,9 @@ _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error)
 	}
 	}
 	defer linux.close(dir_fd)
 	defer linux.close(dir_fd)
 
 
-	dynamic_list := make([dynamic]int, temp_allocator()) or_return
+	dynamic_list := make([dynamic]int, temp_allocator) or_return
 
 
-	buf := make([dynamic]u8, 128, 128, temp_allocator()) or_return
+	buf := make([dynamic]u8, 128, 128, temp_allocator) or_return
 	loop: for {
 	loop: for {
 		buflen: int
 		buflen: int
 		buflen, errno = linux.getdents(dir_fd, buf[:])
 		buflen, errno = linux.getdents(dir_fd, buf[:])
@@ -100,7 +100,7 @@ _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error)
 
 
 @(private="package")
 @(private="package")
 _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (info: Process_Info, err: Error) {
 _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (info: Process_Info, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	info.pid = pid
 	info.pid = pid
 
 
@@ -126,7 +126,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 
 
 		passwd_bytes: []u8
 		passwd_bytes: []u8
 		passwd_err: Error
 		passwd_err: Error
-		passwd_bytes, passwd_err = _read_entire_pseudo_file_cstring("/etc/passwd", temp_allocator())
+		passwd_bytes, passwd_err = _read_entire_pseudo_file_cstring("/etc/passwd", temp_allocator)
 		if passwd_err != nil {
 		if passwd_err != nil {
 			err = passwd_err
 			err = passwd_err
 			break username_if
 			break username_if
@@ -168,7 +168,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 		strings.write_int(&path_builder, pid)
 		strings.write_int(&path_builder, pid)
 		strings.write_string(&path_builder, "/cmdline")
 		strings.write_string(&path_builder, "/cmdline")
 
 
-		cmdline_bytes, cmdline_err := _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator())
+		cmdline_bytes, cmdline_err := _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator)
 		if cmdline_err != nil || len(cmdline_bytes) == 0 {
 		if cmdline_err != nil || len(cmdline_bytes) == 0 {
 			err = cmdline_err
 			err = cmdline_err
 			break cmdline_if
 			break cmdline_if
@@ -189,7 +189,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 			strings.write_int(&path_builder, pid)
 			strings.write_int(&path_builder, pid)
 			strings.write_string(&path_builder, "/cwd")
 			strings.write_string(&path_builder, "/cwd")
 
 
-			cwd, cwd_err = _read_link_cstr(strings.to_cstring(&path_builder) or_return, temp_allocator()) // allowed to fail
+			cwd, cwd_err = _read_link_cstr(strings.to_cstring(&path_builder) or_return, temp_allocator) // allowed to fail
 			if cwd_err == nil && .Working_Dir in selection {
 			if cwd_err == nil && .Working_Dir in selection {
 				info.working_dir = strings.clone(cwd, allocator) or_return
 				info.working_dir = strings.clone(cwd, allocator) or_return
 				info.fields += {.Working_Dir}
 				info.fields += {.Working_Dir}
@@ -245,7 +245,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 		strings.write_int(&path_builder, pid)
 		strings.write_int(&path_builder, pid)
 		strings.write_string(&path_builder, "/stat")
 		strings.write_string(&path_builder, "/stat")
 
 
-		proc_stat_bytes, stat_err := _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator())
+		proc_stat_bytes, stat_err := _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator)
 		if stat_err != nil {
 		if stat_err != nil {
 			err = stat_err
 			err = stat_err
 			break stat_if
 			break stat_if
@@ -284,7 +284,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 			Nice,
 			Nice,
 			//... etc,
 			//... etc,
 		}
 		}
-		stat_fields := strings.split(stats, " ", temp_allocator()) or_return
+		stat_fields := strings.split(stats, " ", temp_allocator) or_return
 
 
 		if len(stat_fields) <= int(Fields.Nice) {
 		if len(stat_fields) <= int(Fields.Nice) {
 			break stat_if
 			break stat_if
@@ -327,7 +327,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 		strings.write_int(&path_builder, pid)
 		strings.write_int(&path_builder, pid)
 		strings.write_string(&path_builder, "/exe")
 		strings.write_string(&path_builder, "/exe")
 
 
-		if exe_bytes, exe_err := _read_link(strings.to_string(path_builder), temp_allocator()); exe_err == nil {
+		if exe_bytes, exe_err := _read_link(strings.to_string(path_builder), temp_allocator); exe_err == nil {
 			info.executable_path = strings.clone(string(exe_bytes), allocator) or_return
 			info.executable_path = strings.clone(string(exe_bytes), allocator) or_return
 			info.fields += {.Executable_Path}
 			info.fields += {.Executable_Path}
 		} else {
 		} else {
@@ -341,7 +341,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 		strings.write_int(&path_builder, pid)
 		strings.write_int(&path_builder, pid)
 		strings.write_string(&path_builder, "/environ")
 		strings.write_string(&path_builder, "/environ")
 
 
-		if env_bytes, env_err := _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator()); env_err == nil {
+		if env_bytes, env_err := _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator); env_err == nil {
 			env := string(env_bytes)
 			env := string(env_bytes)
 
 
 			env_list := make([dynamic]string, allocator) or_return
 			env_list := make([dynamic]string, allocator) or_return
@@ -392,7 +392,7 @@ _process_open :: proc(pid: int, _: Process_Open_Flags) -> (process: Process, err
 
 
 @(private="package")
 @(private="package")
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
 	if len(desc.command) == 0 {
 	if len(desc.command) == 0 {
 		return process, .Invalid_Command
 		return process, .Invalid_Command
@@ -401,7 +401,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	dir_fd := linux.AT_FDCWD
 	dir_fd := linux.AT_FDCWD
 	errno: linux.Errno
 	errno: linux.Errno
 	if desc.working_dir != "" {
 	if desc.working_dir != "" {
-		dir_cstr := temp_cstring(desc.working_dir) or_return
+		dir_cstr := clone_to_cstring(desc.working_dir, temp_allocator) or_return
 		if dir_fd, errno = linux.open(dir_cstr, _OPENDIR_FLAGS); errno != .NONE {
 		if dir_fd, errno = linux.open(dir_cstr, _OPENDIR_FLAGS); errno != .NONE {
 			return process, _get_platform_error(errno)
 			return process, _get_platform_error(errno)
 		}
 		}
@@ -414,10 +414,10 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	exe_path: cstring
 	exe_path: cstring
 	executable_name := desc.command[0]
 	executable_name := desc.command[0]
 	if strings.index_byte(executable_name, '/') < 0 {
 	if strings.index_byte(executable_name, '/') < 0 {
-		path_env := get_env("PATH", temp_allocator())
-		path_dirs := split_path_list(path_env, temp_allocator()) or_return
+		path_env := get_env("PATH", temp_allocator)
+		path_dirs := split_path_list(path_env, temp_allocator) or_return
 
 
-		exe_builder := strings.builder_make(temp_allocator()) or_return
+		exe_builder := strings.builder_make(temp_allocator) or_return
 
 
 		found: bool
 		found: bool
 		for dir in path_dirs {
 		for dir in path_dirs {
@@ -444,7 +444,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 			}
 			}
 		}
 		}
 	} else {
 	} else {
-		exe_path = temp_cstring(executable_name) or_return
+		exe_path = clone_to_cstring(executable_name, temp_allocator) or_return
 		if linux.access(exe_path, linux.X_OK) != .NONE {
 		if linux.access(exe_path, linux.X_OK) != .NONE {
 			return process, .Not_Exist
 			return process, .Not_Exist
 		}
 		}
@@ -452,20 +452,20 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 
 
 	// args and environment need to be a list of cstrings
 	// args and environment need to be a list of cstrings
 	// that are terminated by a nil pointer.
 	// that are terminated by a nil pointer.
-	cargs := make([]cstring, len(desc.command) + 1, temp_allocator()) or_return
+	cargs := make([]cstring, len(desc.command) + 1, temp_allocator) or_return
 	for command, i in desc.command {
 	for command, i in desc.command {
-		cargs[i] = temp_cstring(command) or_return
+		cargs[i] = clone_to_cstring(command, temp_allocator) or_return
 	}
 	}
 
 
 	// Use current process' environment if description didn't provide it.
 	// Use current process' environment if description didn't provide it.
 	env: [^]cstring
 	env: [^]cstring
 	if desc.env == nil {
 	if desc.env == nil {
 		// take this process's current environment
 		// take this process's current environment
-		env = raw_data(export_cstring_environment(temp_allocator()))
+		env = raw_data(export_cstring_environment(temp_allocator))
 	} else {
 	} else {
-		cenv := make([]cstring, len(desc.env) + 1, temp_allocator()) or_return
+		cenv := make([]cstring, len(desc.env) + 1, temp_allocator) or_return
 		for env, i in desc.env {
 		for env, i in desc.env {
-			cenv[i] = temp_cstring(env) or_return
+			cenv[i] = clone_to_cstring(env, temp_allocator) or_return
 		}
 		}
 		env = &cenv[0]
 		env = &cenv[0]
 	}
 	}
@@ -593,7 +593,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 }
 }
 
 
 _process_state_update_times :: proc(state: ^Process_State) -> (err: Error) {
 _process_state_update_times :: proc(state: ^Process_State) -> (err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
 	stat_path_buf: [48]u8
 	stat_path_buf: [48]u8
 	path_builder := strings.builder_from_bytes(stat_path_buf[:])
 	path_builder := strings.builder_from_bytes(stat_path_buf[:])
@@ -602,7 +602,7 @@ _process_state_update_times :: proc(state: ^Process_State) -> (err: Error) {
 	strings.write_string(&path_builder, "/stat")
 	strings.write_string(&path_builder, "/stat")
 
 
 	stat_buf: []u8
 	stat_buf: []u8
-	stat_buf, err = _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator())
+	stat_buf, err = _read_entire_pseudo_file(strings.to_cstring(&path_builder) or_return, temp_allocator)
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}

+ 9 - 9
core/os/os2/process_posix.odin

@@ -52,14 +52,14 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 		return
 		return
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
 	// search PATH if just a plain name is provided.
 	// search PATH if just a plain name is provided.
-	exe_builder := strings.builder_make(temp_allocator())
+	exe_builder := strings.builder_make(temp_allocator)
 	exe_name    := desc.command[0]
 	exe_name    := desc.command[0]
 	if strings.index_byte(exe_name, '/') < 0 {
 	if strings.index_byte(exe_name, '/') < 0 {
-		path_env  := get_env("PATH", temp_allocator())
-		path_dirs := split_path_list(path_env, temp_allocator()) or_return
+		path_env  := get_env("PATH", temp_allocator)
+		path_dirs := split_path_list(path_env, temp_allocator) or_return
 
 
 		found: bool
 		found: bool
 		for dir in path_dirs {
 		for dir in path_dirs {
@@ -108,12 +108,12 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	}
 	}
 
 
 	cwd: cstring; if desc.working_dir != "" {
 	cwd: cstring; if desc.working_dir != "" {
-		cwd = temp_cstring(desc.working_dir)
+		cwd = clone_to_cstring(desc.working_dir, temp_allocator) or_return
 	}
 	}
 
 
-	cmd := make([]cstring, len(desc.command) + 1, temp_allocator())
+	cmd := make([]cstring, len(desc.command) + 1, temp_allocator)
 	for part, i in desc.command {
 	for part, i in desc.command {
-		cmd[i] = temp_cstring(part)
+		cmd[i] = clone_to_cstring(part, temp_allocator) or_return
 	}
 	}
 
 
 	env: [^]cstring
 	env: [^]cstring
@@ -121,9 +121,9 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 		// take this process's current environment
 		// take this process's current environment
 		env = posix.environ
 		env = posix.environ
 	} else {
 	} else {
-		cenv := make([]cstring, len(desc.env) + 1, temp_allocator())
+		cenv := make([]cstring, len(desc.env) + 1, temp_allocator)
 		for env, i in desc.env {
 		for env, i in desc.env {
-			cenv[i] = temp_cstring(env)
+			cenv[i] = clone_to_cstring(env, temp_allocator) or_return
 		}
 		}
 		env = raw_data(cenv)
 		env = raw_data(cenv)
 	}
 	}

+ 4 - 3
core/os/os2/process_posix_darwin.odin

@@ -50,6 +50,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 	}
 	}
 
 
 
 
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 	info.pid = pid
 	info.pid = pid
 
 
 	// Thought on errors is: allocation failures return immediately (also why the non-allocation stuff is done first),
 	// Thought on errors is: allocation failures return immediately (also why the non-allocation stuff is done first),
@@ -127,7 +128,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 			break args
 			break args
 		}
 		}
 
 
-		buf := runtime.make_aligned([]byte, length, 4, temp_allocator())
+		buf := runtime.make_aligned([]byte, length, 4, temp_allocator)
 		if sysctl(raw_data(mib), 3, raw_data(buf), &length, nil, 0) != .OK {
 		if sysctl(raw_data(mib), 3, raw_data(buf), &length, nil, 0) != .OK {
 			if err == nil {
 			if err == nil {
 				err = _get_platform_error()
 				err = _get_platform_error()
@@ -239,9 +240,9 @@ _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error)
 		return
 		return
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buffer := make([]i32, ret, temp_allocator())
+	buffer := make([]i32, ret, temp_allocator)
 	ret = darwin.proc_listallpids(raw_data(buffer), ret*size_of(i32))
 	ret = darwin.proc_listallpids(raw_data(buffer), ret*size_of(i32))
 	if ret < 0 {
 	if ret < 0 {
 		err = _get_platform_error()
 		err = _get_platform_error()

+ 25 - 23
core/os/os2/process_windows.odin

@@ -162,9 +162,10 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 		if err != nil {
 		if err != nil {
 			break read_peb
 			break read_peb
 		}
 		}
+		temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 		if selection >= {.Command_Line, .Command_Args} {
 		if selection >= {.Command_Line, .Command_Args} {
-			TEMP_ALLOCATOR_GUARD()
-			cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator()) or_return
+			temp_allocator_scope(temp_allocator)
+			cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator) or_return
 			_, err = read_memory_as_slice(ph, process_params.CommandLine.Buffer, cmdline_w)
 			_, err = read_memory_as_slice(ph, process_params.CommandLine.Buffer, cmdline_w)
 			if err != nil {
 			if err != nil {
 				break read_peb
 				break read_peb
@@ -179,9 +180,9 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 			}
 			}
 		}
 		}
 		if .Environment in selection {
 		if .Environment in selection {
-			TEMP_ALLOCATOR_GUARD()
+			temp_allocator_scope(temp_allocator)
 			env_len := process_params.EnvironmentSize / 2
 			env_len := process_params.EnvironmentSize / 2
-			envs_w := make([]u16, env_len, temp_allocator()) or_return
+			envs_w := make([]u16, env_len, temp_allocator) or_return
 			_, err = read_memory_as_slice(ph, process_params.Environment, envs_w)
 			_, err = read_memory_as_slice(ph, process_params.Environment, envs_w)
 			if err != nil {
 			if err != nil {
 				break read_peb
 				break read_peb
@@ -190,8 +191,8 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 			info.fields += {.Environment}
 			info.fields += {.Environment}
 		}
 		}
 		if .Working_Dir in selection {
 		if .Working_Dir in selection {
-			TEMP_ALLOCATOR_GUARD()
-			cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator()) or_return
+			temp_allocator_scope(temp_allocator)
+			cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator) or_return
 			_, err = read_memory_as_slice(ph, process_params.CurrentDirectoryPath.Buffer, cwd_w)
 			_, err = read_memory_as_slice(ph, process_params.CurrentDirectoryPath.Buffer, cwd_w)
 			if err != nil {
 			if err != nil {
 				break read_peb
 				break read_peb
@@ -272,9 +273,10 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
 		if err != nil {
 		if err != nil {
 			break read_peb
 			break read_peb
 		}
 		}
+		temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 		if selection >= {.Command_Line, .Command_Args} {
 		if selection >= {.Command_Line, .Command_Args} {
-			TEMP_ALLOCATOR_GUARD()
-			cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator()) or_return
+			temp_allocator_scope(temp_allocator)
+			cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator) or_return
 			_, err = read_memory_as_slice(ph, process_params.CommandLine.Buffer, cmdline_w)
 			_, err = read_memory_as_slice(ph, process_params.CommandLine.Buffer, cmdline_w)
 			if err != nil {
 			if err != nil {
 				break read_peb
 				break read_peb
@@ -289,9 +291,9 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
 			}
 			}
 		}
 		}
 		if .Environment in selection {
 		if .Environment in selection {
-			TEMP_ALLOCATOR_GUARD()
+			temp_allocator_scope(temp_allocator)
 			env_len := process_params.EnvironmentSize / 2
 			env_len := process_params.EnvironmentSize / 2
-			envs_w := make([]u16, env_len, temp_allocator()) or_return
+			envs_w := make([]u16, env_len, temp_allocator) or_return
 			_, err = read_memory_as_slice(ph, process_params.Environment, envs_w)
 			_, err = read_memory_as_slice(ph, process_params.Environment, envs_w)
 			if err != nil {
 			if err != nil {
 				break read_peb
 				break read_peb
@@ -300,8 +302,8 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
 			info.fields += {.Environment}
 			info.fields += {.Environment}
 		}
 		}
 		if .Working_Dir in selection {
 		if .Working_Dir in selection {
-			TEMP_ALLOCATOR_GUARD()
-			cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator()) or_return
+			temp_allocator_scope(temp_allocator)
+			cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator) or_return
 			_, err = read_memory_as_slice(ph, process_params.CurrentDirectoryPath.Buffer, cwd_w)
 			_, err = read_memory_as_slice(ph, process_params.CurrentDirectoryPath.Buffer, cwd_w)
 			if err != nil {
 			if err != nil {
 				break read_peb
 				break read_peb
@@ -419,15 +421,15 @@ _process_open :: proc(pid: int, flags: Process_Open_Flags) -> (process: Process,
 
 
 @(private="package")
 @(private="package")
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	command_line   := _build_command_line(desc.command, temp_allocator())
-	command_line_w := win32_utf8_to_wstring(command_line, temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	command_line   := _build_command_line(desc.command, temp_allocator)
+	command_line_w := win32_utf8_to_wstring(command_line, temp_allocator) or_return
 	environment := desc.env
 	environment := desc.env
 	if desc.env == nil {
 	if desc.env == nil {
-		environment = environ(temp_allocator()) or_return
+		environment = environ(temp_allocator) or_return
 	}
 	}
-	environment_block   := _build_environment_block(environment, temp_allocator())
-	environment_block_w := win32_utf8_to_utf16(environment_block, temp_allocator()) or_return
+	environment_block   := _build_environment_block(environment, temp_allocator)
+	environment_block_w := win32_utf8_to_utf16(environment_block, temp_allocator) or_return
 
 
 	stderr_handle: win32.HANDLE	
 	stderr_handle: win32.HANDLE	
 	stdout_handle: win32.HANDLE	
 	stdout_handle: win32.HANDLE	
@@ -474,7 +476,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 		stdin_handle = win32.HANDLE((^File_Impl)(desc.stdin.impl).fd)
 		stdin_handle = win32.HANDLE((^File_Impl)(desc.stdin.impl).fd)
 	}
 	}
 
 
-	working_dir_w := (win32_utf8_to_wstring(desc.working_dir, temp_allocator()) or_else nil) if len(desc.working_dir) > 0 else nil
+	working_dir_w := (win32_utf8_to_wstring(desc.working_dir, temp_allocator) or_else nil) if len(desc.working_dir) > 0 else nil
 	process_info: win32.PROCESS_INFORMATION
 	process_info: win32.PROCESS_INFORMATION
 	ok := win32.CreateProcessW(
 	ok := win32.CreateProcessW(
 		nil,
 		nil,
@@ -612,7 +614,7 @@ _process_exe_by_pid :: proc(pid: int, allocator: runtime.Allocator) -> (exe_path
 }
 }
 
 
 _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Allocator) -> (full_username: string, err: Error) {
 _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Allocator) -> (full_username: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 	token_handle: win32.HANDLE
 	token_handle: win32.HANDLE
 	if !win32.OpenProcessToken(process_handle, win32.TOKEN_QUERY, &token_handle) {
 	if !win32.OpenProcessToken(process_handle, win32.TOKEN_QUERY, &token_handle) {
 		err = _get_platform_error()
 		err = _get_platform_error()
@@ -627,7 +629,7 @@ _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Alloc
 		}
 		}
 		err = nil
 		err = nil
 	}
 	}
-	token_user := (^win32.TOKEN_USER)(raw_data(make([]u8, token_user_size, temp_allocator()) or_return))
+	token_user := (^win32.TOKEN_USER)(raw_data(make([]u8, token_user_size, temp_allocator) or_return))
 	if !win32.GetTokenInformation(token_handle, .TokenUser, token_user, token_user_size, &token_user_size) {
 	if !win32.GetTokenInformation(token_handle, .TokenUser, token_user, token_user_size, &token_user_size) {
 		err = _get_platform_error()
 		err = _get_platform_error()
 		return
 		return
@@ -643,8 +645,8 @@ _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Alloc
 		err = _get_platform_error()
 		err = _get_platform_error()
 		return
 		return
 	}
 	}
-	username := win32_utf16_to_utf8(username_w[:username_chrs], temp_allocator()) or_return
-	domain   := win32_utf16_to_utf8(domain_w[:domain_chrs], temp_allocator()) or_return
+	username := win32_utf16_to_utf8(username_w[:username_chrs], temp_allocator) or_return
+	domain   := win32_utf16_to_utf8(domain_w[:domain_chrs], temp_allocator) or_return
 	return strings.concatenate({domain, "\\", username}, allocator)
 	return strings.concatenate({domain, "\\", username}, allocator)
 }
 }
 
 

+ 4 - 4
core/os/os2/stat.odin

@@ -73,14 +73,14 @@ last_write_time_by_name :: modification_time_by_path
 
 
 @(require_results)
 @(require_results)
 modification_time :: proc(f: ^File) -> (time.Time, Error) {
 modification_time :: proc(f: ^File) -> (time.Time, Error) {
-	TEMP_ALLOCATOR_GUARD()
-	fi, err := fstat(f, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	fi, err := fstat(f, temp_allocator)
 	return fi.modification_time, err
 	return fi.modification_time, err
 }
 }
 
 
 @(require_results)
 @(require_results)
 modification_time_by_path :: proc(path: string) -> (time.Time, Error) {
 modification_time_by_path :: proc(path: string) -> (time.Time, Error) {
-	TEMP_ALLOCATOR_GUARD()
-	fi, err := stat(path, temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	fi, err := stat(path, temp_allocator)
 	return fi.modification_time, err
 	return fi.modification_time, err
 }
 }

+ 4 - 4
core/os/os2/stat_linux.odin

@@ -47,8 +47,8 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File
 
 
 // NOTE: _stat and _lstat are using _fstat to avoid a race condition when populating fullpath
 // NOTE: _stat and _lstat are using _fstat to avoid a race condition when populating fullpath
 _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err: Error) {
 _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 
 
 	fd, errno := linux.open(name_cstr, {})
 	fd, errno := linux.open(name_cstr, {})
 	if errno != .NONE {
 	if errno != .NONE {
@@ -59,8 +59,8 @@ _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err
 }
 }
 
 
 _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err: Error) {
 _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	name_cstr := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	name_cstr := clone_to_cstring(name, temp_allocator) or_return
 
 
 	fd, errno := linux.open(name_cstr, {.PATH, .NOFOLLOW})
 	fd, errno := linux.open(name_cstr, {.PATH, .NOFOLLOW})
 	if errno != .NONE {
 	if errno != .NONE {

+ 9 - 8
core/os/os2/stat_posix.odin

@@ -69,8 +69,8 @@ _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err
 		return
 		return
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
-	cname := temp_cstring(name) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	cname := clone_to_cstring(name, temp_allocator) or_return
 
 
 	fd := posix.open(cname, {})
 	fd := posix.open(cname, {})
 	if fd == -1 {
 	if fd == -1 {
@@ -96,33 +96,34 @@ _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, er
 		return
 		return
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	// NOTE: can't use realpath or open (+ fcntl F_GETPATH) here because it tries to resolve symlinks.
 	// NOTE: can't use realpath or open (+ fcntl F_GETPATH) here because it tries to resolve symlinks.
 
 
 	// NOTE: This might not be correct when given "/symlink/foo.txt",
 	// NOTE: This might not be correct when given "/symlink/foo.txt",
 	// you would want that to resolve "/symlink", but not resolve "foo.txt".
 	// you would want that to resolve "/symlink", but not resolve "foo.txt".
 
 
-	fullpath := clean_path(name, temp_allocator()) or_return
+	fullpath := clean_path(name, temp_allocator) or_return
 	assert(len(fullpath) > 0)
 	assert(len(fullpath) > 0)
 	switch {
 	switch {
 	case fullpath[0] == '/':
 	case fullpath[0] == '/':
 		// nothing.
 		// nothing.
 	case fullpath == ".":
 	case fullpath == ".":
-		fullpath = getwd(temp_allocator()) or_return
+		fullpath = getwd(temp_allocator) or_return
 	case len(fullpath) > 1 && fullpath[0] == '.' && fullpath[1] == '/':
 	case len(fullpath) > 1 && fullpath[0] == '.' && fullpath[1] == '/':
 		fullpath = fullpath[2:]
 		fullpath = fullpath[2:]
 		fallthrough
 		fallthrough
 	case:
 	case:
 		fullpath = concatenate({
 		fullpath = concatenate({
-			getwd(temp_allocator()) or_return,
+			getwd(temp_allocator) or_return,
 			"/",
 			"/",
 			fullpath,
 			fullpath,
-		}, temp_allocator()) or_return
+		}, temp_allocator) or_return
 	}
 	}
 
 
 	stat: posix.stat_t
 	stat: posix.stat_t
-	if posix.lstat(temp_cstring(fullpath), &stat) != .OK {
+	c_fullpath := clone_to_cstring(fullpath, temp_allocator) or_return
+	if posix.lstat(c_fullpath, &stat) != .OK {
 		err = _get_platform_error()
 		err = _get_platform_error()
 		return
 		return
 	}
 	}

+ 9 - 9
core/os/os2/stat_windows.odin

@@ -45,15 +45,15 @@ full_path_from_name :: proc(name: string, allocator: runtime.Allocator) -> (path
 		name = "."
 		name = "."
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	p := win32_utf8_to_utf16(name, temp_allocator()) or_return
+	p := win32_utf8_to_utf16(name, temp_allocator) or_return
 
 
 	n := win32.GetFullPathNameW(raw_data(p), 0, nil, nil)
 	n := win32.GetFullPathNameW(raw_data(p), 0, nil, nil)
 	if n == 0 {
 	if n == 0 {
 		return "", _get_platform_error()
 		return "", _get_platform_error()
 	}
 	}
-	buf := make([]u16, n+1, temp_allocator())
+	buf := make([]u16, n+1, temp_allocator)
 	n = win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
 	n = win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
 	if n == 0 {
 	if n == 0 {
 		return "", _get_platform_error()
 		return "", _get_platform_error()
@@ -65,9 +65,9 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator: runt
 	if len(name) == 0 {
 	if len(name) == 0 {
 		return {}, .Not_Exist
 		return {}, .Not_Exist
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	wname := _fix_long_path(name, temp_allocator()) or_return
+	wname := _fix_long_path(name, temp_allocator) or_return
 	fa: win32.WIN32_FILE_ATTRIBUTE_DATA
 	fa: win32.WIN32_FILE_ATTRIBUTE_DATA
 	ok := win32.GetFileAttributesExW(wname, win32.GetFileExInfoStandard, &fa)
 	ok := win32.GetFileAttributesExW(wname, win32.GetFileExInfoStandard, &fa)
 	if ok && fa.dwFileAttributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
 	if ok && fa.dwFileAttributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
@@ -137,9 +137,9 @@ _cleanpath_from_handle :: proc(f: ^File, allocator: runtime.Allocator) -> (strin
 		return "", _get_platform_error()
 		return "", _get_platform_error()
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	buf := make([]u16, max(n, 260)+1, temp_allocator())
+	buf := make([]u16, max(n, 260)+1, temp_allocator)
 	n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0)
 	n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0)
 	return _cleanpath_from_buf(buf[:n], allocator)
 	return _cleanpath_from_buf(buf[:n], allocator)
 }
 }
@@ -155,9 +155,9 @@ _cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) {
 		return nil, _get_platform_error()
 		return nil, _get_platform_error()
 	}
 	}
 
 
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 
-	buf := make([]u16, max(n, 260)+1, temp_allocator())
+	buf := make([]u16, max(n, 260)+1, temp_allocator)
 	n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0)
 	n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0)
 	return _cleanpath_strip_prefix(buf[:n]), nil
 	return _cleanpath_strip_prefix(buf[:n]), nil
 }
 }

+ 11 - 9
core/os/os2/temp_file.odin

@@ -15,13 +15,13 @@ MAX_ATTEMPTS :: 1<<13 // Should be enough for everyone, right?
 // The caller must `close` the file once finished with.
 // The caller must `close` the file once finished with.
 @(require_results)
 @(require_results)
 create_temp_file :: proc(dir, pattern: string) -> (f: ^File, err: Error) {
 create_temp_file :: proc(dir, pattern: string) -> (f: ^File, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	dir := dir if dir != "" else temp_directory(temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+	dir := dir if dir != "" else temp_directory(temp_allocator) or_return
 	prefix, suffix := _prefix_and_suffix(pattern) or_return
 	prefix, suffix := _prefix_and_suffix(pattern) or_return
 	prefix = temp_join_path(dir, prefix) or_return
 	prefix = temp_join_path(dir, prefix) or_return
 
 
 	rand_buf: [10]byte
 	rand_buf: [10]byte
-	name_buf := make([]byte, len(prefix)+len(rand_buf)+len(suffix), temp_allocator())
+	name_buf := make([]byte, len(prefix)+len(rand_buf)+len(suffix), temp_allocator)
 
 
 	attempts := 0
 	attempts := 0
 	for {
 	for {
@@ -47,13 +47,13 @@ mkdir_temp :: make_directory_temp
 // If `dir` is an empty tring, `temp_directory()` will be used.
 // If `dir` is an empty tring, `temp_directory()` will be used.
 @(require_results)
 @(require_results)
 make_directory_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (temp_path: string, err: Error) {
 make_directory_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (temp_path: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
-	dir := dir if dir != "" else temp_directory(temp_allocator()) or_return
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	dir := dir if dir != "" else temp_directory(temp_allocator) or_return
 	prefix, suffix := _prefix_and_suffix(pattern) or_return
 	prefix, suffix := _prefix_and_suffix(pattern) or_return
 	prefix = temp_join_path(dir, prefix) or_return
 	prefix = temp_join_path(dir, prefix) or_return
 
 
 	rand_buf: [10]byte
 	rand_buf: [10]byte
-	name_buf := make([]byte, len(prefix)+len(rand_buf)+len(suffix), temp_allocator())
+	name_buf := make([]byte, len(prefix)+len(rand_buf)+len(suffix), temp_allocator)
 
 
 	attempts := 0
 	attempts := 0
 	for {
 	for {
@@ -70,7 +70,7 @@ make_directory_temp :: proc(dir, pattern: string, allocator: runtime.Allocator)
 			return "", err
 			return "", err
 		}
 		}
 		if err == .Not_Exist {
 		if err == .Not_Exist {
-			if _, serr := stat(dir, temp_allocator()); serr == .Not_Exist {
+			if _, serr := stat(dir, temp_allocator); serr == .Not_Exist {
 				return "", serr
 				return "", serr
 			}
 			}
 		}
 		}
@@ -89,9 +89,11 @@ temp_directory :: proc(allocator: runtime.Allocator) -> (string, Error) {
 
 
 @(private="file")
 @(private="file")
 temp_join_path :: proc(dir, name: string) -> (string, runtime.Allocator_Error) {
 temp_join_path :: proc(dir, name: string) -> (string, runtime.Allocator_Error) {
+	temp_allocator := TEMP_ALLOCATOR_GUARD({})
+
 	if len(dir) > 0 && is_path_separator(dir[len(dir)-1]) {
 	if len(dir) > 0 && is_path_separator(dir[len(dir)-1]) {
-		return concatenate({dir, name}, temp_allocator(),)
+		return concatenate({dir, name}, temp_allocator,)
 	}
 	}
 
 
-	return concatenate({dir, Path_Separator_String, name}, temp_allocator())
+	return concatenate({dir, Path_Separator_String, name}, temp_allocator)
 }
 }

+ 2 - 2
core/os/os2/temp_file_linux.odin

@@ -4,8 +4,8 @@ package os2
 import "base:runtime"
 import "base:runtime"
 
 
 _temp_dir :: proc(allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
 _temp_dir :: proc(allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
-	TEMP_ALLOCATOR_GUARD()
-	tmpdir := get_env("TMPDIR", temp_allocator())
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
+	tmpdir := get_env("TMPDIR", temp_allocator)
 	if tmpdir == "" {
 	if tmpdir == "" {
 		tmpdir = "/tmp"
 		tmpdir = "/tmp"
 	}
 	}

+ 2 - 2
core/os/os2/temp_file_windows.odin

@@ -9,9 +9,9 @@ _temp_dir :: proc(allocator: runtime.Allocator) -> (string, runtime.Allocator_Er
 	if n == 0 {
 	if n == 0 {
 		return "", nil
 		return "", nil
 	}
 	}
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
-	b := make([]u16, max(win32.MAX_PATH, n), temp_allocator())
+	b := make([]u16, max(win32.MAX_PATH, n), temp_allocator)
 	n = win32.GetTempPathW(u32(len(b)), raw_data(b))
 	n = win32.GetTempPathW(u32(len(b)), raw_data(b))
 
 
 	if n == 3 && b[1] == ':' && b[2] == '\\' {
 	if n == 3 && b[1] == ':' && b[2] == '\\' {

+ 11 - 11
core/os/os2/user.odin

@@ -4,27 +4,27 @@ import "base:runtime"
 
 
 @(require_results)
 @(require_results)
 user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
 user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	#partial switch ODIN_OS {
 	#partial switch ODIN_OS {
 	case .Windows:
 	case .Windows:
-		dir = get_env("LocalAppData", temp_allocator())
+		dir = get_env("LocalAppData", temp_allocator)
 		if dir != "" {
 		if dir != "" {
-			dir = clone_string(dir, allocator) or_return
+			dir = clone_string(dir, temp_allocator) or_return
 		}
 		}
 	case .Darwin:
 	case .Darwin:
-		dir = get_env("HOME", temp_allocator())
+		dir = get_env("HOME", temp_allocator)
 		if dir != "" {
 		if dir != "" {
-			dir = concatenate({dir, "/Library/Caches"}, allocator) or_return
+			dir = concatenate({dir, "/Library/Caches"}, temp_allocator) or_return
 		}
 		}
 	case: // All other UNIX systems
 	case: // All other UNIX systems
 		dir = get_env("XDG_CACHE_HOME", allocator)
 		dir = get_env("XDG_CACHE_HOME", allocator)
 		if dir == "" {
 		if dir == "" {
-			dir = get_env("HOME", temp_allocator())
+			dir = get_env("HOME", temp_allocator)
 			if dir == "" {
 			if dir == "" {
 				return
 				return
 			}
 			}
-			dir = concatenate({dir, "/.cache"}, allocator) or_return
+			dir = concatenate({dir, "/.cache"}, temp_allocator) or_return
 		}
 		}
 	}
 	}
 	if dir == "" {
 	if dir == "" {
@@ -35,23 +35,23 @@ user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error
 
 
 @(require_results)
 @(require_results)
 user_config_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
 user_config_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
-	TEMP_ALLOCATOR_GUARD()
+	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 
 	#partial switch ODIN_OS {
 	#partial switch ODIN_OS {
 	case .Windows:
 	case .Windows:
-		dir = get_env("AppData", temp_allocator())
+		dir = get_env("AppData", temp_allocator)
 		if dir != "" {
 		if dir != "" {
 			dir = clone_string(dir, allocator) or_return
 			dir = clone_string(dir, allocator) or_return
 		}
 		}
 	case .Darwin:
 	case .Darwin:
-		dir = get_env("HOME", temp_allocator())
+		dir = get_env("HOME", temp_allocator)
 		if dir != "" {
 		if dir != "" {
 			dir = concatenate({dir, "/.config"}, allocator) or_return
 			dir = concatenate({dir, "/.config"}, allocator) or_return
 		}
 		}
 	case: // All other UNIX systems
 	case: // All other UNIX systems
 		dir = get_env("XDG_CONFIG_HOME", allocator)
 		dir = get_env("XDG_CONFIG_HOME", allocator)
 		if dir == "" {
 		if dir == "" {
-			dir = get_env("HOME", temp_allocator())
+			dir = get_env("HOME", temp_allocator)
 			if dir == "" {
 			if dir == "" {
 				return
 				return
 			}
 			}