diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-13 18:24:11 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-13 18:24:11 +0100 |
| commit | 9cabd17e555db8f1a48e1cd5db0a8a7a947bced9 (patch) | |
| tree | b2f3266da33e0bb21d7d70ead73a9ab0639e37ea | |
| parent | 31df5a3eee74862312bbf89449d223aeae13aaf7 (diff) | |
| download | busybox-w32-9cabd17e555db8f1a48e1cd5db0a8a7a947bced9.tar.gz busybox-w32-9cabd17e555db8f1a48e1cd5db0a8a7a947bced9.tar.bz2 busybox-w32-9cabd17e555db8f1a48e1cd5db0a8a7a947bced9.zip | |
hush: fix -c SCRIPT handling
function old new delta
hush_main 1763 1759 -4
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | shell/hush.c | 114 |
1 files changed, 63 insertions, 51 deletions
diff --git a/shell/hush.c b/shell/hush.c index b6d9d7abb..219158f18 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -10096,6 +10096,19 @@ int hush_main(int argc, char **argv) | |||
| 10096 | * PS4='+ ' | 10096 | * PS4='+ ' |
| 10097 | */ | 10097 | */ |
| 10098 | 10098 | ||
| 10099 | #if NUM_SCRIPTS > 0 | ||
| 10100 | if (argc < 0) { | ||
| 10101 | char *script = get_script_content(-argc - 1); | ||
| 10102 | G.global_argv = argv; | ||
| 10103 | G.global_argc = string_array_len(argv); | ||
| 10104 | G.root_pid = getpid(); | ||
| 10105 | G.root_ppid = getppid(); | ||
| 10106 | //install_special_sighandlers(); - needed? | ||
| 10107 | parse_and_run_string(script); | ||
| 10108 | goto final_return; | ||
| 10109 | } | ||
| 10110 | #endif | ||
| 10111 | |||
| 10099 | /* Initialize some more globals to non-zero values */ | 10112 | /* Initialize some more globals to non-zero values */ |
| 10100 | die_func = restore_ttypgrp_and__exit; | 10113 | die_func = restore_ttypgrp_and__exit; |
| 10101 | 10114 | ||
| @@ -10110,16 +10123,8 @@ int hush_main(int argc, char **argv) | |||
| 10110 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */ | 10123 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */ |
| 10111 | flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0; | 10124 | flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0; |
| 10112 | builtin_argc = 0; | 10125 | builtin_argc = 0; |
| 10113 | #if NUM_SCRIPTS > 0 | ||
| 10114 | if (argc < 0) { | ||
| 10115 | optarg = get_script_content(-argc - 1); | ||
| 10116 | optind = 0; | ||
| 10117 | argc = string_array_len(argv); | ||
| 10118 | goto run_script; | ||
| 10119 | } | ||
| 10120 | #endif | ||
| 10121 | while (1) { | 10126 | while (1) { |
| 10122 | int opt = getopt(argc, argv, "+c:exinsl" | 10127 | int opt = getopt(argc, argv, "+cexinsl" |
| 10123 | #if !BB_MMU | 10128 | #if !BB_MMU |
| 10124 | "<:$:R:V:" | 10129 | "<:$:R:V:" |
| 10125 | # if ENABLE_HUSH_FUNCTIONS | 10130 | # if ENABLE_HUSH_FUNCTIONS |
| @@ -10131,50 +10136,11 @@ int hush_main(int argc, char **argv) | |||
| 10131 | break; | 10136 | break; |
| 10132 | switch (opt) { | 10137 | switch (opt) { |
| 10133 | case 'c': | 10138 | case 'c': |
| 10134 | /* Possibilities: | 10139 | /* Note: -c is not a param with option! |
| 10135 | * sh ... -c 'script' | 10140 | * "hush -c -l SCRIPT" is valid. "hush -cSCRIPT" is not. |
| 10136 | * sh ... -c 'script' ARG0 [ARG1...] | ||
| 10137 | * On NOMMU, if builtin_argc != 0, | ||
| 10138 | * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...] | ||
| 10139 | * "" needs to be replaced with NULL | ||
| 10140 | * and BARGV vector fed to builtin function. | ||
| 10141 | * Note: the form without ARG0 never happens: | ||
| 10142 | * sh ... -c 'builtin' BARGV... "" | ||
| 10143 | */ | 10141 | */ |
| 10144 | #if NUM_SCRIPTS > 0 | ||
| 10145 | run_script: | ||
| 10146 | #endif | ||
| 10147 | if (!G.root_pid) { | ||
| 10148 | G.root_pid = getpid(); | ||
| 10149 | G.root_ppid = getppid(); | ||
| 10150 | } | ||
| 10151 | G.global_argv = argv + optind; | ||
| 10152 | G.global_argc = argc - optind; | ||
| 10153 | if (builtin_argc) { | ||
| 10154 | /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ | ||
| 10155 | const struct built_in_command *x; | ||
| 10156 | |||
| 10157 | install_special_sighandlers(); | ||
| 10158 | x = find_builtin(optarg); | ||
| 10159 | if (x) { /* paranoia */ | ||
| 10160 | G.global_argc -= builtin_argc; /* skip [BARGV...] "" */ | ||
| 10161 | G.global_argv += builtin_argc; | ||
| 10162 | G.global_argv[-1] = NULL; /* replace "" */ | ||
| 10163 | fflush_all(); | ||
| 10164 | G.last_exitcode = x->b_function(argv + optind - 1); | ||
| 10165 | } | ||
| 10166 | goto final_return; | ||
| 10167 | } | ||
| 10168 | G.opt_c = 1; | 10142 | G.opt_c = 1; |
| 10169 | if (!G.global_argv[0]) { | 10143 | break; |
| 10170 | /* -c 'script' (no params): prevent empty $0 */ | ||
| 10171 | G.global_argv--; /* points to argv[i] of 'script' */ | ||
| 10172 | G.global_argv[0] = argv[0]; | ||
| 10173 | G.global_argc++; | ||
| 10174 | } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ | ||
| 10175 | install_special_sighandlers(); | ||
| 10176 | parse_and_run_string(optarg); | ||
| 10177 | goto final_return; | ||
| 10178 | case 'i': | 10144 | case 'i': |
| 10179 | /* Well, we cannot just declare interactiveness, | 10145 | /* Well, we cannot just declare interactiveness, |
| 10180 | * we have to have some stuff (ctty, etc) */ | 10146 | * we have to have some stuff (ctty, etc) */ |
| @@ -10290,6 +10256,52 @@ int hush_main(int argc, char **argv) | |||
| 10290 | */ | 10256 | */ |
| 10291 | } | 10257 | } |
| 10292 | 10258 | ||
| 10259 | /* -c takes effect *after* -l */ | ||
| 10260 | if (G.opt_c) { | ||
| 10261 | /* Possibilities: | ||
| 10262 | * sh ... -c 'script' | ||
| 10263 | * sh ... -c 'script' ARG0 [ARG1...] | ||
| 10264 | * On NOMMU, if builtin_argc != 0, | ||
| 10265 | * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...] | ||
| 10266 | * "" needs to be replaced with NULL | ||
| 10267 | * and BARGV vector fed to builtin function. | ||
| 10268 | * Note: the form without ARG0 never happens: | ||
| 10269 | * sh ... -c 'builtin' BARGV... "" | ||
| 10270 | */ | ||
| 10271 | char *script; | ||
| 10272 | |||
| 10273 | install_special_sighandlers(); | ||
| 10274 | |||
| 10275 | G.global_argc--; | ||
| 10276 | G.global_argv++; | ||
| 10277 | if (builtin_argc) { | ||
| 10278 | /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ | ||
| 10279 | const struct built_in_command *x; | ||
| 10280 | x = find_builtin(G.global_argv[0]); | ||
| 10281 | if (x) { /* paranoia */ | ||
| 10282 | argv = G.global_argv; | ||
| 10283 | G.global_argc -= builtin_argc + 1; /* skip [BARGV...] "" */ | ||
| 10284 | G.global_argv += builtin_argc + 1; | ||
| 10285 | G.global_argv[-1] = NULL; /* replace "" */ | ||
| 10286 | G.last_exitcode = x->b_function(argv); | ||
| 10287 | } | ||
| 10288 | goto final_return; | ||
| 10289 | } | ||
| 10290 | |||
| 10291 | script = G.global_argv[0]; | ||
| 10292 | if (!script) | ||
| 10293 | bb_error_msg_and_die(bb_msg_requires_arg, "-c"); | ||
| 10294 | if (!G.global_argv[1]) { | ||
| 10295 | /* -c 'script' (no params): prevent empty $0 */ | ||
| 10296 | G.global_argv[0] = argv[0]; | ||
| 10297 | } else { /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ | ||
| 10298 | G.global_argc--; | ||
| 10299 | G.global_argv++; | ||
| 10300 | } | ||
| 10301 | parse_and_run_string(script); | ||
| 10302 | goto final_return; | ||
| 10303 | } | ||
| 10304 | |||
| 10293 | /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ | 10305 | /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ |
| 10294 | if (!G.opt_s && G.global_argv[1]) { | 10306 | if (!G.opt_s && G.global_argv[1]) { |
| 10295 | HFILE *input; | 10307 | HFILE *input; |
