diff options
author | Ron Yorston <rmy@pobox.com> | 2023-04-09 11:24:09 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-04-09 11:24:09 +0100 |
commit | d9f2ea8628452f787e02dd0e496af612a2e94578 (patch) | |
tree | c12be657e31c2e832b41fbff9a77aa0f886d47f0 /shell | |
parent | fa04f2dc766c76f2caa44a4b8429185dde6a66b0 (diff) | |
parent | a26711a2d1464167be4ebc990fe21a3809a2da34 (diff) | |
download | busybox-w32-d9f2ea8628452f787e02dd0e496af612a2e94578.tar.gz busybox-w32-d9f2ea8628452f787e02dd0e496af612a2e94578.tar.bz2 busybox-w32-d9f2ea8628452f787e02dd0e496af612a2e94578.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 69 | ||||
-rw-r--r-- | shell/ash_test/ash-signals/usage.right | 12 | ||||
-rwxr-xr-x | shell/ash_test/ash-signals/usage.tests | 12 | ||||
-rw-r--r-- | shell/hush.c | 40 |
4 files changed, 89 insertions, 44 deletions
diff --git a/shell/ash.c b/shell/ash.c index 51bf95377..0443f1a02 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2049,16 +2049,18 @@ _STPUTC(int c, char *p) | |||
2049 | /* | 2049 | /* |
2050 | * prefix -- see if pfx is a prefix of string. | 2050 | * prefix -- see if pfx is a prefix of string. |
2051 | */ | 2051 | */ |
2052 | static char * | 2052 | static ALWAYS_INLINE char * |
2053 | prefix(const char *string, const char *pfx) | 2053 | prefix(const char *string, const char *pfx) |
2054 | { | 2054 | { |
2055 | return is_prefixed_with(string, pfx); | ||
2056 | #if 0 /* dash implementation: */ | ||
2055 | while (*pfx) { | 2057 | while (*pfx) { |
2056 | if (*pfx++ != *string++) | 2058 | if (*pfx++ != *string++) |
2057 | return NULL; | 2059 | return NULL; |
2058 | } | 2060 | } |
2059 | return (char *) string; | 2061 | return (char *) string; |
2062 | #endif | ||
2060 | } | 2063 | } |
2061 | |||
2062 | /* | 2064 | /* |
2063 | * Check for a valid number. This should be elsewhere. | 2065 | * Check for a valid number. This should be elsewhere. |
2064 | */ | 2066 | */ |
@@ -2296,7 +2298,7 @@ struct localvar { | |||
2296 | #define VNOFUNC 0x40 /* don't call the callback function */ | 2298 | #define VNOFUNC 0x40 /* don't call the callback function */ |
2297 | #define VNOSET 0x80 /* do not set variable - just readonly test */ | 2299 | #define VNOSET 0x80 /* do not set variable - just readonly test */ |
2298 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ | 2300 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ |
2299 | #if ENABLE_ASH_RANDOM_SUPPORT | 2301 | #if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS |
2300 | # define VDYNAMIC 0x200 /* dynamic variable */ | 2302 | # define VDYNAMIC 0x200 /* dynamic variable */ |
2301 | #else | 2303 | #else |
2302 | # define VDYNAMIC 0 | 2304 | # define VDYNAMIC 0 |
@@ -2319,10 +2321,7 @@ change_lc_ctype(const char *value) | |||
2319 | } | 2321 | } |
2320 | #endif | 2322 | #endif |
2321 | #if ENABLE_ASH_MAIL | 2323 | #if ENABLE_ASH_MAIL |
2322 | static void chkmail(void); | ||
2323 | static void changemail(const char *var_value) FAST_FUNC; | 2324 | static void changemail(const char *var_value) FAST_FUNC; |
2324 | #else | ||
2325 | # define chkmail() ((void)0) | ||
2326 | #endif | 2325 | #endif |
2327 | static void changepath(const char *) FAST_FUNC; | 2326 | static void changepath(const char *) FAST_FUNC; |
2328 | #if ENABLE_ASH_RANDOM_SUPPORT | 2327 | #if ENABLE_ASH_RANDOM_SUPPORT |
@@ -3407,7 +3406,7 @@ cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3407 | if (!*dest) | 3406 | if (!*dest) |
3408 | dest = "."; | 3407 | dest = "."; |
3409 | path = bltinlookup("CDPATH"); | 3408 | path = bltinlookup("CDPATH"); |
3410 | while (p = path, (len = padvance(&path, dest)) >= 0) { | 3409 | while (p = path, (len = padvance_magic(&path, dest, 0)) >= 0) { |
3411 | c = *p; | 3410 | c = *p; |
3412 | p = stalloc(len); | 3411 | p = stalloc(len); |
3413 | 3412 | ||
@@ -4454,9 +4453,6 @@ getjob(const char *name, int getctl) | |||
4454 | unsigned num; | 4453 | unsigned num; |
4455 | int c; | 4454 | int c; |
4456 | const char *p; | 4455 | const char *p; |
4457 | #if ENABLE_PLATFORM_POSIX || JOBS_WIN32 | ||
4458 | char *(*match)(const char *, const char *); | ||
4459 | #endif | ||
4460 | 4456 | ||
4461 | jp = curjob; | 4457 | jp = curjob; |
4462 | p = name; | 4458 | p = name; |
@@ -4498,15 +4494,12 @@ getjob(const char *name, int getctl) | |||
4498 | } | 4494 | } |
4499 | 4495 | ||
4500 | #if ENABLE_PLATFORM_POSIX || JOBS_WIN32 | 4496 | #if ENABLE_PLATFORM_POSIX || JOBS_WIN32 |
4501 | match = prefix; | ||
4502 | if (*p == '?') { | ||
4503 | match = strstr; | ||
4504 | p++; | ||
4505 | } | ||
4506 | |||
4507 | found = NULL; | 4497 | found = NULL; |
4508 | while (jp) { | 4498 | while (jp) { |
4509 | if (match(jp->ps[0].ps_cmd, p)) { | 4499 | if (*p == '?' |
4500 | ? strstr(jp->ps[0].ps_cmd, p + 1) | ||
4501 | : prefix(jp->ps[0].ps_cmd, p) | ||
4502 | ) { | ||
4510 | if (found) | 4503 | if (found) |
4511 | goto err; | 4504 | goto err; |
4512 | found = jp; | 4505 | found = jp; |
@@ -5802,8 +5795,7 @@ forkchild(struct job *jp, union node *n, int mode) | |||
5802 | 5795 | ||
5803 | closescript(); | 5796 | closescript(); |
5804 | 5797 | ||
5805 | if (mode == FORK_NOJOB /* is it `xxx` ? */ | 5798 | if (n && n->type == NCMD /* is it single cmd? */ |
5806 | && n && n->type == NCMD /* is it single cmd? */ | ||
5807 | /* && n->ncmd.args->type == NARG - always true? */ | 5799 | /* && n->ncmd.args->type == NARG - always true? */ |
5808 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 | 5800 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 |
5809 | && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */ | 5801 | && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */ |
@@ -5897,10 +5889,12 @@ forkchild(struct job *jp, union node *n, int mode) | |||
5897 | ) { | 5889 | ) { |
5898 | TRACE(("Job hack\n")); | 5890 | TRACE(("Job hack\n")); |
5899 | /* "jobs": we do not want to clear job list for it, | 5891 | /* "jobs": we do not want to clear job list for it, |
5900 | * instead we remove only _its_ own_ job from job list. | 5892 | * instead we remove only _its_ own_ job from job list |
5893 | * (if it has one). | ||
5901 | * This makes "jobs .... | cat" more useful. | 5894 | * This makes "jobs .... | cat" more useful. |
5902 | */ | 5895 | */ |
5903 | freejob(curjob); | 5896 | if (jp) |
5897 | freejob(curjob); | ||
5904 | return; | 5898 | return; |
5905 | } | 5899 | } |
5906 | #endif | 5900 | #endif |
@@ -7293,7 +7287,7 @@ evalbackcmd(union node *n, struct backcmd *result | |||
7293 | 7287 | ||
7294 | if (pipe(pip) < 0) | 7288 | if (pipe(pip) < 0) |
7295 | ash_msg_and_raise_perror("can't create pipe"); | 7289 | ash_msg_and_raise_perror("can't create pipe"); |
7296 | /* process substitution uses NULL job/node, like openhere() */ | 7290 | /* process substitution uses NULL job, like openhere() */ |
7297 | jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL; | 7291 | jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL; |
7298 | #if ENABLE_PLATFORM_MINGW32 | 7292 | #if ENABLE_PLATFORM_MINGW32 |
7299 | memset(&fs, 0, sizeof(fs)); | 7293 | memset(&fs, 0, sizeof(fs)); |
@@ -7302,9 +7296,9 @@ evalbackcmd(union node *n, struct backcmd *result | |||
7302 | fs.fd[0] = pip[0]; | 7296 | fs.fd[0] = pip[0]; |
7303 | fs.fd[1] = pip[1]; | 7297 | fs.fd[1] = pip[1]; |
7304 | fs.fd[2] = ctl; | 7298 | fs.fd[2] = ctl; |
7305 | spawn_forkshell(&fs, jp, (ctl == CTLBACKQ) ? n : NULL, FORK_NOJOB); | 7299 | spawn_forkshell(&fs, jp, n, FORK_NOJOB); |
7306 | #else | 7300 | #else |
7307 | if (forkshell(jp, (ctl == CTLBACKQ) ? n : NULL, FORK_NOJOB) == 0) { | 7301 | if (forkshell(jp, n, FORK_NOJOB) == 0) { |
7308 | /* child */ | 7302 | /* child */ |
7309 | FORCE_INT_ON; | 7303 | FORCE_INT_ON; |
7310 | close(pip[ip]); | 7304 | close(pip[ip]); |
@@ -9507,8 +9501,6 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
9507 | const struct alias *ap; | 9501 | const struct alias *ap; |
9508 | #endif | 9502 | #endif |
9509 | 9503 | ||
9510 | path = path ? path : pathval(); | ||
9511 | |||
9512 | if (describe_command_verbose) { | 9504 | if (describe_command_verbose) { |
9513 | out1str(command); | 9505 | out1str(command); |
9514 | } | 9506 | } |
@@ -9533,6 +9525,7 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
9533 | } | 9525 | } |
9534 | #endif | 9526 | #endif |
9535 | /* Brute force */ | 9527 | /* Brute force */ |
9528 | path = path ? path : pathval(); | ||
9536 | find_command(command, &entry, DO_ABS, path); | 9529 | find_command(command, &entry, DO_ABS, path); |
9537 | 9530 | ||
9538 | switch (entry.cmdtype) { | 9531 | switch (entry.cmdtype) { |
@@ -12311,15 +12304,14 @@ setinputstring(char *string) | |||
12311 | #if ENABLE_ASH_MAIL | 12304 | #if ENABLE_ASH_MAIL |
12312 | 12305 | ||
12313 | /* Hash of mtimes of mailboxes */ | 12306 | /* Hash of mtimes of mailboxes */ |
12307 | /* Cleared to 0 if MAIL or MAILPATH is changed */ | ||
12314 | static unsigned mailtime_hash; | 12308 | static unsigned mailtime_hash; |
12315 | /* Set if MAIL or MAILPATH is changed. */ | ||
12316 | static smallint mail_var_path_changed; | ||
12317 | 12309 | ||
12318 | /* | 12310 | /* |
12319 | * Print appropriate message(s) if mail has arrived. | 12311 | * Print appropriate message(s) if mail has arrived. |
12320 | * If mail_var_path_changed is set, | 12312 | * If mailtime_hash is zero, |
12321 | * then the value of MAIL has mail_var_path_changed, | 12313 | * then the value of MAIL has changed, |
12322 | * so we just update the values. | 12314 | * so we just update the hash value. |
12323 | */ | 12315 | */ |
12324 | static void | 12316 | static void |
12325 | chkmail(void) | 12317 | chkmail(void) |
@@ -12338,10 +12330,9 @@ chkmail(void) | |||
12338 | int len; | 12330 | int len; |
12339 | 12331 | ||
12340 | len = padvance_magic(&mpath, nullstr, 2); | 12332 | len = padvance_magic(&mpath, nullstr, 2); |
12341 | if (!len) | 12333 | if (len < 0) |
12342 | break; | 12334 | break; |
12343 | p = stackblock(); | 12335 | p = stackblock(); |
12344 | break; | ||
12345 | if (*p == '\0') | 12336 | if (*p == '\0') |
12346 | continue; | 12337 | continue; |
12347 | for (q = p; *q; q++) | 12338 | for (q = p; *q; q++) |
@@ -12357,21 +12348,24 @@ chkmail(void) | |||
12357 | /* Very simplistic "hash": just a sum of all mtimes */ | 12348 | /* Very simplistic "hash": just a sum of all mtimes */ |
12358 | new_hash += (unsigned)statb.st_mtime; | 12349 | new_hash += (unsigned)statb.st_mtime; |
12359 | } | 12350 | } |
12360 | if (!mail_var_path_changed && mailtime_hash != new_hash) { | 12351 | if (mailtime_hash != new_hash) { |
12361 | if (mailtime_hash != 0) | 12352 | if (mailtime_hash != 0) |
12362 | out2str("you have mail\n"); | 12353 | out2str("you have mail\n"); |
12363 | mailtime_hash = new_hash; | 12354 | mailtime_hash = new_hash; |
12364 | } | 12355 | } |
12365 | mail_var_path_changed = 0; | ||
12366 | popstackmark(&smark); | 12356 | popstackmark(&smark); |
12367 | } | 12357 | } |
12368 | 12358 | ||
12369 | static void FAST_FUNC | 12359 | static void FAST_FUNC |
12370 | changemail(const char *val UNUSED_PARAM) | 12360 | changemail(const char *val UNUSED_PARAM) |
12371 | { | 12361 | { |
12372 | mail_var_path_changed = 1; | 12362 | mailtime_hash = 0; |
12373 | } | 12363 | } |
12374 | 12364 | ||
12365 | #else | ||
12366 | |||
12367 | # define chkmail() ((void)0) | ||
12368 | |||
12375 | #endif /* ASH_MAIL */ | 12369 | #endif /* ASH_MAIL */ |
12376 | 12370 | ||
12377 | 12371 | ||
@@ -14707,7 +14701,7 @@ static char * | |||
14707 | find_dot_file(char *basename) | 14701 | find_dot_file(char *basename) |
14708 | { | 14702 | { |
14709 | char *fullname; | 14703 | char *fullname; |
14710 | const char *path = pathval(); | 14704 | const char *path; |
14711 | struct stat statb; | 14705 | struct stat statb; |
14712 | int len; | 14706 | int len; |
14713 | 14707 | ||
@@ -14715,6 +14709,7 @@ find_dot_file(char *basename) | |||
14715 | if (strchr(basename, '/') IF_PLATFORM_MINGW32(|| strchr(basename, '\\'))) | 14709 | if (strchr(basename, '/') IF_PLATFORM_MINGW32(|| strchr(basename, '\\'))) |
14716 | return basename; | 14710 | return basename; |
14717 | 14711 | ||
14712 | path = pathval(); | ||
14718 | while ((len = padvance(&path, basename)) >= 0) { | 14713 | while ((len = padvance(&path, basename)) >= 0) { |
14719 | fullname = stackblock(); | 14714 | fullname = stackblock(); |
14720 | if ((!pathopt || *pathopt == 'f') | 14715 | if ((!pathopt || *pathopt == 'f') |
diff --git a/shell/ash_test/ash-signals/usage.right b/shell/ash_test/ash-signals/usage.right index c0dbd6c3c..df1ed2dd7 100644 --- a/shell/ash_test/ash-signals/usage.right +++ b/shell/ash_test/ash-signals/usage.right | |||
@@ -6,6 +6,18 @@ trap -- 'a' INT | |||
6 | trap -- 'a' USR1 | 6 | trap -- 'a' USR1 |
7 | trap -- 'a' USR2 | 7 | trap -- 'a' USR2 |
8 | ___ | 8 | ___ |
9 | trap -- 'a' EXIT trap -- 'a' INT trap -- 'a' USR1 trap -- 'a' USR2 | ||
10 | ___ | ||
11 | trap -- 'a' EXIT | ||
12 | trap -- 'a' INT | ||
13 | trap -- 'a' USR1 | ||
14 | trap -- 'a' USR2 | ||
15 | ___ | ||
16 | trap -- 'a' EXIT | ||
17 | trap -- 'a' INT | ||
18 | trap -- 'a' USR1 | ||
19 | trap -- 'a' USR2 | ||
20 | ___ | ||
9 | ___ | 21 | ___ |
10 | trap -- 'a' USR1 | 22 | trap -- 'a' USR1 |
11 | trap -- 'a' USR2 | 23 | trap -- 'a' USR2 |
diff --git a/shell/ash_test/ash-signals/usage.tests b/shell/ash_test/ash-signals/usage.tests index d29c6e74a..34e24cceb 100755 --- a/shell/ash_test/ash-signals/usage.tests +++ b/shell/ash_test/ash-signals/usage.tests | |||
@@ -10,6 +10,18 @@ trap "a" EXIT INT USR1 USR2 | |||
10 | echo ___ | 10 | echo ___ |
11 | trap | 11 | trap |
12 | 12 | ||
13 | # show them by command substitution | ||
14 | echo ___ | ||
15 | echo $(trap) | ||
16 | |||
17 | # show them by pipe | ||
18 | echo ___ | ||
19 | trap | cat | ||
20 | |||
21 | # show them by process substitution | ||
22 | echo ___ | ||
23 | cat <(trap) | ||
24 | |||
13 | # clear one | 25 | # clear one |
14 | echo ___ | 26 | echo ___ |
15 | trap 0 INT | 27 | trap 0 INT |
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 |