Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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 getenv function searches the list of environment variables for varname. getenv is not case sensitive in the Windows operating system. getenv and _putenv use the copy of the environment pointed to by the global variable _environ to access the environment. getenv operates 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 the envp argument to main or wmain may 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
bgColor#FFcccc
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
bgColor#ccccff

#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
bgColor#ccccff
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

...