From: Pádraig Brady Date: Thu, 2 Mar 2023 14:56:18 +0000 (-0300) Subject: env: add -a,--argv0 to set the first argument passed to exec X-Git-Tag: v9.5~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=193449b17334649a2abcbca589544d858fca92a1;p=thirdparty%2Fcoreutils.git 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. --- diff --git a/NEWS b/NEWS index cb47621880..a6ec7c6ef9 100644 --- a/NEWS +++ b/NEWS @@ -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 37d7290893..8a21048317 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 diff --git a/src/env.c b/src/env.c index ed6628f8f1..af876fa08b 100644 --- a/src/env.c +++ b/src/env.c @@ -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'}, @@ -118,6 +119,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\ @@ -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; ierr || fail=1 +cat <err_exp || framework_failure_ +argv0: '$arg' +executing: true + arg[0]= '$arg' +EOF +done + Exit $fail