Wiki Markup |
---|
TheC99 defines {{getenv()}} functionto searches an environment list, provided by have the hostfollowing environment, for a string that matches a specified name. The {{getenv()}} function returns a pointer to a string associated with the matched list member. It is best not to store this pointer as it may be overwritten by a subsequent call to the {{getenv()}} function \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] or invalidated as a result of changes made to the environment list through calls to {{putenv()}}, {{setenv()}}, or other means. Storing the pointer for later use can result in a dangling pointer or a pointer to incorrect data. |
Wiki Markup |
---|
According to C99 \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]: |
The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function.
This allows an implementation, for example, to copy the environmental variable to an internal static buffer and return a pointer to that buffer.
behavior: \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]: |
The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function.
Consequently, it is best not to store this pointer as it may be overwritten by a subsequent call to the getenv()
function or invalidated as a result of changes made to the environment list through calls to putenv()
, setenv()
, or other means. Storing the pointer for later use can result in a dangling pointer or a pointer to incorrect data.
This This string should be referenced immediately and discarded, or copied so that the copy may be referenced safely 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.
...
Compliant Solution (Windows)
Wiki Markup |
---|
Windows provides the [{{ |
Microsoft Visual Studio 2005 provides provides the getenv_s()}} and {{\_wgetenv_s()}}|http://msdn.microsoft.com/en-us/library/tb2sfw2z(VS.80).aspx] functions for getting a value from the current environment \[[MSDN|AA. C References#MSDN]\]. |
Code Block |
---|
|
char *tmpvar;
char *tempvar;
size_t requiredSize;
getenv_s(&requiredSize, NULL, 0, "TMP");
tmpvar = (char *)malloc(requiredSize * sizeof(char));
if (!tmpvar) {
/* handleHandle error conditionError */
}
getenv_s(&requiredSize, tmpvar, requiredSize, "TMP" );
getenv_s(&requiredSize, NULL, 0, "TEMP");
tempvar = (char *)malloc(requiredSize * sizeof(char));
if (!tempvar) {
free(tmpvar);
tmpvar = NULL;
/* handleHandle errorError condition */
}
getenv_s(&requiredSize, tempvar, requiredSize, "TEMP" );
if (strcmp(tmpvar, tempvar) == 0) {
puts("TMP and TEMP are the same.\n");
}
else {
puts("TMP and TEMP are NOT the same.\n");
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;
|
Compliant Solution (Windows)
Wiki Markup |
---|
Microsoft Visual Studio 2005 providesWindows also provides the [{{\_dupenv_s()}} and {{\_wdupenv_s()}}|http://msdn.microsoft.com/en-us/library/ms175774.aspx] functions for getting a value from the current environment. \[[Microsoft Visual Studio 2005/.NET Framework 2.0 help pages|http://msdn2.microsoft.com/en-us/library/ms175774(VS.80).aspxMSDN|AA. C References#MSDN]\]. |
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 and _wdupenv_s()
provide a more convenient alternative to getenv_s()
, and _wgetenv_s()
.
It is the calling program's responsibility to free the memory by calling free()
.
...
Compliant Solution (POSIX)
Wiki Markup |
---|
The following compliant solution depends onPOSIX provides the POSIX [{{strdup()}}|http://www.opengroup.org/onlinepubs/009695399/functions/strdup.html] function which tocan make a copy of the environment variable string \[[Open Group 04|AA. C References#Open Group 04]\]. The {{strdup()}} function is also included in ISO/IEC PDTR 24731-2 \[[ISO/IEC PDTR 24731-2|AA. C References#ISO/IEC ISO/IEC PDTR 24731-2]\]. |
Code Block |
---|
|
char *tmpvar;
char *tempvar;
char *temp = getenv("TMP");
if (temp != NULL) {
tmpvar = strdup(temp);
if (tmpvar == NULL) {
/* handleHandle error conditionError */
}
}
else {
return -1;
}
temp = getenv("TEMP");
if (temp != NULL) {
tempvar = strdup(temp);
if (tempvar == NULL) {
free(tmpvar);
tmpvar = NULL;
/* handle error condition */
}
}
else {
free(tmpvar);
tmpvar = NULL;
return -1;
}
if (strcmp(tmpvar, tempvar) == 0) {
puts("TMP and TEMP are the same.\n");
}
else {
puts("TMP and TEMP are NOT the same.\n");
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;
|
Compliant Solution
This compliant solution is fully portableuses only the C99 malloc()
and strcpy()
functions to copy the string returned by getenv()
into a dynamically allocated buffer.
Code Block |
---|
|
char *tmpvar;
char *tempvar;
char *temp = getenv("TMP");
if (temp != NULL) {
tmpvar = (char *)malloc(strlen(temp)+1);
if (tmpvar != NULL) {
strcpy(tmpvar, temp);
}
else {
/* handleHandle error conditionError */
}
}
else {
return -1;
}
temp = getenv("TEMP");
if (temp != NULL) {
tempvar = (char *)malloc(strlen(temp)+1);
if (tempvar != NULL) {
strcpy(tempvar, temp);
}
else {
free(tmpvar);
tmpvar = NULL;
/* handleHandle errorError condition */
}
}
else {
free(tmpvar);
tmpvar = NULL;
return -1;
}
if (strcmp(tmpvar, tempvar) == 0) {
puts("TMP and TEMP are the same.\n");
}
else {
puts("TMP and TEMP are NOT the same.\n");
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;
|
...
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.4, "Communication with the environment"
\[[ISO/IEC PDTR 24731-2|AA. C References#ISO/IEC PDTR 24731-2-2007]\]
\[[MSDN|AA. C References#MSDN]\] [{{\_dupenv_s()}} and {{\_wdupenv_s()}}|http://msdn.microsoft.com/en-us/library/ms175774.aspx], [{{getenv_s()}}, {{\_wgetenv_s()}}|http://msdn.microsoft.com/en-us/library/tb2sfw2z(VS.80).aspx]
\[[Open Group 04|AA. C References#Open Group 04]\] Chapter 8, "Environment Variables", [strdup|http://www.opengroup.org/onlinepubs/009695399/functions/strdup.html]
\[[Viega 03|AA. C References#Viega 03]\] Section 3.6, "Using Environment Variables Securely" |
...