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 /shell | |
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>
Diffstat (limited to 'shell')
-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; |