diff options
| author | Pádraig Brady <P@draigBrady.com> | 2023-03-02 11:56:18 -0300 |
|---|---|---|
| committer | Pádraig Brady <P@draigBrady.com> | 2024-03-22 13:12:52 +0000 |
| commit | 193449b17334649a2abcbca589544d858fca92a1 (patch) | |
| tree | 4a4bb18505b9b455f1683760ac893e77ee71f632 | |
| parent | doc: pr: give solution to expanding TABs in multicolumn output (diff) | |
| download | coreutils-193449b17334649a2abcbca589544d858fca92a1.tar.gz coreutils-193449b17334649a2abcbca589544d858fca92a1.zip | |
env: add -a,--argv0 to set the first argument passed to exec
Using the shell's exec -a feature can be awkward
so add support for setting overriding argv[0].
This gives env full control over the arguments it passes.
* src/env.c: Accept -a,--argv0 and set argv[0] appropriately.
* tests/env/env.sh: Add test cases.
* doc/coreutils.texi (env invocation): Describe -a,--argv0.
* NEWS: Mention the new feature.
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | doc/coreutils.texi | 7 | ||||
| -rw-r--r-- | src/env.c | 31 | ||||
| -rwxr-xr-x | tests/env/env.sh | 10 |
4 files changed, 46 insertions, 5 deletions
@@ -92,6 +92,9 @@ GNU coreutils NEWS -*- outline -*- and the command exits with failure status if existing files. The -n,--no-clobber option is best avoided due to platform differences. + env now accepts the -a,--argv0 option to override the zeroth argument + of the command being executed. + mv now accepts an --exchange option, which causes the source and destination to be exchanged. It should be combined with --no-target-directory (-T) if the destination is a directory. diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 37d729089..8a2104831 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -17950,6 +17950,13 @@ Options must precede operands. @optNull +@item -a @var{arg} +@itemx --argv0=@var{arg} +@opindex -a +@opindex --argv0 +Override the zeroth argument passed to the command being executed. +Without this option a default value of @var{command} is used. + @item -u @var{name} @itemx --unset=@var{name} @opindex -u @@ -73,7 +73,7 @@ static bool report_signal_handling; /* The isspace characters in the C locale. */ #define C_ISSPACE_CHARS " \t\n\v\f\r" -static char const shortopts[] = "+C:iS:u:v0" C_ISSPACE_CHARS; +static char const shortopts[] = "+a:C:iS:u:v0" C_ISSPACE_CHARS; /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ @@ -87,6 +87,7 @@ enum static struct option const longopts[] = { + {"argv0", required_argument, nullptr, 'a'}, {"ignore-environment", no_argument, nullptr, 'i'}, {"null", no_argument, nullptr, '0'}, {"unset", required_argument, nullptr, 'u'}, @@ -119,6 +120,9 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\ emit_mandatory_arg_note (); fputs (_("\ + -a, --argv0=ARG pass ARG as the zeroth argument of COMMAND\n\ +"), stdout); + fputs (_("\ -i, --ignore-environment start with an empty environment\n\ -0, --null end each output line with NUL, not newline\n\ -u, --unset=NAME remove variable from the environment\n\ @@ -759,6 +763,7 @@ main (int argc, char **argv) bool ignore_environment = false; bool opt_nul_terminate_output = false; char const *newdir = nullptr; + char *argv0 = nullptr; initialize_main (&argc, &argv); set_program_name (argv[0]); @@ -775,6 +780,9 @@ main (int argc, char **argv) { switch (optc) { + case 'a': + argv0 = optarg; + break; case 'i': ignore_environment = true; break; @@ -865,6 +873,12 @@ main (int argc, char **argv) usage (EXIT_CANCELED); } + if (argv0 && ! program_specified) + { + error (0, 0, _("must specify command with --argv0 (-a)")); + usage (EXIT_CANCELED); + } + if (! program_specified) { /* Print the environment and exit. */ @@ -890,19 +904,26 @@ main (int argc, char **argv) quoteaf (newdir)); } + char *program = argv[optind]; + if (argv0) + { + devmsg ("argv0: %s\n", quoteaf (argv0)); + argv[optind] = argv0; + } + if (dev_debug) { - devmsg ("executing: %s\n", argv[optind]); + devmsg ("executing: %s\n", program); for (int i=optind; i<argc; ++i) devmsg (" arg[%d]= %s\n", i-optind, quote (argv[i])); } - execvp (argv[optind], &argv[optind]); + execvp (program, &argv[optind]); int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE; - error (0, errno, "%s", quote (argv[optind])); + error (0, errno, "%s", quote (program)); - if (exit_status == EXIT_ENOENT && strpbrk (argv[optind], C_ISSPACE_CHARS)) + if (exit_status == EXIT_ENOENT && strpbrk (program, C_ISSPACE_CHARS)) error (0, 0, _("use -[v]S to pass options in shebang lines")); main_exit (exit_status); diff --git a/tests/env/env.sh b/tests/env/env.sh index 1a4b1a53f..d8f520299 100755 --- a/tests/env/env.sh +++ b/tests/env/env.sh @@ -163,4 +163,14 @@ exp=$(cd empty && env pwd) || framework_failure_ got=$(env --chdir=empty pwd) || fail=1 test "$exp" = "$got" || fail=1 +# Verify argv0 overriding +for arg in 'argv0' ''; do +env -v -a short --argv0=$arg true 2>err || fail=1 +cat <<EOF >err_exp || framework_failure_ +argv0: '$arg' +executing: true + arg[0]= '$arg' +EOF +done + Exit $fail |
