...
If you do not immediately use and discard this string, make a copy of the referenced string returned by getenv() so that this copy may be safely referenced at a later time. The getenv() function is not thread-safe. Make sure to address any possible race conditions resulting from the use of this function.
Implementation Details
According to the Microsoft Visual Studio 2005/.NET Framework 2.0 help pages:
The
getenvfunction searches the list of environment variables forvarname.getenvis not case sensitive in the Windows operating system.getenvand_putenvuse the copy of the environment pointed to by the global variable_environto access the environment.getenvoperates only on the data structures accessible to the run-time library and not on the environment "segment" created for the process by the operating system. Therefore, programs that use theenvpargument tomainorwmainmay retrieve invalid information.
and
The _putenv and _getenv families of functions are not thread-safe. _getenv could return a string pointer while _putenv is modifying the string, causing random failures. Make sure that calls to these functions are synchronized.
Non-Compliant Coding Example
Non-Compliant Coding Example
This non-compliant code example compares the value of the TMP and TEMP environment variables to determine if they are the same. This code example is non-compliant because the string referenced by pwd tmpvar may be overwritten as a result of the second call to getenv() function. As a result, it is possible that both pwd tmpvar and home will refer to the same string tempvar will compare equal even if the two environment variables have different values.
| Code Block | ||
|---|---|---|
| ||
char *pwdtmpvar; char *hometempvar; pwdtmpvar = getenv("PWDTMP"); if (!pwdtmpvar) return -1; hometempvar = getenv("HOMETEMP"); if (!hometempvar) return -1; if (strcmp(pwdtmpvar, hometempvar) == 0) { puts("pwdTMP and homeTEMP are the same.\n"); } else { puts("pwdTMP and homeTEMP are NOT the same.\n"); } |
Compliant Solution (Windows)
Microsoft Visual Studio 2005 provides provides the ((getenv_s()}} and _wgetenv_s() functions for getting a value from the current environment.
| Code Block | ||
|---|---|---|
| ||
#include <stdlib.h> #include <stdio.h> int main( void ) { char* libvar; size_t requiredSize; getenv_s( &requiredSize, NULL, 0, "LIB"); libvar = (char*) malloc(requiredSize * sizeof(char)); if (!libvar) { /* handle error printf("Failed to allocate memory!\n"); exit(1); condition */ } // Get the value of the LIB environment variable. getenv_s( &requiredSize, libvar, requiredSize, "LIB" ); |
Compliant Solution (Windows)
...
The _dupenv_s() function searches the list of environment variables for a specified name. If the name is found, a buffer is allocated, the variable's value is copied into the buffer, and the buffer's address and number of elements are returned. By allocating the buffer itself, _dupenv_s() provides a more convenient alternative to getenv_s(), _wgetenv_s().
It is the calling program's responsibility to free the memory by calling free()_.
| Code Block | ||
|---|---|---|
| ||
char *pValue;
size_t len;
errno_t err = _dupenv_s(&pValue, &len, "pathext");
if (err) return -1;
printf("pathext = %s\n", pValue);
free(pValue);
err = _dupenv_s(&pValue, &len, "nonexistentvariable");
if (err) return -1;
printf("nonexistentvariable = %s\n", pValue);
free(pValue); // It's OK to call free with NULL
|
...