Versions Compared

Key

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

...

If you do not immediately make a copy of the value returned by getenv(), but instead store the pointer somewhere for later use, you could end up with a dangling pointer or a different value altogether.

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.

Non-Compliant Coding Example

Code Block
bgColor#FFcccc
char *pwd;
char *home;
  
pwd = getenv("PWD");
if (!pwd) return -1;
home = getenv("HOME");
if (!home) return -1;

if (strcmp(pwd, home) == 0) {
  puts("pwd and home are the same.\n");
}
else {
  puts("pwd and home are NOT the same.\n");    
}

Compliant Solution (Windows)

Microsoft Visual Studio 2005 provides provides the ((_dupenv_s()}} and _wdupenv_s() functions for getting a value from the current environment. http://msdn2.microsoft.com/en-us/library/ms175774(VS.80).aspxImage Added

The ((_dupenv_s()}} function searches the list of environment variables for varname. If the variable is found, a buffer is allocated, the variable's value is copied into the buffer, and the buffer's address and length are returned in buffer and numberOfElements. 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

Compliant Solution

Code Block
bgColor#ccccff

...