X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fenv.c;h=e1b5d81dd5db47b861d049842ed445db57c4d387;hb=b7d9f86f7a1c23be18b50d5c647fd5d3c08369c3;hp=c0f8ea3f98924c44e6c9eb86f03867373c01ea4f;hpb=17e16b3110b4c5124b0707435e0427993d696545;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/env.c b/Usermode/Libraries/libc.so_src/env.c index c0f8ea3f..e1b5d81d 100644 --- a/Usermode/Libraries/libc.so_src/env.c +++ b/Usermode/Libraries/libc.so_src/env.c @@ -1,33 +1,96 @@ /* -AcessOS C Library -- Environment Handler + * Acess C Library + * - Environment Handler */ #include +#include +#include // === GLOBALS === -char **_envp = NULL; +char **environ = NULL; +static char **expected_environ = NULL; +static int num_allocated_slots; // === CODE === char *getenv(const char *name) { - char **env; - char *str; + char *env_str; int len; - if(!_envp) return NULL; + if(!environ) return NULL; if(!name) return NULL; - len = strlen((char*)name); - env = _envp; - while(*env) { - str = *env; - if(str[len] == '=' && strncmp((char*)name, str, len) == 0) { - return str+len+1; + for( char **env = environ; *env; env ++ ) + { + env_str = *env; + if(strncmp(name, env_str, len) == 0 && env_str[len] == '=') { + return env_str+len+1; } - env ++; } return NULL; } + + +int putenv(char *string) +{ + char *eqpos = strchr(string, '='); + if( !eqpos ) { + errno = EINVAL; + return -1; + } + size_t namelen = eqpos - string; + + static const int alloc_step = 10; + if( expected_environ == NULL || expected_environ != environ ) + { + if( expected_environ ) + free(expected_environ); + + int envc = 0; + // Take a copy + for( char **env = environ; *env; env ++ ) + envc ++; + envc ++; // NULL termination + envc ++; // assume we're adding a new value + + num_allocated_slots = (envc + alloc_step-1) / alloc_step * alloc_step; + + expected_environ = malloc(num_allocated_slots*sizeof(char*)); + if(!expected_environ) + return 1; + + int idx = 0; + for( char **env = environ; *env; env ++ ) + expected_environ[idx++] = *env; + expected_environ[idx++] = NULL; + + environ = expected_environ; + } + + int envc = 0; + for( char **env = environ; *env; env ++, envc++ ) + { + if( strncmp(*env, string, namelen) != 0 ) + continue ; + if( *env[namelen] != '=' ) + continue ; + *env = string; + return 0; + } + if( num_allocated_slots >= envc+1 ) + { + num_allocated_slots += alloc_step; + expected_environ = realloc(expected_environ, num_allocated_slots*sizeof(char*)); + if(!expected_environ) + return 1; + environ = expected_environ; + } + environ[envc] = string; + environ[envc+1] = NULL; + + return 0; +} +