...
For example, when compiled with GCC 3.4.6 and run on a 32-bit Intel GNU/Linux machine, the following code,
Code Block |
---|
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
/* ... */
int main(int argc, const char *argv[], const char *envp[]) {
printf("environ: %p\n", environ);
printf("envp: %p\n", envp);
setenv("MY_NEW_VAR", "new_value", 1);
puts("--Added MY_NEW_VAR--");
printf("environ: %p\n", environ);
printf("envp: %p\n", envp);
return 0;
}
|
yields
Code Block |
---|
% ./envp-environ
environ: 0xbf8656ec
envp: 0xbf8656ec
--Added MY_NEW_VAR--
environ: 0x804a008
envp: 0xbf8656ec
|
...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[], const char *envp[]) {
size_t i;
if (setenv("MY_NEW_VAR", "new_value", 1) != 0) {
/* Handle error */
}
if (envp != NULL) {
for (size_t i = 0; envp[i] != NULL; i++i) {
if (puts(envp[i]) == EOF) {
/* Handle error */
}
}
}
return 0;
}
|
Because envp
may no longer point to the current environment, this program has undefined behavior.
...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
/* ... */
int main(int argc, const char *argv[]) {
size_t i;
if (setenv("MY_NEW_VAR", "new_value", 1) != 0) {
/* Handle error */
}
if (environ != NULL) {
for (size_t i = 0; environ[i] != NULL; i++i) {
if (puts(environ[i]) == EOF) {
/* Handle error */
}
}
}
return 0;
}
|
Noncompliant Code Example (Windows)
...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[], const char *envp[]) {
size_t i;
if (_putenv_s("MY_NEW_VAR", "new_value") != 0) {
/* Handle error */
}
if (envp != NULL) {
for (size_t i = 0; envp[i] != NULL; i++i) {
if (puts(envp[i]) == EOF) {
/* Handle error */
}
}
}
return 0;
}
|
Because envp
no longer points to the current environment, this program fails to print the value of MY_NEW_VAR
.
...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
_CRTIMP extern char **_environ;
/* ... */
int main(int argc, const char *argv[]) {
size_t i;
if (_putenv_s("MY_NEW_VAR", "new_value") != 0) {
/* Handle error */
}
if (_environ != NULL) {
for (i = 0; _environ[i] != NULL; i++i) {
if (puts(_environ[i]) == EOF) {
/* Handle error */
}
}
}
return 0;
}
|
Compliant Solution
...
Code Block |
---|
|
#if defined (_POSIX_) || defined (__USE_POSIX)
extern char **environ;
#define envp environ
#else#elif defined(_WIN32)
_CRTIMP extern char **_environ;
#define envp _environ
#endif
int main(int argc, char *argv[]) {
/* ... */
}
|
...
Bibliography
...