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 <[email protected]> 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 >
_______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox
