commit: c81e81c9fba64342444084a8628c55df84605734
parent 4087f6a16718ffe7ca31ec4909ad7701e925b84b
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Fri, 7 Jul 2023 20:13:41 +0200
cmd/env: Add support for --unset
Quite a hack to avoid depending on GNU's getopt_long(3).
Diffstat:
3 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/cmd/env.1 b/cmd/env.1
@@ -11,7 +11,8 @@
.Nm
.Op Fl i
.Op Fl u Ar name
-.Op Ar name=value
+.Op Fl -unset= Ns Ar name
+.Op Ar name Ns = Ns Ar value
.Op Ar command Op Ar argument ...
.Sh DESCRIPTION
.Nm
@@ -22,11 +23,11 @@ The environment can be modified via the following options:
.Bl -tag -width Ds
.It Fl i
Ignore the existing environment.
-.It Fl u Ar name
+.It Fl u Ar name | Fl -unset= Ns Ar name
Removes the variable named
.Ar name
from the new environment.
-.It Ar name=value
+.It Ar name Ns = Ns Ar value
Adds the variable named
.Ar name
with the value
diff --git a/cmd/env.c b/cmd/env.c
@@ -33,7 +33,7 @@ int export()
void
usage()
{
- fprintf(stderr, "env [-i] [-u key] [key=value ...] [command [args]]\n");
+ fprintf(stderr, "env [-i] [-u key | --unset=key] [key=value ...] [command [args]]\n");
}
int
@@ -43,7 +43,7 @@ main(int argc, char *argv[])
bool flag_i = false;
/* flawfinder: ignore. Old implementations of getopt should fix themselves */
- while((c = getopt(argc, argv, ":iu:")) != -1)
+ while((c = getopt(argc, argv, ":iu:-:")) != -1)
{
switch(c)
{
@@ -53,6 +53,25 @@ main(int argc, char *argv[])
case 'u':
unsetenv(optarg);
break;
+ case '-':
+ char *val = strchr(optarg, '=');
+ if(val == NULL)
+ {
+ fprintf(stderr, "env: Error: Missing = in long option\n", optopt);
+ return 1;
+ }
+
+ *val = 0;
+ val++;
+
+ if(strcmp(optarg, "unset") != 0)
+ {
+ fprintf(stderr, "env: Error: Unknown long option --%s\n", optarg);
+ return 1;
+ }
+ unsetenv(val);
+
+ break;
case ':':
fprintf(stderr, "env: Error: Missing operand for option: '-%c'\n", optopt);
usage();
diff --git a/test-cmd/env b/test-cmd/env
@@ -11,7 +11,7 @@ noargs_body() {
atf_test_case badarg
badarg_body() {
- atf_check -s not-exit:0 -e "inline:env: Error: Unrecognised option: '-f'\nenv [-i] [-u key] [key=value ...] [command [args]]\n" ../cmd/env -f
+ atf_check -s not-exit:0 -e "inline:env: Error: Unrecognised option: '-f'\nenv [-i] [-u key | --unset=key] [key=value ...] [command [args]]\n" ../cmd/env -f
}
atf_test_case iflag
@@ -30,7 +30,16 @@ uflag_body() {
atf_check -o "inline:FOO=BAR\n" ../cmd/env -i FOO=BAR BAR=FOO ../cmd/env -u BAR
- atf_check -s not-exit:0 -e "inline:env: Error: Missing operand for option: '-u'\nenv [-i] [-u key] [key=value ...] [command [args]]\n" ../cmd/env -u
+ atf_check -s not-exit:0 -e "inline:env: Error: Missing operand for option: '-u'\nenv [-i] [-u key | --unset=key] [key=value ...] [command [args]]\n" ../cmd/env -u
+}
+
+atf_test_case unsetflag
+unsetflag_body() {
+ [ "${LD_PRELOAD}" = "libsandbox.so" ] && atf_expect_fail "sandbox (gentoo) interferes with the environment"
+
+ atf_check -o "inline:FOO=BAR\n" ../cmd/env -i FOO=BAR BAR=FOO ../cmd/env --unset=BAR
+
+ atf_check -s not-exit:0 -e "inline:env: Error: Missing operand for option: '-u'\nenv [-i] [-u key | --unset=key] [key=value ...] [command [args]]\n" ../cmd/env -u
}
atf_test_case devfull
@@ -57,6 +66,7 @@ atf_init_test_cases() {
atf_add_test_case badarg
atf_add_test_case iflag
atf_add_test_case uflag
+ atf_add_test_case unsetflag
atf_add_test_case devfull
atf_add_test_case noutil
atf_add_test_case false