commit: 92c933a1d3fe2cce2bbf5c85c4b89b956c02c9bd
parent a68504597b31351c35baf9808ae3e00a9840c49c
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 8 Dec 2025 18:13:37 +0100
cmd/env: Add -C option (GNU, FreeBSD 15.0)
Diffstat:
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/cmd/env.1 b/cmd/env.1
@@ -10,11 +10,13 @@
.Sh SYNOPSIS
.Nm
.Op Fl i
+.Oo Fl C Ar directory
.Oo Fl u Ar name Oc Ns ...
.Oo Ar name Ns = Ns Ar value Oc Ns ...
.Op Ar command Op Ar argument...
.Nm
.Op Fl i
+.Oo Fl C Ar directory
.Oo Fl u Ar name Oc Ns ...
.Oo Ar name Ns = Ns Ar value Oc Ns ...
.Fl S Ar command_string
@@ -28,6 +30,10 @@ and otherwise prints the environment.
.Pp
The environment can be modified via the following options:
.Bl -tag -width Ds
+.It Fl C Ar directory
+Change workding directory into
+.Ar directory
+before executing the specified command.
.It Fl i
Ignore the existing environment.
.It Fl u Ar name
@@ -92,7 +98,11 @@ GNU coreutils, BusyBox, ...
.br
The
.Fl S
-flag in an extension known to be present in GNU coreutils and
+.\" before FreeBSD 15.0
+and
+.Fl C
+.\" FreeBSD 15.0
+flag are extensions known to be present in GNU coreutils and
.Fx .
.Sh AUTHORS
.An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me
diff --git a/cmd/env.c b/cmd/env.c
@@ -53,13 +53,14 @@ usage(void)
int
main(int argc, char *argv[])
{
+ const char *newdir = NULL;
bool flag_i = false;
#ifdef HAS_WORDEXP
bool flag_S = false;
wordexp_t opt_S;
-#define OPTARGS ":iu:S:"
+#define OPTARGS ":C:iu:S:"
#else
-#define OPTARGS ":iu:"
+#define OPTARGS ":C:iu:"
#endif
#ifdef HAS_GETOPT_LONG
@@ -68,6 +69,7 @@ main(int argc, char *argv[])
static struct option opts[] = {
{"ignore-environment", no_argument, NULL, 'i'},
{"unset", required_argument, NULL, 'u'},
+ {"chdir", required_argument, NULL, 'C'},
#ifdef HAS_WORDEXP
{"split-string", required_argument, NULL, 'S'},
#endif
@@ -83,6 +85,9 @@ main(int argc, char *argv[])
{
switch(c)
{
+ case 'C':
+ newdir = optarg;
+ break;
case 'i':
flag_i = true;
break;
@@ -162,6 +167,15 @@ main(int argc, char *argv[])
}
}
+ if(newdir && chdir(newdir) != 0)
+ {
+ fprintf(stderr,
+ "env: error: Failed changing workding directory into '%s': %s\n",
+ newdir,
+ strerror(errno));
+ return 1;
+ }
+
#ifdef HAS_WORDEXP
if(flag_S)
{
diff --git a/test-cmd/env.sh b/test-cmd/env.sh
@@ -7,8 +7,8 @@ target="${WD}/cmd/env"
. "${WD}/test_functions.sh"
-plans=10
-gentoo_sandbox && plans=6
+plans=11
+gentoo_sandbox && plans=7
. "${WD}/test-cmd/tap.sh"
t exec_true 'true' ''
@@ -21,6 +21,9 @@ t --exit=127 enoent '/var/empty/e/no/ent' "env: error: Failed executing '/var/em
t posix_me_harder "-i FOO=BAR sh -c echo" '
'
+t chdir "-C ${WD}/cmd/ pwd" "$(realpath "${WD}/cmd/")
+"
+
if grep -q HAS_WORDEXP "${WD}/config.h"; then
t_args opt_S 'foo
bar