From 8e371180022e848be965da128f554c69f633241e Mon Sep 17 00:00:00 2001 From: Pierre Curto Date: Mon, 25 Sep 2023 08:41:51 +0200 Subject: [PATCH] std::os: add support for WIN32 in set_var and clear_var Signed-off-by: Pierre Curto --- lib/std/os/env.c3 | 27 ++++++++++++++++++++------- lib/std/os/win32/process.c3 | 4 ++++ test/unit/stdlib/os/env.c3 | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 test/unit/stdlib/os/env.c3 diff --git a/lib/std/os/env.c3 b/lib/std/os/env.c3 index 1bee1b80d..1491b8076 100644 --- a/lib/std/os/env.c3 +++ b/lib/std/os/env.c3 @@ -58,15 +58,24 @@ macro usz get_env_win32(name, buffer) @local **/ fn void set_var(String name, String value, bool overwrite = true) { - $if env::LIBC && !env::WIN32: @pool() { - if (libc::setenv(name.zstr_tcopy(), value.zstr_copy(), (int)overwrite)) + ZString zname = name.zstr_tcopy(); + ZString zvalue = value.zstr_tcopy(); + $switch + $case env::LIBC && !env::WIN32: + if (libc::setenv(zname, zvalue, (int)overwrite)) { unreachable(); } + $case env::WIN32: + // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setenvironmentvariable + if (!win32::setEnvironmentVariable((Win32_LPCSTR)zname.ptr, (Win32_LPCSTR)zvalue.ptr)) + { + unreachable(); + } + $endswitch }; - $endif } /** @@ -124,21 +133,25 @@ fn String! get_config_dir(Allocator* using = mem::heap()) **/ fn void clear_var(String name) { - $if env::LIBC && !env::WIN32: @pool() { - if (libc::unsetenv(name.zstr_tcopy())) + ZString zname = name.zstr_tcopy(); + $switch + $case env::LIBC && !env::WIN32: + if (libc::unsetenv(zname)) { unreachable(); } + $case env::WIN32: + win32::getEnvironmentVariable((Win32_LPCSTR)zname.ptr, 0); + $endswitch }; - $endif } fn String! executable_path(Allocator *using = mem::heap()) { $if env::DARWIN: - return darwin::executable_path(); + return darwin::executable_path(using); $else return ""; $endif diff --git a/lib/std/os/win32/process.c3 b/lib/std/os/win32/process.c3 index b4770a0ef..34e60a296 100644 --- a/lib/std/os/win32/process.c3 +++ b/lib/std/os/win32/process.c3 @@ -88,6 +88,10 @@ extern fn Win32_DWORD getEnvironmentVariable( Win32_LPSTR lpBuffer, Win32_DWORD nSize ) @extern("GetEnvironmentVariableA"); +extern fn Win32_BOOL setEnvironmentVariable( + Win32_LPCSTR lpName, + Win32_LPCSTR lpBuffer +) @extern("SetEnvironmentVariableA"); struct SystemInfo { diff --git a/test/unit/stdlib/os/env.c3 b/test/unit/stdlib/os/env.c3 new file mode 100644 index 000000000..e7a9e3152 --- /dev/null +++ b/test/unit/stdlib/os/env.c3 @@ -0,0 +1,17 @@ +module std::os::env @test; + +fn void! set_get_unset() +{ + const NAME = "C3_TEST_ENVVAR"; + const VALUE = "foobar"; + + env::set_var(NAME, VALUE); + String v = env::get_var(NAME)!; + assert(v == VALUE, "got %s; want %s", v, VALUE); + + env::clear_var(NAME); + if (try env::get_var(NAME)) + { + assert(false, "environment variable should no longer exist"); + } +} \ No newline at end of file