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