aboutsummaryrefslogtreecommitdiff
path: root/lib/mlibc/options/ansi/generic/environment.cpp
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-03-07 17:28:52 -0500
committerIan Moffett <ian@osmora.org>2024-03-07 18:24:51 -0500
commitf5e48e94a2f4d4bbd6e5628c7f2afafc6dbcc459 (patch)
tree93b156621dc0303816b37f60ba88051b702d92f6 /lib/mlibc/options/ansi/generic/environment.cpp
parentbd5969fc876a10b18613302db7087ef3c40f18e1 (diff)
build: Build mlibc + add distclean target
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/ansi/generic/environment.cpp')
-rw-r--r--lib/mlibc/options/ansi/generic/environment.cpp164
1 files changed, 0 insertions, 164 deletions
diff --git a/lib/mlibc/options/ansi/generic/environment.cpp b/lib/mlibc/options/ansi/generic/environment.cpp
deleted file mode 100644
index 5625592..0000000
--- a/lib/mlibc/options/ansi/generic/environment.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <bits/ensure.h>
-#include <mlibc/allocator.hpp>
-#include <mlibc/debug.hpp>
-
-#include <frg/string.hpp>
-#include <frg/vector.hpp>
-
-namespace {
- char *empty_environment[] = { nullptr };
-}
-
-char **environ = empty_environment;
-
-namespace {
-
-size_t find_environ_index(frg::string_view name) {
- for(size_t i = 0; environ[i]; i++) {
- frg::string_view view{environ[i]};
- size_t s = view.find_first('=');
- if(s == size_t(-1)) {
- mlibc::infoLogger() << "mlibc: environment string \""
- << frg::escape_fmt{view.data(), view.size()}
- << "\" does not contain an equals sign (=)" << frg::endlog;
- continue;
- }
- if(view.sub_string(0, s) == name)
- return i;
- }
-
- return -1;
-}
-
-// Environment vector that is mutated by putenv() and setenv().
-// Cannot be global as it is accessed during library initialization.
-frg::vector<char *, MemoryAllocator> &get_vector() {
- static frg::vector<char *, MemoryAllocator> vector{getAllocator()};
- return vector;
-}
-
-void update_vector() {
- auto &vector = get_vector();
- if(environ == vector.data())
- return;
-
- // If the environ variable was changed, we copy the environment.
- // Note that we must only copy the pointers but not the strings themselves!
- vector.clear();
- for(size_t i = 0; environ[i]; i++)
- vector.push(environ[i]);
- vector.push(nullptr);
-
- environ = vector.data();
-}
-
-void assign_variable(frg::string_view name, const char *string, bool overwrite) {
- auto &vector = get_vector();
- __ensure(environ == vector.data());
-
- auto k = find_environ_index(name);
- if(k != size_t(-1)) {
- if(overwrite)
- vector[k] = const_cast<char *>(string);
- }else{
- // Last pointer of environ must always be a null delimiter.
- __ensure(!vector.back());
- vector.back() = const_cast<char *>(string);
- vector.push(nullptr);
- }
-
- // push() might have re-allocated the vector.
- environ = vector.data();
-}
-
-void unassign_variable(frg::string_view name) {
- auto &vector = get_vector();
- __ensure(environ == vector.data());
-
- auto k = find_environ_index(name);
- if(k == size_t(-1))
- return;
-
- // Last pointer of environ must always be a null delimiter.
- __ensure(vector.size() >= 2 && !vector.back());
- std::swap(vector[k], vector[vector.size() - 2]);
- vector.pop();
- vector.back() = nullptr;
-
- // pop() might have re-allocated the vector.
- environ = vector.data();
-}
-
-} // anonymous namespace
-
-char *getenv(const char *name) {
- auto k = find_environ_index(name);
- if(k == size_t(-1))
- return nullptr;
-
- frg::string_view view{environ[k]};
- size_t s = view.find_first('=');
- __ensure(s != size_t(-1));
- return const_cast<char *>(view.data() + s + 1);
-}
-
-namespace mlibc {
-
-int putenv(char *string) {
- frg::string_view view{string};
- size_t s = view.find_first('=');
- if(s == size_t(-1))
- __ensure(!"Environment strings need to contain an equals sign");
-
- update_vector();
- assign_variable(view.sub_string(0, s), string, true);
- return 0;
-}
-
-} // namespace mlibc
-
-#if __MLIBC_POSIX_OPTION
-
-int putenv(char *string) {
- return mlibc::putenv(string);
-}
-
-int setenv(const char *name, const char *value, int overwrite) {
- frg::string_view view{name};
- size_t s = view.find_first('=');
- if(s != size_t(-1)) {
- mlibc::infoLogger() << "mlibc: environment variable \""
- << frg::escape_fmt{view.data(), view.size()} << "\" contains an equals sign"
- << frg::endlog;
- errno = EINVAL;
- return -1;
- }
-
- // We never free strings here. TODO: Reuse them?
- char *string;
- __ensure(asprintf(&string, "%s=%s", name, value) > 0);
- __ensure(string);
-
- update_vector();
- assign_variable(name, string, overwrite);
- return 0;
-}
-
-int unsetenv(const char *name) {
- update_vector();
- unassign_variable(name);
- return 0;
-}
-
-int clearenv(void) {
- auto vector = get_vector();
- vector.clear();
- update_vector();
- return 0;
-}
-
-#endif /* __MLIBC_POSIX_OPTION */