mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
env: Add a handful of test cases.
MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D46996 (cherry picked from commit 334af5e4131b21c658203635bf713d6a59846585) env: Improve documentation. * The `env` utility's inability to run a command whose name contains an equal sign is a feature, not a bug, so move that paragraph up from the BUGS section to the DESCRIPTION section. * Mention that this can be worked around by prefixing the command name with `command`, and add an example of this to the EXAMPLE section. * Add a test case which verifies that `env` does not run a command with an equal sign in its name even if it exists, and also demonstrates the workaround. MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D46997 (cherry picked from commit a0dfb0668b45506de97beb4c7acbe3fd1ba69fc8) env: Add an option to change the directory. This mirrors the equivalent option in GNU coreutils env, but does not add support for long options. MFC after: 3 days Relnotes: yes Sponsored by: Klara, Inc. Reviewed by: 0mp, bcr Differential Revision: https://reviews.freebsd.org/D47008 (cherry picked from commit 6f6166e49c78f6460732c02bbbba6fcc218221cf) env: Check the status of stdout. MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D47009 (cherry picked from commit c2d93a803acef634bd0eede6673aeea59e90c277)
This commit is contained in:
parent
76c656bd97
commit
08e8554c4a
6 changed files with 222 additions and 15 deletions
|
|
@ -1057,6 +1057,8 @@
|
|||
..
|
||||
du
|
||||
..
|
||||
env
|
||||
..
|
||||
factor
|
||||
..
|
||||
file2c
|
||||
|
|
|
|||
4
usr.bin/env/Makefile
vendored
4
usr.bin/env/Makefile
vendored
|
|
@ -1,4 +1,5 @@
|
|||
# From: @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE= runtime
|
||||
PROG= env
|
||||
|
|
@ -6,4 +7,7 @@ SRCS= env.c envopts.c
|
|||
|
||||
LIBADD= util
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
|||
41
usr.bin/env/env.1
vendored
41
usr.bin/env/env.1
vendored
|
|
@ -30,7 +30,7 @@
|
|||
.\" From @(#)printenv.1 8.1 (Berkeley) 6/6/93
|
||||
.\" From FreeBSD: src/usr.bin/printenv/printenv.1,v 1.17 2002/11/26 17:33:35 ru Exp
|
||||
.\"
|
||||
.Dd March 3, 2021
|
||||
.Dd October 8, 2024
|
||||
.Dt ENV 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
.Op Ar name Ns = Ns Ar value ...
|
||||
.Nm
|
||||
.Op Fl iv
|
||||
.Op Fl C Ar altwd
|
||||
.Op Fl L Ns | Ns Fl U Ar user Ns Op / Ns Ar class
|
||||
.Op Fl P Ar altpath
|
||||
.Op Fl S Ar string
|
||||
|
|
@ -81,6 +82,12 @@ The environment inherited
|
|||
by
|
||||
.Nm
|
||||
is ignored completely.
|
||||
.\" -C
|
||||
.It Fl C Ar altwd
|
||||
Change to the specified alternate working directory before executing
|
||||
the specified
|
||||
.Ar utility
|
||||
program.
|
||||
.\" -L | -U
|
||||
.It Fl L | Fl U Ar user Ns Op / Ns Ar class
|
||||
Add the environment variable definitions from
|
||||
|
|
@ -173,6 +180,19 @@ Both
|
|||
and
|
||||
.Ar utility
|
||||
may not be specified together.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility does not handle values of
|
||||
.Ar utility
|
||||
which have an equals sign
|
||||
.Pq Ql =
|
||||
in their name, for obvious reasons.
|
||||
This can easily be worked around by interposing the
|
||||
.Xr command 1
|
||||
utility, which simply executes its arguments; see
|
||||
.Sx EXAMPLES
|
||||
below.
|
||||
.\"
|
||||
.Ss Details of -S (split-string) processing
|
||||
The processing of the
|
||||
|
|
@ -471,6 +491,11 @@ and
|
|||
options:
|
||||
.Pp
|
||||
.Dl "#!/usr/bin/env -S-P/usr/local/bin:/usr/bin:${PATH} perl"
|
||||
.Pp
|
||||
To execute a utility with an equal sign in its name:
|
||||
.Bd -literal -offset indent
|
||||
env name=value ... command foo=bar arg ...
|
||||
.Ed
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Nm
|
||||
|
|
@ -490,7 +515,7 @@ The
|
|||
utility conforms to
|
||||
.St -p1003.1-2001 .
|
||||
The
|
||||
.Fl 0 , L , P , S , U , u
|
||||
.Fl 0 , C , L , P , S , U , u
|
||||
and
|
||||
.Fl v
|
||||
options are non-standard extensions supported by
|
||||
|
|
@ -513,15 +538,11 @@ and
|
|||
.Fl U
|
||||
options were added in
|
||||
.Fx 13.0 .
|
||||
.Sh BUGS
|
||||
The
|
||||
.Nm
|
||||
utility does not handle values of
|
||||
.Ar utility
|
||||
which have an equals sign
|
||||
.Pq Ql =
|
||||
in their name, for obvious reasons.
|
||||
.Pp
|
||||
.Fl C
|
||||
option was added in
|
||||
.Fx 14.2 .
|
||||
.Sh BUGS
|
||||
The
|
||||
.Nm
|
||||
utility does not take multibyte characters into account when
|
||||
|
|
|
|||
24
usr.bin/env/env.c
vendored
24
usr.bin/env/env.c
vendored
|
|
@ -72,7 +72,7 @@ static void usage(void) __dead2;
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *altpath, **ep, *p, **parg, term;
|
||||
char *altpath, *altwd, **ep, *p, **parg, term;
|
||||
char *cleanenv[1];
|
||||
char *login_class, *login_name;
|
||||
struct passwd *pw;
|
||||
|
|
@ -83,6 +83,7 @@ main(int argc, char **argv)
|
|||
int rtrn;
|
||||
|
||||
altpath = NULL;
|
||||
altwd = NULL;
|
||||
login_class = NULL;
|
||||
login_name = NULL;
|
||||
pw = NULL;
|
||||
|
|
@ -90,7 +91,7 @@ main(int argc, char **argv)
|
|||
login_as_user = false;
|
||||
want_clear = 0;
|
||||
term = '\n';
|
||||
while ((ch = getopt(argc, argv, "-0iL:P:S:U:u:v")) != -1)
|
||||
while ((ch = getopt(argc, argv, "-0C:iL:P:S:U:u:v")) != -1)
|
||||
switch(ch) {
|
||||
case '-':
|
||||
case 'i':
|
||||
|
|
@ -99,6 +100,9 @@ main(int argc, char **argv)
|
|||
case '0':
|
||||
term = '\0';
|
||||
break;
|
||||
case 'C':
|
||||
altwd = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
login_as_user = true;
|
||||
/* FALLTHROUGH */
|
||||
|
|
@ -106,7 +110,7 @@ main(int argc, char **argv)
|
|||
login_name = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
altpath = strdup(optarg);
|
||||
altpath = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
/*
|
||||
|
|
@ -199,6 +203,9 @@ main(int argc, char **argv)
|
|||
if (*argv) {
|
||||
if (term == '\0')
|
||||
errx(EXIT_CANCELED, "cannot specify command with -0");
|
||||
if (altwd && chdir(altwd) != 0)
|
||||
err(EXIT_CANCELED, "cannot change directory to '%s'",
|
||||
altwd);
|
||||
if (altpath)
|
||||
search_paths(altpath, argv);
|
||||
if (env_verbosity) {
|
||||
|
|
@ -212,9 +219,16 @@ main(int argc, char **argv)
|
|||
execvp(*argv, argv);
|
||||
err(errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE,
|
||||
"%s", *argv);
|
||||
} else {
|
||||
if (altwd)
|
||||
errx(EXIT_CANCELED, "must specify command with -C");
|
||||
if (altpath)
|
||||
errx(EXIT_CANCELED, "must specify command with -P");
|
||||
}
|
||||
for (ep = environ; *ep; ep++)
|
||||
(void)printf("%s%c", *ep, term);
|
||||
if (fflush(stdout) != 0)
|
||||
err(1, "stdout");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +236,7 @@ static void
|
|||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: env [-0iv] [-L|-U user[/class]] [-P utilpath] [-S string] [-u name]\n"
|
||||
" [name=value ...] [utility [argument ...]]\n");
|
||||
"usage: env [-0iv] [-C workdir] [-L|-U user[/class]] [-P utilpath] [-S string]\n"
|
||||
" [-u name] [name=value ...] [utility [argument ...]]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
|||
6
usr.bin/env/tests/Makefile
vendored
Normal file
6
usr.bin/env/tests/Makefile
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
PACKAGE= tests
|
||||
|
||||
ATF_TESTS_SH= env_test
|
||||
BINDIR= ${TESTSDIR}
|
||||
|
||||
.include <bsd.test.mk>
|
||||
160
usr.bin/env/tests/env_test.sh
vendored
Normal file
160
usr.bin/env/tests/env_test.sh
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#
|
||||
# Copyright (c) 2024 Klara, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
|
||||
magic_words="Squeamish $$ Ossifrage"
|
||||
|
||||
atf_test_case basic
|
||||
basic_head()
|
||||
{
|
||||
atf_set "descr" "Basic test case"
|
||||
}
|
||||
basic_body()
|
||||
{
|
||||
atf_check -o match:"^magic_words=${magic_words}\$" \
|
||||
env magic_words="${magic_words}"
|
||||
export MAGIC_WORDS="${magic_words}"
|
||||
atf_check -o match:"^MAGIC_WORDS=${magic_words}\$" \
|
||||
env
|
||||
unset MAGIC_WORDS
|
||||
}
|
||||
|
||||
atf_test_case unset
|
||||
unset_head()
|
||||
{
|
||||
atf_set "descr" "Unset a variable"
|
||||
}
|
||||
unset_body()
|
||||
{
|
||||
export MAGIC_WORDS="${magic_words}"
|
||||
atf_check -o not-match:"^MAGIC_WORDS=" \
|
||||
env -u MAGIC_WORDS
|
||||
unset MAGIC_WORDS
|
||||
}
|
||||
|
||||
atf_test_case empty
|
||||
empty_head()
|
||||
{
|
||||
atf_set "descr" "Empty environment"
|
||||
}
|
||||
empty_body()
|
||||
{
|
||||
atf_check env -i
|
||||
}
|
||||
|
||||
atf_test_case true
|
||||
true_head()
|
||||
{
|
||||
atf_set "descr" "Run true"
|
||||
}
|
||||
true_body()
|
||||
{
|
||||
atf_check env true
|
||||
}
|
||||
|
||||
atf_test_case false
|
||||
false_head()
|
||||
{
|
||||
atf_set "descr" "Run false"
|
||||
}
|
||||
false_body()
|
||||
{
|
||||
atf_check -s exit:1 env false
|
||||
}
|
||||
|
||||
atf_test_case false
|
||||
false_head()
|
||||
{
|
||||
atf_set "descr" "Run false"
|
||||
}
|
||||
false_body()
|
||||
{
|
||||
atf_check -s exit:1 env false
|
||||
}
|
||||
|
||||
atf_test_case altpath
|
||||
altpath_head()
|
||||
{
|
||||
atf_set "descr" "Use alternate path"
|
||||
}
|
||||
altpath_body()
|
||||
{
|
||||
echo "echo ${magic_words}" >magic_words
|
||||
chmod 0755 magic_words
|
||||
atf_check -s exit:125 -e match:"must specify command" \
|
||||
env -P "${PWD}"
|
||||
atf_check -s exit:127 -e match:"No such file" \
|
||||
env magic_words
|
||||
atf_check -o inline:"${magic_words}\n" \
|
||||
env -P "${PWD}" magic_words
|
||||
}
|
||||
|
||||
atf_test_case equal
|
||||
equal_head()
|
||||
{
|
||||
atf_set "descr" "Command name contains equal sign"
|
||||
}
|
||||
equal_body()
|
||||
{
|
||||
echo "echo ${magic_words}" >"magic=words"
|
||||
chmod 0755 "magic=words"
|
||||
atf_check -o match:"^${PWD}/magic=words$" \
|
||||
env "${PWD}/magic=words"
|
||||
atf_check -s exit:125 -e match:"must specify command" \
|
||||
env -P "${PATH}:${PWD}" "magic=words"
|
||||
atf_check -o inline:"${magic_words}\n" \
|
||||
env command "${PWD}/magic=words"
|
||||
atf_check -o inline:"${magic_words}\n" \
|
||||
env PATH="${PATH}:${PWD}" command "magic=words"
|
||||
}
|
||||
|
||||
atf_test_case chdir
|
||||
chdir_head()
|
||||
{
|
||||
atf_set "descr" "Change working directory"
|
||||
}
|
||||
chdir_body()
|
||||
{
|
||||
local subdir="dir.$$"
|
||||
atf_check -o inline:"${PWD}\n" \
|
||||
env pwd
|
||||
atf_check -s exit:125 -e match:"must specify command" \
|
||||
env -C "${subdir}"
|
||||
atf_check -s exit:125 \
|
||||
-e match:"cannot change directory to '${subdir}':" \
|
||||
env -C "${subdir}" pwd
|
||||
atf_check mkdir "${subdir}"
|
||||
atf_check -o inline:"${PWD}/${subdir}\n" \
|
||||
env -C "${subdir}" pwd
|
||||
}
|
||||
|
||||
atf_test_case stdout
|
||||
stdout_head()
|
||||
{
|
||||
atf_set descr "Failure to write to stdout"
|
||||
}
|
||||
stdout_body()
|
||||
{
|
||||
(
|
||||
trap "" PIPE
|
||||
env 2>stderr
|
||||
echo $? >result
|
||||
) | true
|
||||
atf_check -o inline:"1\n" cat result
|
||||
atf_check -o match:"stdout" cat stderr
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case basic
|
||||
atf_add_test_case unset
|
||||
atf_add_test_case empty
|
||||
atf_add_test_case true
|
||||
atf_add_test_case false
|
||||
atf_add_test_case altpath
|
||||
atf_add_test_case equal
|
||||
atf_add_test_case chdir
|
||||
atf_add_test_case stdout
|
||||
}
|
||||
Loading…
Reference in a new issue