aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/env/env.115
-rw-r--r--usr.bin/env/env.c22
-rw-r--r--usr.bin/env/tests/env_test.sh25
3 files changed, 54 insertions, 8 deletions
diff --git a/usr.bin/env/env.1 b/usr.bin/env/env.1
index 5581d3838a7b..bdf920eabb42 100644
--- a/usr.bin/env/env.1
+++ b/usr.bin/env/env.1
@@ -28,7 +28,7 @@
.\" SUCH DAMAGE.
.\" From FreeBSD: src/usr.bin/printenv/printenv.1,v 1.17 2002/11/26 17:33:35 ru Exp
.\"
-.Dd October 7, 2024
+.Dd October 8, 2024
.Dt ENV 1
.Os
.Sh NAME
@@ -42,6 +42,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
@@ -79,6 +80,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
@@ -506,7 +513,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
@@ -529,6 +536,10 @@ and
.Fl U
options were added in
.Fx 13.0 .
+The
+.Fl C
+option was added in
+.Fx 14.2 .
.Sh BUGS
The
.Nm
diff --git a/usr.bin/env/env.c b/usr.bin/env/env.c
index 762c5dc4d551..bb83baee114f 100644
--- a/usr.bin/env/env.c
+++ b/usr.bin/env/env.c
@@ -59,7 +59,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;
@@ -70,6 +70,7 @@ main(int argc, char **argv)
int rtrn;
altpath = NULL;
+ altwd = NULL;
login_class = NULL;
login_name = NULL;
pw = NULL;
@@ -77,7 +78,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':
@@ -86,6 +87,9 @@ main(int argc, char **argv)
case '0':
term = '\0';
break;
+ case 'C':
+ altwd = optarg;
+ break;
case 'U':
login_as_user = true;
/* FALLTHROUGH */
@@ -93,7 +97,7 @@ main(int argc, char **argv)
login_name = optarg;
break;
case 'P':
- altpath = strdup(optarg);
+ altpath = optarg;
break;
case 'S':
/*
@@ -186,6 +190,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) {
@@ -199,6 +206,11 @@ 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);
@@ -209,7 +221,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);
}
diff --git a/usr.bin/env/tests/env_test.sh b/usr.bin/env/tests/env_test.sh
index da238caaf7fa..d49765a04f9a 100644
--- a/usr.bin/env/tests/env_test.sh
+++ b/usr.bin/env/tests/env_test.sh
@@ -83,6 +83,8 @@ 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" \
@@ -100,7 +102,7 @@ equal_body()
chmod 0755 "magic=words"
atf_check -o match:"^${PWD}/magic=words$" \
env "${PWD}/magic=words"
- atf_check -o match:"^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"
@@ -108,6 +110,26 @@ equal_body()
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_init_test_cases()
{
atf_add_test_case basic
@@ -117,4 +139,5 @@ atf_init_test_cases()
atf_add_test_case false
atf_add_test_case altpath
atf_add_test_case equal
+ atf_add_test_case chdir
}