logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git
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:

Mcmd/env.17++++---
Mcmd/env.c23+++++++++++++++++++++--
Mtest-cmd/env14++++++++++++--
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