aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-12-13 18:24:11 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-12-13 18:24:11 +0100
commit9cabd17e555db8f1a48e1cd5db0a8a7a947bced9 (patch)
treeb2f3266da33e0bb21d7d70ead73a9ab0639e37ea /shell
parent31df5a3eee74862312bbf89449d223aeae13aaf7 (diff)
downloadbusybox-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.c114
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;