aboutsummaryrefslogtreecommitdiff
path: root/src/path.cpp
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2025-06-27 01:20:37 +0200
committerGitHub <noreply@github.com>2025-06-27 01:20:37 +0200
commit2e83e221419b480160dbf11dd09edf8b5fa97f32 (patch)
treebc5e666006bf43931bc793ac921061b5630db4d4 /src/path.cpp
parentc51df72f1a8a21dd0064086dfc1186a3dd79e2ef (diff)
parentf72b2b153057e1d629c85af2ea7c54f7928198d5 (diff)
Merge branch 'master' into args-leak
Diffstat (limited to 'src/path.cpp')
-rw-r--r--src/path.cpp76
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) {