libc: Partially support environment variables

This commit is contained in:
Alexander van der Grinten 2018-01-21 16:48:09 +01:00
parent ebf9d35c3e
commit 12ac7e660e
3 changed files with 51 additions and 7 deletions

View file

@ -3,8 +3,9 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <frg/random.hpp>
#include <frg/random.hpp>
#include <frigg/debug.hpp>
#include <mlibc/ensure.h>
extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *dso_tag);
@ -177,10 +178,7 @@ void exit(int status) {
_Exit(status);
}
// _Exit() is provided by the platform
char *getenv(const char *name) {
// TODO: should be provided by the POSIX sublibrary based on environ
return nullptr;
}
// getenv() is provided by POSIX
void quick_exit(int status) {
__ensure(!"Not implemented");
__builtin_unreachable();

View file

@ -8,6 +8,8 @@ extern "C" {
long random(void);
int putenv(const char *);
#ifdef __cplusplus
}
#endif

View file

@ -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;
}