Usermode/libc #6 Fix string.h functions, add some more unit tests
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / env.c
1 /*
2  * Acess C Library
3  * - Environment Handler
4 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <errno.h>
8
9 // === GLOBALS ===
10 char    **environ = NULL;       
11 static char     **expected_environ = NULL;
12 static int      num_allocated_slots;
13
14 // === CODE ===
15 char *getenv(const char *name)
16 {
17         char    *env_str;
18          int    len;
19         
20         if(!environ)    return NULL;
21         if(!name)       return NULL;
22         
23         len = strlen((char*)name);
24         
25         for( char **env = environ; *env; env ++ )
26         {
27                 env_str = *env;
28                 if(strncmp(name, env_str, len) == 0 && env_str[len] == '=') {
29                         return env_str+len+1;
30                 }
31         }
32         
33         return NULL;
34 }
35
36
37 int putenv(char *string)
38 {
39         char *eqpos = strchr(string, '=');
40         if( !eqpos ) {
41                 errno = EINVAL;
42                 return -1;
43         }
44         size_t  namelen = eqpos - string;
45         
46         static const int        alloc_step = 10;
47         if( expected_environ == NULL || expected_environ != environ )
48         {
49                 if( expected_environ )
50                         free(expected_environ);
51                 
52                  int    envc = 0;
53                 // Take a copy
54                 for( char **env = environ; *env; env ++ )
55                         envc ++;
56                 envc ++;        // NULL termination
57                 envc ++;        // assume we're adding a new value
58                 
59                 num_allocated_slots = (envc + alloc_step-1) / alloc_step * alloc_step;
60
61                 expected_environ = malloc(num_allocated_slots*sizeof(char*));
62                 if(!expected_environ)
63                         return 1;
64                 
65                  int    idx = 0;
66                 for( char **env = environ; *env; env ++ )
67                         expected_environ[idx++] = *env;
68                 expected_environ[idx++] = NULL;
69                 
70                 environ = expected_environ;
71         }
72         
73          int    envc = 0;
74         for( char **env = environ; *env; env ++, envc++ )
75         {
76                 if( strncmp(*env, string, namelen) != 0 )
77                         continue ;
78                 if( *env[namelen] != '=' )
79                         continue ;
80                 *env = string;
81                 return 0;
82         }
83         if( num_allocated_slots >= envc+1 )
84         {
85                 num_allocated_slots += alloc_step;
86                 expected_environ = realloc(expected_environ, num_allocated_slots*sizeof(char*));
87                 if(!expected_environ)
88                         return 1;
89                 environ = expected_environ;
90         }
91         environ[envc] = string;
92         environ[envc+1] = NULL;
93         
94         return 0;
95 }
96

UCC git Repository :: git.ucc.asn.au