diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 65b72f95..092ed8c3 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -112,6 +112,9 @@ extern "C" /* Remove a variable from the environment. */ int unsetenv(const char* key); + /* Clear all environment variables. */ + int clearenv(void); + void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); diff --git a/libc/src/env.cpp b/libc/src/env.cpp index c666d6a7..2139906c 100644 --- a/libc/src/env.cpp +++ b/libc/src/env.cpp @@ -15,6 +15,8 @@ static isize _findenv(const char* key, char** value) char** env = environ; size_t len = strlen(key); + if (!env) return -1; + while (*env) { // Retrieve an environment variable from environ. @@ -51,6 +53,15 @@ static Result _try_move_env() } }); + if (!env) + { + guard.deactivate(); + env_is_dynamic = true; + environ = g_dynamic_env.data(); + check(!environ); + return {}; + } + while (*env) { char* ptr = strdup(*(env++)); @@ -91,6 +102,22 @@ extern "C" { char** environ = nullptr; + int clearenv() + { + if (env_is_dynamic) + { + for (auto element : g_dynamic_env) + { + if (element) free(element); + } + } + + env_is_dynamic = false; + environ = nullptr; + + return 0; + } + int unsetenv(const char* key) { if (!key || *key == 0 || strchr(key, '='))