diff --git a/core/os/os2/path_posix.odin b/core/os/os2/path_posix.odin index 1e59afdc1..066ca1ddf 100644 --- a/core/os/os2/path_posix.odin +++ b/core/os/os2/path_posix.odin @@ -96,8 +96,7 @@ _remove_all :: proc(path: string) -> Error { } _get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { - assert(!is_temp(allocator)) - TEMP_ALLOCATOR_GUARD() + TEMP_ALLOCATOR_GUARD(ignore=is_temp(allocator)) buf: [dynamic]byte buf.allocator = temp_allocator() diff --git a/core/os/os2/stat_posix.odin b/core/os/os2/stat_posix.odin index caf25a277..2830a1f22 100644 --- a/core/os/os2/stat_posix.odin +++ b/core/os/os2/stat_posix.odin @@ -97,24 +97,38 @@ _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, er return } - assert(!is_temp(allocator)) - TEMP_ALLOCATOR_GUARD() - cname := temp_cstring(name) or_return + TEMP_ALLOCATOR_GUARD(ignore=is_temp(allocator)) - rcname := posix.realpath(cname) - if rcname == nil { - err = .Invalid_Path - return + // NOTE: can't use realpath here because it tries to resolve symlinks. + + // NOTE: This might not be correct when given "/symlink/foo.txt", + // you would want that to resolve "/symlink", but not resolve "foo.txt". + + fullpath := filepath.clean(name, temp_allocator()) + assert(len(fullpath) > 0) + switch { + case fullpath[0] == '/': + // nothing. + case fullpath == ".": + fullpath = getwd(temp_allocator()) or_return + case len(fullpath) > 1 && fullpath[0] == '.' && fullpath[1] == '/': + fullpath = fullpath[2:] + fallthrough + case: + fullpath = concatenate({ + getwd(temp_allocator()) or_return, + "/", + fullpath, + }, temp_allocator()) or_return } - defer posix.free(rcname) stat: posix.stat_t - if posix.lstat(rcname, &stat) != .OK { + if posix.lstat(temp_cstring(fullpath), &stat) != .OK { err = _get_platform_error() return } - fullpath := clone_string(string(rcname), allocator) or_return + fullpath = clone_string(fullpath, allocator) or_return return internal_stat(stat, fullpath), nil }