summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/stdlib/getenv.c19
-rw-r--r--tools/regression/environ/envctl.c41
-rw-r--r--tools/regression/environ/envtest.t54
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}"
OpenPOWER on IntegriCloud