diff options
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/shell/hush.c b/shell/hush.c index e6be70078..a938cc790 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -7468,6 +7468,9 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
7468 | if (!cur->flg_export || cur->flg_read_only) | 7468 | if (!cur->flg_export || cur->flg_read_only) |
7469 | cnt += 2; | 7469 | cnt += 2; |
7470 | } | 7470 | } |
7471 | # if ENABLE_HUSH_LINENO_VAR | ||
7472 | cnt += 2; | ||
7473 | # endif | ||
7471 | # if ENABLE_HUSH_FUNCTIONS | 7474 | # if ENABLE_HUSH_FUNCTIONS |
7472 | for (funcp = G.top_func; funcp; funcp = funcp->next) | 7475 | for (funcp = G.top_func; funcp; funcp = funcp->next) |
7473 | cnt += 3; | 7476 | cnt += 3; |
@@ -7489,6 +7492,10 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
7489 | *pp++ = cur->varstr; | 7492 | *pp++ = cur->varstr; |
7490 | } | 7493 | } |
7491 | } | 7494 | } |
7495 | # if ENABLE_HUSH_LINENO_VAR | ||
7496 | *pp++ = (char *) "-L"; | ||
7497 | *pp++ = utoa(G.execute_lineno); | ||
7498 | # endif | ||
7492 | # if ENABLE_HUSH_FUNCTIONS | 7499 | # if ENABLE_HUSH_FUNCTIONS |
7493 | for (funcp = G.top_func; funcp; funcp = funcp->next) { | 7500 | for (funcp = G.top_func; funcp; funcp = funcp->next) { |
7494 | *pp++ = (char *) "-F"; | 7501 | *pp++ = (char *) "-F"; |
@@ -10260,6 +10267,20 @@ int hush_main(int argc, char **argv) | |||
10260 | INIT_G(); | 10267 | INIT_G(); |
10261 | if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */ | 10268 | if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */ |
10262 | G.last_exitcode = EXIT_SUCCESS; | 10269 | G.last_exitcode = EXIT_SUCCESS; |
10270 | #if !BB_MMU | ||
10271 | /* "Big heredoc" support via "sh -< STRING" invocation. | ||
10272 | * Check it first (do not bother to run the usual init code, | ||
10273 | * it is not needed for this case). | ||
10274 | */ | ||
10275 | if (argv[1] | ||
10276 | && argv[1][0] == '-' && argv[1][1] == '<' /*&& !argv[1][2]*/ | ||
10277 | /*&& argv[2] && !argv[3] - we don't check some conditions */ | ||
10278 | ) { | ||
10279 | full_write1_str(argv[2]); | ||
10280 | _exit(0); | ||
10281 | } | ||
10282 | G.argv0_for_re_execing = argv[0]; | ||
10283 | #endif | ||
10263 | #if ENABLE_HUSH_TRAP | 10284 | #if ENABLE_HUSH_TRAP |
10264 | # if ENABLE_HUSH_FUNCTIONS | 10285 | # if ENABLE_HUSH_FUNCTIONS |
10265 | G.return_exitcode = -1; | 10286 | G.return_exitcode = -1; |
@@ -10270,9 +10291,6 @@ int hush_main(int argc, char **argv) | |||
10270 | #if ENABLE_HUSH_FAST | 10291 | #if ENABLE_HUSH_FAST |
10271 | G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ | 10292 | G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ |
10272 | #endif | 10293 | #endif |
10273 | #if !BB_MMU | ||
10274 | G.argv0_for_re_execing = argv[0]; | ||
10275 | #endif | ||
10276 | 10294 | ||
10277 | cached_getpid = getpid(); /* for tcsetpgrp() during init */ | 10295 | cached_getpid = getpid(); /* for tcsetpgrp() during init */ |
10278 | G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ | 10296 | G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ |
@@ -10388,7 +10406,10 @@ int hush_main(int argc, char **argv) | |||
10388 | int opt = getopt(argc, argv, "+" /* stop at 1st non-option */ | 10406 | int opt = getopt(argc, argv, "+" /* stop at 1st non-option */ |
10389 | "cexinsl" | 10407 | "cexinsl" |
10390 | #if !BB_MMU | 10408 | #if !BB_MMU |
10391 | "<:$:R:V:" | 10409 | "$:R:V:" |
10410 | # if ENABLE_HUSH_LINENO_VAR | ||
10411 | "L:" | ||
10412 | # endif | ||
10392 | # if ENABLE_HUSH_FUNCTIONS | 10413 | # if ENABLE_HUSH_FUNCTIONS |
10393 | "F:" | 10414 | "F:" |
10394 | # endif | 10415 | # endif |
@@ -10438,9 +10459,6 @@ int hush_main(int argc, char **argv) | |||
10438 | flags |= OPT_login; | 10459 | flags |= OPT_login; |
10439 | break; | 10460 | break; |
10440 | #if !BB_MMU | 10461 | #if !BB_MMU |
10441 | case '<': /* "big heredoc" support */ | ||
10442 | full_write1_str(optarg); | ||
10443 | _exit(0); | ||
10444 | case '$': { | 10462 | case '$': { |
10445 | unsigned long long empty_trap_mask; | 10463 | unsigned long long empty_trap_mask; |
10446 | 10464 | ||
@@ -10490,6 +10508,11 @@ int hush_main(int argc, char **argv) | |||
10490 | case 'V': | 10508 | case 'V': |
10491 | set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0); | 10509 | set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0); |
10492 | break; | 10510 | break; |
10511 | # if ENABLE_HUSH_LINENO_VAR | ||
10512 | case 'L': | ||
10513 | G.parse_lineno = xatou(optarg); | ||
10514 | break; | ||
10515 | # endif | ||
10493 | # if ENABLE_HUSH_FUNCTIONS | 10516 | # if ENABLE_HUSH_FUNCTIONS |
10494 | case 'F': { | 10517 | case 'F': { |
10495 | struct function *funcp = new_function(optarg); | 10518 | struct function *funcp = new_function(optarg); |
@@ -11276,6 +11299,9 @@ static int FAST_FUNC builtin_local(char **argv) | |||
11276 | bb_error_msg("%s: not in a function", argv[0]); | 11299 | bb_error_msg("%s: not in a function", argv[0]); |
11277 | return EXIT_FAILURE; /* bash compat */ | 11300 | return EXIT_FAILURE; /* bash compat */ |
11278 | } | 11301 | } |
11302 | //TODO? ash and bash support "local -" special form, | ||
11303 | //which saves/restores $- around function call (including async returns, such as ^C) | ||
11304 | //(IOW: it makes "set +/-..." effects local) | ||
11279 | argv++; | 11305 | argv++; |
11280 | /* Since all builtins run in a nested variable level, | 11306 | /* Since all builtins run in a nested variable level, |
11281 | * need to use level - 1 here. Or else the variable will be removed at once | 11307 | * need to use level - 1 here. Or else the variable will be removed at once |