Thread safe, reentrant, async-signal safe putenv Thread safe, reentrant, async-signal safe putenv unix unix

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.