From 8aa4e4ff1e814a92efd1d1e9a06c7490c29aba33 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 21 May 2025 18:11:22 +0300 Subject: [PATCH] LibC: Implement `clearenv` This is GNU extension but seems nice to have :D --- userspace/libraries/LibC/environ.cpp | 32 +++++++++++++++++++++-- userspace/libraries/LibC/include/stdlib.h | 1 + 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/userspace/libraries/LibC/environ.cpp b/userspace/libraries/LibC/environ.cpp index 2769f9d053..781c379bc3 100644 --- a/userspace/libraries/LibC/environ.cpp +++ b/userspace/libraries/LibC/environ.cpp @@ -19,7 +19,7 @@ static int malloc_environ() ASSERT(!s_environ_malloced); size_t environ_count = 0; - while (environ[environ_count]) + while (environ && environ[environ_count]) environ_count++; const size_t bitmap_size = (environ_count + 7) / 8; @@ -111,12 +111,37 @@ static int putenv_impl(char* string, bool malloced) return 0; } +int clearenv(void) +{ + if (s_environ_malloced) + { + ASSERT(environ); + + for (size_t i = 0; environ[i]; i++) + { + const size_t byte = i / 8; + const size_t mask = 1 << (i % 8); + if (s_environ_bitmap[byte] & mask) + free(environ[i]); + } + + free(s_environ_bitmap); + free(environ); + } + + environ = nullptr; + s_environ_count = 0; + s_environ_bitmap = nullptr; + s_environ_malloced = false; + return 0; +} + char* getenv(const char* name) { if (environ == nullptr) return nullptr; const size_t namelen = strlen(name); - for (int i = 0; environ[i]; i++) + for (size_t i = 0; environ[i]; i++) if (strncmp(name, environ[i], namelen) == 0) if (environ[i][namelen] == '=') return environ[i] + namelen + 1; @@ -154,6 +179,9 @@ int unsetenv(const char* name) return -1; } + if (environ == nullptr) + return 0; + const size_t namelen = strlen(name); size_t i = 0; diff --git a/userspace/libraries/LibC/include/stdlib.h b/userspace/libraries/LibC/include/stdlib.h index 63449d2beb..b93cba789b 100644 --- a/userspace/libraries/LibC/include/stdlib.h +++ b/userspace/libraries/LibC/include/stdlib.h @@ -51,6 +51,7 @@ long atol(const char* str); long long atoll(const char* str); void* bsearch(const void* key, const void* base, size_t nel, size_t width, int (*compar)(const void*, const void*)); void* calloc(size_t nelem, size_t elsize); +int clearenv(void); div_t div(int numer, int denom); double drand48(void); double erand48(unsigned short xsubi[3]);