diff options
-rw-r--r-- | lib/libc/stdlib/getenv.c | 19 | ||||
-rw-r--r-- | tools/regression/environ/envctl.c | 41 | ||||
-rw-r--r-- | tools/regression/environ/envtest.t | 54 |
3 files changed, 82 insertions, 32 deletions
diff --git a/lib/libc/stdlib/getenv.c b/lib/libc/stdlib/getenv.c index 74595b2..0f84082 100644 --- a/lib/libc/stdlib/getenv.c +++ b/lib/libc/stdlib/getenv.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2007 Sean C. Farley <scf@FreeBSD.org> + * Copyright (c) 2007-2008 Sean C. Farley <scf@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -431,11 +431,13 @@ getenv(const char *name) /* * Find environment variable via environ if no changes have been made - * via a *env() call or environ has been replaced by a running program, - * otherwise, use the rebuilt environment. + * via a *env() call or environ has been replaced or cleared by a + * running program, otherwise, use the rebuilt environment. */ if (envVars == NULL || environ != intEnviron) return (__findenv_environ(name, nameLen)); + else if (environ[0] == NULL) + return (NULL); else { envNdx = envVarsTotal - 1; return (__findenv(name, nameLen, &envNdx, true)); @@ -525,8 +527,8 @@ __setenv(const char *name, size_t nameLen, const char *value, int overwrite) /* * If the program attempts to replace the array of environment variables - * (environ) environ, then deactivate all variables and merge in the new list - * from environ. + * (environ) environ or sets the first varible to NULL, then deactivate all + * variables and merge in the new list from environ. */ static int __merge_environ(void) @@ -534,8 +536,11 @@ __merge_environ(void) char **env; char *equals; - /* environ has been replaced. clean up everything. */ - if (envVarsTotal > 0 && environ != intEnviron) { + /* + * Internally-built environ has been replaced or cleared. clean up + * everything. + */ + if (envVarsTotal > 0 && (environ != intEnviron || environ[0] == NULL)) { /* Deactivate all environment variables. */ if (envActive > 0) { origEnviron = NULL; diff --git a/tools/regression/environ/envctl.c b/tools/regression/environ/envctl.c index 0fee86c..7858211 100644 --- a/tools/regression/environ/envctl.c +++ b/tools/regression/environ/envctl.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2007 Sean C. Farley <scf@FreeBSD.org> + * Copyright (c) 2007-2008 Sean C. Farley <scf@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,15 +60,19 @@ dump_environ(void) static void usage(const char *program) { - fprintf(stderr, "Usage: %s [-CDGUchrt] [-gu name] [-p name=value] " - "[(-S|-s name) value overwrite]\n\n" + fprintf(stderr, "Usage: %s [-DGUchrt] [-c 1|2|3|4] [-gu name] " + "[-p name=value]\n" + "\t[(-S|-s name) value overwrite]\n\n" "Options:\n" - " -C\t\t\t\tClear environ variable with NULL pointer\n" " -D\t\t\t\tDump environ\n" " -G name\t\t\tgetenv(NULL)\n" " -S value overwrite\t\tsetenv(NULL, value, overwrite)\n" " -U\t\t\t\tunsetenv(NULL)\n" - " -c\t\t\t\tClear environ variable with calloc()'d memory\n" + " -c 1|2|3|4\t\t\tClear environ variable using method:\n" + "\t\t\t\t1 - set environ to NULL pointer\n" + "\t\t\t\t2 - set environ[0] to NULL pointer\n" + "\t\t\t\t3 - set environ to calloc()'d NULL-terminated array\n" + "\t\t\t\t4 - set environ to static NULL-terminated array\n" " -g name\t\t\tgetenv(name)\n" " -h\t\t\t\tHelp\n" " -p name=value\t\t\tputenv(name=value)\n" @@ -98,10 +102,11 @@ print_rtrn_errno(int rtrnVal, const char *eol) int main(int argc, char **argv) { - char *staticEnv[] = { "FOO=bar", NULL }; char arg; const char *eol = "\n"; const char *value; + static char *emptyEnv[] = { NULL }; + static char *staticEnv[] = { "FOO=bar", NULL }; if (argc == 1) { usage(argv[0]); @@ -109,14 +114,26 @@ main(int argc, char **argv) } /* The entire program is basically executed from this loop. */ - while ((arg = getopt(argc, argv, "CDGS:Ucg:hp:rs:tu:")) != -1) { + while ((arg = getopt(argc, argv, "DGS:Uc:g:hp:rs:tu:")) != -1) { switch (arg) { - case 'C': - environ = NULL; - break; - case 'c': - environ = calloc(1, sizeof(*environ)); + switch (atoi(optarg)) { + case 1: + environ = NULL; + break; + + case 2: + environ[0] = NULL; + break; + + case 3: + environ = calloc(1, sizeof(*environ)); + break; + + case 4: + environ = emptyEnv; + break; + } break; case 'D': diff --git a/tools/regression/environ/envtest.t b/tools/regression/environ/envtest.t index d3243d3..6b5485a 100644 --- a/tools/regression/environ/envtest.t +++ b/tools/regression/environ/envtest.t @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2007 Sean C. Farley <scf@FreeBSD.org> +# Copyright (c) 2007-2008 Sean C. Farley <scf@FreeBSD.org> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -81,19 +81,47 @@ export FOO=${BAR} run_test -g FOO check_result "${FOO}" -run_test -c -g FOO +run_test -c 3 -g FOO check_result "${NULL}" run_test -g FOOBAR check_result "${NULL}" -run_test -c -g FOOBAR +run_test -c 3 -g FOOBAR check_result "${NULL}" run_test -G check_result "${NULL}" +# Clear environ. +run_test -c 1 -g FOO +check_result "${NULL}" + +run_test -c 2 -g FOO +check_result "${NULL}" + +run_test -c 3 -g FOO +check_result "${NULL}" + +run_test -c 4 -g FOO +check_result "${NULL}" + + +# Clear environ and verify values do not return after a set. +run_test -c 1 -g FOO -s FOO2 ${NEWBAR} 1 -g FOO -g FOO2 +check_result "${NULL} 0 0 ${NULL} ${NEWBAR}" + +run_test -c 2 -g FOO -s FOO2 ${NEWBAR} 1 -g FOO -g FOO2 +check_result "${NULL} 0 0 ${NULL} ${NEWBAR}" + +run_test -c 3 -g FOO -s FOO2 ${NEWBAR} 1 -g FOO -g FOO2 +check_result "${NULL} 0 0 ${NULL} ${NEWBAR}" + +run_test -c 4 -g FOO -s FOO2 ${NEWBAR} 1 -g FOO -g FOO2 +check_result "${NULL} 0 0 ${NULL} ${NEWBAR}" + + # Sets. run_test -s FOO ${NEWBAR} 0 -g FOO check_result "0 0 ${BAR}" @@ -101,10 +129,10 @@ check_result "0 0 ${BAR}" run_test -s FOO ${NEWBAR} 1 -g FOO check_result "0 0 ${NEWBAR}" -run_test -c -s FOO ${NEWBAR} 0 -g FOO +run_test -c 3 -s FOO ${NEWBAR} 0 -g FOO check_result "0 0 ${NEWBAR}" -run_test -c -s FOO ${NEWBAR} 1 -g FOO +run_test -c 3 -s FOO ${NEWBAR} 1 -g FOO check_result "0 0 ${NEWBAR}" run_test -s "FOO=" ${NEWBAR} 1 -g FOO @@ -125,7 +153,7 @@ check_result "-1 22" run_test -s FOO ${NEWBAR} 1 -s FOO ${BAR} 1 -g FOO check_result "0 0 0 0 ${BAR}" -run_test -c -s FOO ${NEWBAR} 1 -s FOO ${BAR} 1 -g FOO +run_test -c 3 -s FOO ${NEWBAR} 1 -s FOO ${BAR} 1 -g FOO check_result "0 0 0 0 ${BAR}" run_test -s FOO ${NEWBAR} 1 -s FOO ${BAR} 1 -s FOO ${NEWBAR} 1 -g FOO @@ -135,7 +163,7 @@ run_test -s FOO ${NEWBAR} 1 -s FOO ${BAR} 1 -s FOO ${NEWBAR} 1 -s FOO ${BAR} 1\ -g FOO check_result "0 0 0 0 0 0 0 0 ${BAR}" -run_test -c -s FOO ${BAR} 1 -g FOO -c -s FOO ${NEWBAR} 1 -g FOO +run_test -c 3 -s FOO ${BAR} 1 -g FOO -c 3 -s FOO ${NEWBAR} 1 -g FOO check_result "0 0 ${BAR} 0 0 ${NEWBAR}" @@ -143,7 +171,7 @@ check_result "0 0 ${BAR} 0 0 ${NEWBAR}" run_test -u FOO -g FOO check_result "0 0 ${NULL}" -run_test -c -u FOO -g FOO +run_test -c 3 -u FOO -g FOO check_result "0 0 ${NULL}" run_test -U @@ -155,10 +183,10 @@ check_result "-1 22" run_test -u "=${BAR}" check_result "-1 22" -run_test -c -s FOO ${NEWBAR} 1 -g FOO -u FOO -g FOO +run_test -c 3 -s FOO ${NEWBAR} 1 -g FOO -u FOO -g FOO check_result "0 0 ${NEWBAR} 0 0 ${NULL}" -run_test -c -u FOO -s FOO ${BAR} 1 -g FOO -u FOO -g FOO -c -u FOO\ +run_test -c 3 -u FOO -s FOO ${BAR} 1 -g FOO -u FOO -g FOO -c 3 -u FOO\ -s FOO ${NEWBAR} 1 -g FOO check_result "0 0 0 0 ${BAR} 0 0 ${NULL} 0 0 0 0 ${NEWBAR}" @@ -167,7 +195,7 @@ check_result "0 0 0 0 ${BAR} 0 0 ${NULL} 0 0 0 0 ${NEWBAR}" run_test -p FOO=${NEWBAR} -g FOO check_result "0 0 ${NEWBAR}" -run_test -c -p FOO=${NEWBAR} -g FOO +run_test -c 3 -p FOO=${NEWBAR} -g FOO check_result "0 0 ${NEWBAR}" run_test -p FOO -g FOO @@ -191,10 +219,10 @@ check_result "0 0 0 0 0 0" run_test -s FOO ${NEWBAR} 1 -p FOO=${BAR} -u FOO check_result "0 0 0 0 0 0" -run_test -s FOO ${NEWBAR} 1 -p FOO=${BAR} -c -g FOO -p FOO=${NEWBAR} -g FOO +run_test -s FOO ${NEWBAR} 1 -p FOO=${BAR} -c 3 -g FOO -p FOO=${NEWBAR} -g FOO check_result "0 0 0 0 ${NULL} 0 0 ${NEWBAR}" -run_test -c -p FOO=${BAR} -g FOO -c -p FOO=${NEWBAR} -g FOO +run_test -c 3 -p FOO=${BAR} -g FOO -c 3 -p FOO=${NEWBAR} -g FOO check_result "0 0 ${BAR} 0 0 ${NEWBAR}" |