libc: Partially support environment variables
This commit is contained in:
parent
ebf9d35c3e
commit
12ac7e660e
|
@ -3,8 +3,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <frg/random.hpp>
|
|
||||||
|
|
||||||
|
#include <frg/random.hpp>
|
||||||
|
#include <frigg/debug.hpp>
|
||||||
#include <mlibc/ensure.h>
|
#include <mlibc/ensure.h>
|
||||||
|
|
||||||
extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *dso_tag);
|
extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *dso_tag);
|
||||||
|
@ -177,10 +178,7 @@ void exit(int status) {
|
||||||
_Exit(status);
|
_Exit(status);
|
||||||
}
|
}
|
||||||
// _Exit() is provided by the platform
|
// _Exit() is provided by the platform
|
||||||
char *getenv(const char *name) {
|
// getenv() is provided by POSIX
|
||||||
// TODO: should be provided by the POSIX sublibrary based on environ
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
void quick_exit(int status) {
|
void quick_exit(int status) {
|
||||||
__ensure(!"Not implemented");
|
__ensure(!"Not implemented");
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
|
|
|
@ -8,6 +8,8 @@ extern "C" {
|
||||||
|
|
||||||
long random(void);
|
long random(void);
|
||||||
|
|
||||||
|
int putenv(const char *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,49 @@
|
||||||
|
|
||||||
char *__emptyEnviron[] = { nullptr };
|
#include <stdlib.h>
|
||||||
|
|
||||||
char **environ = __emptyEnviron;
|
#include <frigg/string.hpp>
|
||||||
|
#include <frigg/vector.hpp>
|
||||||
|
#include <mlibc/ensure.h>
|
||||||
|
#include <mlibc/frigg-alloc.hpp>
|
||||||
|
|
||||||
|
static char *emptyEnvironment[] = { nullptr };
|
||||||
|
|
||||||
|
char **environ = emptyEnvironment;
|
||||||
|
|
||||||
|
char *getenv(const char *name) {
|
||||||
|
for(auto it = environ; *it; it++) {
|
||||||
|
frigg::StringView view{*it};
|
||||||
|
|
||||||
|
size_t s = view.findFirst('=');
|
||||||
|
if(s == size_t(-1)) {
|
||||||
|
frigg::infoLogger() << "\e[35mmlibc: getenv() environment string '"
|
||||||
|
<< view << "' does not contain the '=' sign\e[39m" << frigg::endLog;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(view.subString(0, s) != name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return const_cast<char *>(view.data() + s + 1);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Environment vector that is mutated by putenv() and setenv().
|
||||||
|
static frigg::Vector<char *, MemoryAllocator> mutEnvironment{getAllocator()};
|
||||||
|
|
||||||
|
int putenv(const char *string) {
|
||||||
|
// If the environ variable was changed, we copy the environment.
|
||||||
|
if(environ != mutEnvironment.data()) {
|
||||||
|
// TODO: Actually copy the entries.
|
||||||
|
__ensure(!*environ);
|
||||||
|
mutEnvironment.push(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Replace the entry instead of adding it.
|
||||||
|
__ensure(!mutEnvironment.back());
|
||||||
|
mutEnvironment.back() = const_cast<char *>(string);
|
||||||
|
mutEnvironment.push(nullptr);
|
||||||
|
environ = mutEnvironment.data();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue