The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6f6166e49c78f6460732c02bbbba6fcc218221cf

commit 6f6166e49c78f6460732c02bbbba6fcc218221cf
Author:     Dag-Erling Smørgrav <d...@freebsd.org>
AuthorDate: 2024-10-08 17:01:32 +0000
Commit:     Dag-Erling Smørgrav <d...@freebsd.org>
CommitDate: 2024-10-08 17:01:32 +0000

    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
---
 usr.bin/env/env.1             | 15 +++++++++++++--
 usr.bin/env/env.c             | 22 +++++++++++++++++-----
 usr.bin/env/tests/env_test.sh | 25 ++++++++++++++++++++++++-
 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
 }

Reply via email to