[PATCH 2/2] env: add option -S to split string
Marc Kewitz
herderkewitz at googlemail.com
Mon Apr 7 10:12:25 UTC 2025
Hi,
I kind of needed this feature in busybox. Maybe it is already useful in this state
On April 7, 2025 12:08:04 PM GMT+02:00, Marc Kewitz <herderkewitz at googlemail.com> wrote:
>used in cases where no proper argument vector is passed to env
>an example are shebangs:
>"#!/usr/bin/env -S executable -o"
>this will pass 3 arguments to env: the env executable,
>"-S executable -o" as one string and filename.
>"-S executable -o" willobe split and "executable -o" will be separate
>arguments in the argument vector
>---
> coreutils/env.c | 39 ++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 38 insertions(+), 1 deletion(-)
>
>diff --git a/coreutils/env.c b/coreutils/env.c
>index 9ca1fad2d..22cc916be 100644
>--- a/coreutils/env.c
>+++ b/coreutils/env.c
>@@ -48,6 +48,7 @@
> //usage: "\n -, -i Start with empty environment"
> //usage: "\n -0 NUL terminated output"
> //usage: "\n -u NAME Remove variable from environment"
>+//usage: "\n -S ARGS split into separate arguments, only useful in shebang or similar"
>
> #include "libbb.h"
> #include <getopt.h>
>@@ -56,10 +57,11 @@ static struct option const long_options[] = {
> {"ignore-environment", no_argument, 0, 'i' },
> {"null", no_argument, 0, '0' },
> {"unset", required_argument, 0, 'u' },
>+ {"split", required_argument, 0, 'S' },
> {0, 0, 0, 0 }
> };
>
>-static char const short_options[] = "+iu:0";
>+static char const short_options[] = "+iS:u:0";
>
> static char const **unset_vars;
> static int num_unset_vars;
>@@ -70,6 +72,38 @@ static void add_unset_var (char const *var)
> unset_vars[num_unset_vars++] = var;
> }
>
>+// inspired by GNU core utilities env.c
>+static void split_string (char const *str, int *optind, int *argc, char ***argv)
>+{
>+ // remember the amount of extra arguments after the string to split
>+ int extra_argc = *argc - *optind;
>+ // 1 is reserved for the executable name of env
>+ int new_argc = extra_argc + 1;
>+ int new_ind = new_argc - extra_argc;
>+ char **new_argv = NULL;
>+ char *arg, *tokstate;
>+
>+ // keep it simple, assume arguments are split by spaces
>+ arg = strtok_r (str, " ", &tokstate);
>+ while (arg != NULL) {
>+ // increase size of new_argv
>+ new_argv = xrealloc(new_argv, ++new_argc * sizeof(char *));
>+ // copy the current argument to new_argv
>+ new_argv[new_ind++] = xstrdup(arg);
>+ arg = strtok_r (NULL, " ", &tokstate);
>+ }
>+ // keep executable name
>+ *new_argv = (*argv)[0];
>+
>+ // copy remaining arguments
>+ memcpy(new_argv + new_ind, *argv + *optind, (extra_argc + 1) * sizeof(char *));
>+
>+ // write back values to argc and argv
>+ *argc = new_argc;
>+ *argv = new_argv;
>+ *optind = 0;
>+}
>+
> int env_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
> int env_main(int argc, char **argv)
> {
>@@ -90,6 +124,9 @@ int env_main(int argc, char **argv)
> case '0':
> null_terminate_output = true;
> break;
>+ case 'S':
>+ split_string(optarg, &optind, &argc, &argv);
>+ break;
> default:
> exit(EXIT_FAILURE);
> }
>--
>2.30.2
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20250407/c3d98ee9/attachment-0001.htm>
More information about the busybox
mailing list