X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fenv.c;h=e1b5d81dd5db47b861d049842ed445db57c4d387;hb=4d0188930e7d0e571db78d1d2e3c4d9b3f0fe8fb;hp=3dca4df7b7dbd5dd7e8cd1b7a0ef2f7054f15ee8;hpb=a2210987109ab5a6337c72b45f7e52cfc9092f8f;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/env.c b/Usermode/Libraries/libc.so_src/env.c index 3dca4df7..e1b5d81d 100644 --- a/Usermode/Libraries/libc.so_src/env.c +++ b/Usermode/Libraries/libc.so_src/env.c @@ -4,31 +4,93 @@ */ #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; +} +