aboutsummaryrefslogtreecommitdiff
path: root/tools/regression/environ
diff options
context:
space:
mode:
Diffstat (limited to 'tools/regression/environ')
-rw-r--r--tools/regression/environ/Makefile13
-rw-r--r--tools/regression/environ/Makefile.envctl15
-rw-r--r--tools/regression/environ/Makefile.retention15
-rw-r--r--tools/regression/environ/Makefile.timings15
-rw-r--r--tools/regression/environ/envctl.c215
-rw-r--r--tools/regression/environ/envtest.t248
-rw-r--r--tools/regression/environ/retention.c106
-rw-r--r--tools/regression/environ/timings.c197
8 files changed, 824 insertions, 0 deletions
diff --git a/tools/regression/environ/Makefile b/tools/regression/environ/Makefile
new file mode 100644
index 000000000000..00796304b60d
--- /dev/null
+++ b/tools/regression/environ/Makefile
@@ -0,0 +1,13 @@
+#
+#
+PROGS= envctl retention timings
+
+all clean test:
+.for target in ${.TARGET}
+.for prog in ${PROGS}
+ @${MAKE} -f Makefile.${prog} ${target}
+.endfor
+.if make(clean)
+ rm -f *~
+.endif
+.endfor
diff --git a/tools/regression/environ/Makefile.envctl b/tools/regression/environ/Makefile.envctl
new file mode 100644
index 000000000000..37fac012cd2e
--- /dev/null
+++ b/tools/regression/environ/Makefile.envctl
@@ -0,0 +1,15 @@
+#
+#
+SRCS= envctl.c
+PROG= envctl
+
+CFLAGS+=-Wall -I../../../include
+
+CLEANFILES= ${PROG}.core
+
+MAN=
+
+.include <bsd.prog.mk>
+
+test: ${PROG}
+ @env -i sh envtest.t
diff --git a/tools/regression/environ/Makefile.retention b/tools/regression/environ/Makefile.retention
new file mode 100644
index 000000000000..90eb544c5afc
--- /dev/null
+++ b/tools/regression/environ/Makefile.retention
@@ -0,0 +1,15 @@
+#
+#
+SRCS= retention.c
+PROG= retention
+
+CFLAGS+=-Wall -I../../../include
+
+CLEANFILES= *~ ${PROG}.core
+
+MAN=
+
+.include <bsd.prog.mk>
+
+test: ${PROG}
+ @./${PROG}
diff --git a/tools/regression/environ/Makefile.timings b/tools/regression/environ/Makefile.timings
new file mode 100644
index 000000000000..4d48eb44d386
--- /dev/null
+++ b/tools/regression/environ/Makefile.timings
@@ -0,0 +1,15 @@
+#
+#
+SRCS= timings.c
+PROG= timings
+
+CFLAGS+=-Wall -I../../../include
+
+CLEANFILES= ${PROG}.core
+
+MAN=
+
+.include <bsd.prog.mk>
+
+test: ${PROG}
+ @./timings
diff --git a/tools/regression/environ/envctl.c b/tools/regression/environ/envctl.c
new file mode 100644
index 000000000000..06071f642cc1
--- /dev/null
+++ b/tools/regression/environ/envctl.c
@@ -0,0 +1,215 @@
+/*-
+ * Copyright (c) 2007-2008 Sean C. Farley <scf@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <errno.h>
+#include <libgen.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include <sys/cdefs.h>
+extern char **environ;
+
+
+/*
+ * Print entire environ array.
+ */
+static void
+dump_environ(void)
+{
+ char **environPtr;
+
+ for (environPtr = environ; *environPtr != NULL; environPtr++)
+ printf("%s\n", *environPtr);
+
+ return;
+}
+
+
+/*
+ * Print usage.
+ */
+static void
+usage(const char *program)
+{
+ fprintf(stderr, "Usage: %s [-DGUchrt] [-c 1|2|3|4] [-bgu name] "
+ "[-p name=value]\n"
+ "\t[(-S|-s name) value overwrite]\n\n"
+ "Options:\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"
+ " -b name\t\t\tblank the 'name=$name' entry, corrupting it\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"
+ " -r\t\t\t\treplace environ with { \"FOO=bar\", NULL }\n"
+ " -s name value overwrite\tsetenv(name, value, overwrite)\n"
+ " -t\t\t\t\tOutput is suitable for testing (no newlines)\n"
+ " -u name\t\t\tunsetenv(name)\n",
+ basename(program));
+
+ return;
+}
+
+
+/*
+ * Print the return value of a call along with errno upon error else zero.
+ * Also, use the eol string based upon whether running in test mode or not.
+ */
+static void
+print_rtrn_errno(int rtrnVal, const char *eol)
+{
+ printf("%d %d%s", rtrnVal, rtrnVal != 0 ? errno : 0, eol);
+
+ return;
+}
+
+static void
+blank_env(const char *var)
+{
+ char **newenviron;
+ int n, varlen;
+
+ if (environ == NULL)
+ return;
+
+ for (n = 0; environ[n] != NULL; n++)
+ ;
+ newenviron = malloc(sizeof(char *) * (n + 1));
+ varlen = strlen(var);
+ for (; n >= 0; n--) {
+ newenviron[n] = environ[n];
+ if (newenviron[n] != NULL &&
+ strncmp(newenviron[n], var, varlen) == 0 &&
+ newenviron[n][varlen] == '=')
+ newenviron[n] += strlen(newenviron[n]);
+ }
+ environ = newenviron;
+}
+
+int
+main(int argc, char **argv)
+{
+ 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]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* The entire program is basically executed from this loop. */
+ while ((arg = getopt(argc, argv, "DGS:Ub:c:g:hp:rs:tu:")) != -1) {
+ switch (arg) {
+ case 'b':
+ blank_env(optarg);
+ break;
+
+ case 'c':
+ 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':
+ dump_environ();
+ break;
+
+ case 'G':
+ case 'g':
+ value = getenv(arg == 'g' ? optarg : NULL);
+ printf("%s%s", value == NULL ? "*NULL*" : value, eol);
+ break;
+
+ case 'p':
+ print_rtrn_errno(putenv(optarg), eol);
+ break;
+
+ case 'r':
+ environ = staticEnv;
+ break;
+
+ case 'S':
+ print_rtrn_errno(setenv(NULL, optarg,
+ atoi(argv[optind])), eol);
+ optind += 1;
+ break;
+
+ case 's':
+ print_rtrn_errno(setenv(optarg, argv[optind],
+ atoi(argv[optind + 1])), eol);
+ optind += 2;
+ break;
+
+ case 't':
+ eol = " ";
+ break;
+
+ case 'U':
+ case 'u':
+ print_rtrn_errno(unsetenv(arg == 'u' ? optarg : NULL),
+ eol);
+ break;
+
+ case 'h':
+ default:
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Output a closing newline in test mode. */
+ if (eol[0] == ' ')
+ printf("\n");
+
+ return (EXIT_SUCCESS);
+}
diff --git a/tools/regression/environ/envtest.t b/tools/regression/environ/envtest.t
new file mode 100644
index 000000000000..5532c2ee7860
--- /dev/null
+++ b/tools/regression/environ/envtest.t
@@ -0,0 +1,248 @@
+#!/bin/sh
+#
+# Copyright (c) 2007-2008 Sean C. Farley <scf@FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer,
+# without modification, immediately at the beginning of the file.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+# Initialization.
+testndx=0
+
+
+# Testing function.
+run_test()
+{
+ lasttest="${@}"
+ result=`./envctl -t "${@}"`
+
+ if [ ${?} -ne 0 ]
+ then
+ echo "Test program failed" >&2
+ exit 1
+ fi
+
+ return
+}
+
+
+# Perform test on results.
+check_result()
+{
+ testndx=$((testndx + 1))
+
+ echo "${result}" | sed 's/[ \t]*$//' | grep -q "^${@}$"
+ if [ ${?} -eq 0 ]
+ then
+ echo "ok ${testndx}"
+ else
+ echo "not ok ${testndx} - '${lasttest}'"
+ fi
+
+ return
+}
+
+
+#
+# Regression tests
+#
+
+# How NULL will be returned by program.
+readonly NULL="\*NULL\*"
+
+# Setup environment for tests.
+readonly BAR="bar"
+readonly NEWBAR="newbar"
+export FOO=${BAR}
+
+
+# Gets from environ.
+run_test -g FOO
+check_result "${FOO}"
+
+run_test -c 3 -g FOO
+check_result "${NULL}"
+
+run_test -g FOOBAR
+check_result "${NULL}"
+
+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}"
+
+run_test -s FOO ${NEWBAR} 1 -g FOO
+check_result "0 0 ${NEWBAR}"
+
+run_test -c 3 -s FOO ${NEWBAR} 0 -g FOO
+check_result "0 0 ${NEWBAR}"
+
+run_test -c 3 -s FOO ${NEWBAR} 1 -g FOO
+check_result "0 0 ${NEWBAR}"
+
+run_test -s "FOO=" ${NEWBAR} 1 -g FOO
+check_result "-1 22 ${BAR}"
+
+run_test -s "=FOO" ${NEWBAR} 1
+check_result "-1 22"
+
+run_test -s "=" ${NEWBAR} 1
+check_result "-1 22"
+
+run_test -s "" ${NEWBAR} 1
+check_result "-1 22"
+
+run_test -S ${NEWBAR} 1
+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 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
+check_result "0 0 0 0 0 0 ${NEWBAR}"
+
+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 3 -s FOO ${BAR} 1 -g FOO -c 3 -s FOO ${NEWBAR} 1 -g FOO
+check_result "0 0 ${BAR} 0 0 ${NEWBAR}"
+
+
+# Unsets.
+run_test -u FOO -g FOO
+check_result "0 0 ${NULL}"
+
+run_test -c 3 -u FOO -g FOO
+check_result "0 0 ${NULL}"
+
+run_test -U
+check_result "-1 22"
+
+run_test -u ""
+check_result "-1 22"
+
+run_test -u "=${BAR}"
+check_result "-1 22"
+
+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 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}"
+
+
+# Puts.
+run_test -p FOO=${NEWBAR} -g FOO
+check_result "0 0 ${NEWBAR}"
+
+run_test -c 3 -p FOO=${NEWBAR} -g FOO
+check_result "0 0 ${NEWBAR}"
+
+run_test -p FOO -g FOO
+check_result "-1 22 ${BAR}"
+
+run_test -p FOO=${BAR} -p FOO=${NEWBAR} -g FOO
+check_result "0 0 0 0 ${NEWBAR}"
+
+run_test -p FOO=${BAR} -s FOO ${NEWBAR} 1 -g FOO
+check_result "0 0 0 0 ${NEWBAR}"
+
+run_test -s FOO ${NEWBAR} 1 -p FOO=${BAR} -g FOO
+check_result "0 0 0 0 ${BAR}"
+
+run_test -p FOO=${BAR} -u FOO
+check_result "0 0 0 0"
+
+run_test -p FOO=${BAR} -s FOO ${NEWBAR} 1 -u FOO
+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 3 -g FOO -p FOO=${NEWBAR} -g FOO
+check_result "0 0 0 0 ${NULL} 0 0 ${NEWBAR}"
+
+run_test -c 3 -p FOO=${BAR} -g FOO -c 3 -p FOO=${NEWBAR} -g FOO
+check_result "0 0 ${BAR} 0 0 ${NEWBAR}"
+
+
+# environ replacements.
+run_test -r -g FOO -s FOO ${BAR} 1 -g FOO -u FOO -g FOO
+check_result "${BAR} 0 0 ${BAR} 0 0 ${NULL}"
+
+run_test -r -g FOO -u FOO -g FOO -s FOO ${BAR} 1 -g FOO
+check_result "${BAR} 0 0 ${NULL} 0 0 ${BAR}"
+
+
+# corruption (blanking) of environ members.
+export BLANK_ME=
+export AFTER_BLANK=blanked
+run_test -b BLANK_ME -p MORE=vars -g FOO -g BLANK_ME -g AFTER_BLANK
+check_result "0 0 ${FOO} ${NULL} ${AFTER_BLANK}"
+
+run_test -b BLANK_ME -u FOO -g FOO -g AFTER_BLANK
+check_result "0 0 ${NULL} ${AFTER_BLANK}"
+
+export BLANK_ME2=
+export AFTER_BLANKS=blankD
+run_test -b BLANK_ME -b AFTER_BLANK -b BLANK_ME2 -g FOO -g AFTER_BLANKS
+check_result "${FOO} ${AFTER_BLANKS}"
diff --git a/tools/regression/environ/retention.c b/tools/regression/environ/retention.c
new file mode 100644
index 000000000000..3edaf8ca1d0a
--- /dev/null
+++ b/tools/regression/environ/retention.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2007 Sean C. Farley <scf@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include <sys/cdefs.h>
+extern char **environ;
+const char *envName = "FOOBAR";
+const char *envValSmall = "Hi";
+const char *envValLarge = "Hi, again";
+const char *envValAny = "Any value";
+
+
+int
+main(int argc, char **argv)
+{
+ const char *env1 = NULL;
+ const char *env2 = NULL;
+ const char *env3 = NULL;
+ const char *env4 = NULL;
+ const char *env5 = NULL;
+ int testNdx;
+
+ /* Clean slate. */
+ environ = NULL;
+ testNdx = 0;
+
+ /* Initial value of variable. */
+ if (getenv(envName) != NULL)
+ printf("not ");
+ printf("ok %d - getenv(\"%s\")\n", ++testNdx, envName);
+
+ /* Set value of variable to smaller value and get value. */
+ if ((setenv(envName, envValSmall, 1) != 0) ||
+ ((env1 = getenv(envName)) == NULL) ||
+ (strcmp(env1, envValSmall) != 0))
+ printf("not ");
+ printf("ok %d - setenv(\"%s\", \"%s\", 1)\n", ++testNdx, envName,
+ envValSmall);
+
+ /* Unset variable. */
+ if ((unsetenv(envName) == -1) || ((env2 = getenv(envName)) != NULL))
+ printf("not ");
+ printf("ok %d - unsetenv(\"%s\")\n", ++testNdx, envName);
+
+ /* Set variable to bigger value and get value. */
+ if ((setenv(envName, envValLarge, 1) != 0) ||
+ ((env3 = getenv(envName)) == NULL) ||
+ (strcmp(env3, envValLarge) != 0))
+ printf("not ");
+ printf("ok %d - setenv(\"%s\", \"%s\", 1)\n", ++testNdx, envName,
+ envValLarge);
+
+ /* Set variable to smaller value and get value. */
+ if ((setenv(envName, envValSmall, 1) != 0) ||
+ ((env4 = getenv(envName)) == NULL) ||
+ (strcmp(env4, envValSmall) != 0))
+ printf("not ");
+ printf("ok %d - setenv(\"%s\", \"%s\", 1)\n", ++testNdx, envName,
+ envValSmall);
+
+ /* Set variable to any value without overwrite and get value. */
+ if ((setenv(envName, envValAny, 0) != 0) ||
+ ((env5 = getenv(envName)) == NULL) ||
+ (strcmp(env5, envValAny) == 0))
+ printf("not ");
+ printf("ok %d - setenv(\"%s\", \"%s\", 0)\n", ++testNdx, envName,
+ envValAny);
+
+ /*
+ * Verify FreeBSD-ism about allowing a program to keep old pointers without
+ * risk of segfaulting.
+ */
+ if ((strcmp(env1, envValSmall) != 0) ||
+ (strcmp(env3, envValSmall) != 0) ||
+ (strcmp(env4, envValSmall) != 0))
+ printf("not ");
+ printf("ok %d - old variables point to valid memory\n", ++testNdx);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/tools/regression/environ/timings.c b/tools/regression/environ/timings.c
new file mode 100644
index 000000000000..ac7dfcaa658f
--- /dev/null
+++ b/tools/regression/environ/timings.c
@@ -0,0 +1,197 @@
+/*-
+ * Copyright (c) 2007 Sean C. Farley <scf@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include <sys/cdefs.h>
+const char value1[] = "Large ------------------ value";
+const char value2[] = "Small -- value";
+char nameValuePair[] = "less=more";
+const char name[] = "PATH";
+const char name2[] = "SHELL";
+const int MaxIterations = 1000000;
+const char Tabs[] = "\t\t\t";
+
+
+static int
+report_time(const char *action, struct timeval *startTime,
+ struct timeval *endTime)
+{
+ int actionLen;
+ int numTabs;
+
+ actionLen = strlen(action);
+ numTabs = 3 - actionLen / 8;
+
+ return (printf("Time spent executing %s:%.*s%f\n", action, numTabs, Tabs,
+ (endTime->tv_sec - startTime->tv_sec) +
+ (double)(endTime->tv_usec - startTime->tv_usec) / 1000000));
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int iterations;
+ struct rusage endUsage;
+ struct rusage startUsage;
+
+ /*
+ * getenv() on the existing environment.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ if (getenv(name) == NULL)
+ err(EXIT_FAILURE, "getenv(name)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("getenv(name)", &startUsage.ru_utime, &endUsage.ru_utime);
+
+
+ /*
+ * setenv() a variable with a large value.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ if (setenv(name, value1, 1) == -1)
+ err(EXIT_FAILURE, "setenv(name, value1, 1)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("setenv(name, value1, 1)", &startUsage.ru_utime,
+ &endUsage.ru_utime);
+
+
+ /*
+ * getenv() the new variable on the new environment.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ /* Set large value to variable. */
+ if (getenv(name) == NULL)
+ err(EXIT_FAILURE, "getenv(name)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("getenv(name)", &startUsage.ru_utime, &endUsage.ru_utime);
+
+
+ /*
+ * getenv() a different variable on the new environment.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ /* Set large value to variable. */
+ if (getenv(name2) == NULL)
+ err(EXIT_FAILURE, "getenv(name2)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("getenv(name2)", &startUsage.ru_utime, &endUsage.ru_utime);
+
+
+ /*
+ * setenv() a variable with a small value.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ if (setenv(name, value2, 1) == -1)
+ err(EXIT_FAILURE, "setenv(name, value2, 1)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("setenv(name, value2, 1)", &startUsage.ru_utime,
+ &endUsage.ru_utime);
+
+
+ /*
+ * getenv() a different variable on the new environment.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ /* Set large value to variable. */
+ if (getenv(name2) == NULL)
+ err(EXIT_FAILURE, "getenv(name)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("getenv(name)", &startUsage.ru_utime, &endUsage.ru_utime);
+
+
+ /*
+ * getenv() a different variable on the new environment.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ /* Set large value to variable. */
+ if (getenv(name2) == NULL)
+ err(EXIT_FAILURE, "getenv(name2)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("getenv(name2)", &startUsage.ru_utime, &endUsage.ru_utime);
+
+
+ /*
+ * putenv() a variable with a small value.
+ */
+ getrusage(RUSAGE_SELF, &startUsage);
+
+ /* Iterate over setting variable. */
+ for (iterations = 0; iterations < MaxIterations; iterations++)
+ if (putenv(nameValuePair) == -1)
+ err(EXIT_FAILURE, "putenv(nameValuePair)");
+
+ getrusage(RUSAGE_SELF, &endUsage);
+
+ report_time("putenv(nameValuePair)", &startUsage.ru_utime,
+ &endUsage.ru_utime);
+
+
+ exit(EXIT_SUCCESS);
+}