diff options
| author | Colin Davidson <colrdavidson@gmail.com> | 2025-04-26 18:22:21 -0700 |
|---|---|---|
| committer | Colin Davidson <colrdavidson@gmail.com> | 2025-04-26 18:22:21 -0700 |
| commit | f1fdd1a8b9a53d34b59f8bac86ebba5f35189f28 (patch) | |
| tree | 5d8e0f200c25ae3451f666e7292f9cc9ad3db743 /src/path.cpp | |
| parent | 78d8ed2d391e8def6b303445c82f7d143897c251 (diff) | |
| parent | 7d4c3d23e6156c1b4be1f91e6d18e51a8e9814f0 (diff) | |
Merge branch 'master' into macharena
Diffstat (limited to 'src/path.cpp')
| -rw-r--r-- | src/path.cpp | 76 |
1 files changed, 64 insertions, 12 deletions
diff --git a/src/path.cpp b/src/path.cpp index 2c08ddd98..d5e982088 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -30,28 +30,80 @@ gb_internal String remove_directory_from_path(String const &s) { } -// NOTE(Mark Naughton): getcwd as String -#if !defined(GB_SYSTEM_WINDOWS) -gb_internal String get_current_directory(void) { - char cwd[256]; - getcwd(cwd, 256); +#if defined(GB_SYSTEM_WINDOWS) +gb_global SRWLOCK cwd_lock; + +String get_working_directory(gbAllocator allocator) { + AcquireSRWLockExclusive(&cwd_lock); + + TEMPORARY_ALLOCATOR_GUARD(); + + DWORD sz_utf16 = GetCurrentDirectoryW(0, nullptr); + wchar_t *dir_buf_wstr = gb_alloc_array(temporary_allocator(), wchar_t, sz_utf16); + if (dir_buf_wstr == nullptr) { + ReleaseSRWLockExclusive(&cwd_lock); + return {}; + } + + DWORD n = GetCurrentDirectoryW(sz_utf16, dir_buf_wstr); + GB_ASSERT(n+1 == sz_utf16); + ReleaseSRWLockExclusive(&cwd_lock); + + + isize buf_len = sz_utf16*4; + u8 *buf = gb_alloc_array(allocator, u8, buf_len); + gb_ucs2_to_utf8(buf, buf_len, cast(u16 *)dir_buf_wstr); + + return make_string_c(cast(char const *)buf); +} + +bool set_working_directory(String dir) { + bool ok = false; + TEMPORARY_ALLOCATOR_GUARD(); + + char const *cdir = alloc_cstring(temporary_allocator(), dir); + wchar_t *wstr = gb__alloc_utf8_to_ucs2(temporary_allocator(), cdir, nullptr); - return make_string_c(cwd); + AcquireSRWLockExclusive(&cwd_lock); + + ok = SetCurrentDirectoryW(wstr); + + ReleaseSRWLockExclusive(&cwd_lock); + + return ok; } #else -gb_internal String get_current_directory(void) { - gbAllocator a = heap_allocator(); - wchar_t cwd[256]; - GetCurrentDirectoryW(256, cwd); +String get_working_directory(gbAllocator allocator) { + TEMPORARY_ALLOCATOR_GUARD(); - String16 wstr = make_string16_c(cwd); + auto buf = array_make<char>(temporary_allocator()); + size_t size = PATH_MAX; - return string16_to_string(a, wstr); + char const *cwd = nullptr; + for (; cwd == nullptr; size *= 2) { + array_resize(&buf, size); + + cwd = getcwd(buf.data, buf.count); + if (cwd == nullptr && errno != ERANGE) { + return {}; + } + } + + return copy_string(allocator, make_string_c(cwd)); +} + +bool set_working_directory(String dir) { + TEMPORARY_ALLOCATOR_GUARD(); + char const *cdir = alloc_cstring(temporary_allocator(), dir); + return !chdir(cdir); } + #endif + + gb_internal bool path_is_directory(String path); gb_internal String directory_from_path(String const &s) { |