Thread safe, reentrant, async-signal safe putenv
This code is a problem:
// If we get here, the env var didn't already exist, so we add it.// Note that malloc isn't async-signal safe. This is why we block signals.environ[i] = malloc(sizeof(char *));environ[i] = string;
It creates a char *
on the heap, assigns the address of that char *
to environ[i]
, then overwrites that value with the address contained in string
. That's not going to work. It doesn't guarantee that environ
is NULL-terminated afterwards.
Because char **environ
is a pointer to an array of pointers. The last pointer in the array is NULL
- that's how code can tell it's reached the end of the list of environment variables.
Something like this should work better:
unsigned int envCount;for ( envCount = 0; environ[ envCount ]; envCount++ ){ /* empty loop */;}/* since environ[ envCount ] is NULL, the environ array of pointers has envCount + 1 elements in it */envCount++;/* grow the environ array by one pointer */char ** newEnviron = realloc( environ, ( envCount + 1 ) * sizeof( char * ) );/* add the new envval */newEnviron[ envCount - 1 ] = newEnvval;/* NULL-terminate the array of pointers */newEnviron[ envCount ] = NULL;environ = newEnviron;
Note that there's no error checking, and it assumes the original environ
array was obtained via a call to malloc()
or similar. If that assumption is wrong, the behavior is undefined.