Sets the zeroth argument (argv[0]) of the invoked command. It's difficult to use bash's exec -a simultaneously with env, so add support for setting the program name with env.
Discussed in: https://lists.gnu.org/r/coreutils/2023-03/msg00002.html * src/env.c (newname, program): New variables, options and logic. --- src/env.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/env.c b/src/env.c index 2f38d75..3dc5c2a 100644 --- a/src/env.c +++ b/src/env.c @@ -76,7 +76,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[] = "+C:n: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. */ @@ -94,6 +94,7 @@ static struct option const longopts[] = {"null", no_argument, NULL, '0'}, {"unset", required_argument, NULL, 'u'}, {"chdir", required_argument, NULL, 'C'}, + {"name", required_argument, NULL, 'n'}, {"default-signal", optional_argument, NULL, DEFAULT_SIGNAL_OPTION}, {"ignore-signal", optional_argument, NULL, IGNORE_SIGNAL_OPTION}, {"block-signal", optional_argument, NULL, BLOCK_SIGNAL_OPTION}, @@ -128,6 +129,9 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\ "), stdout); fputs (_("\ -C, --chdir=DIR change working directory to DIR\n\ +"), stdout); + fputs (_("\ + -n, --name=NAME pass NAME as the zeroth argument of COMMAND\n\ "), stdout); fputs (_("\ -S, --split-string=S process and split S into separate arguments;\n\ @@ -754,6 +758,7 @@ main (int argc, char **argv) bool ignore_environment = false; bool opt_nul_terminate_output = false; char const *newdir = NULL; + char *newname = NULL; initialize_main (&argc, &argv); set_program_name (argv[0]); @@ -798,6 +803,9 @@ main (int argc, char **argv) case 'C': newdir = optarg; break; + case 'n': + newname = optarg; + break; case 'S': parse_split_string (optarg, &optind, &argc, &argv); break; @@ -860,6 +868,12 @@ main (int argc, char **argv) usage (EXIT_CANCELED); } + if (newname && ! program_specified) + { + error (0, 0, _("must specify command with --name (-n)")); + usage (EXIT_CANCELED); + } + if (! program_specified) { /* Print the environment and exit. */ @@ -885,6 +899,13 @@ main (int argc, char **argv) quoteaf (newdir)); } + char *program = argv[optind]; + if (newname) + { + devmsg ("name: %s\n", quoteaf (newname)); + argv[optind] = newname; + } + if (dev_debug) { devmsg ("executing: %s\n", argv[optind]); @@ -892,7 +913,7 @@ main (int argc, char **argv) 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])); -- 2.39.2