diff options
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 89 |
1 files changed, 43 insertions, 46 deletions
diff --git a/shell/ash.c b/shell/ash.c index f3eb98d85..4d4137800 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -35,7 +35,7 @@ | |||
35 | //config: depends on !NOMMU | 35 | //config: depends on !NOMMU |
36 | //config: | 36 | //config: |
37 | //config:config ASH | 37 | //config:config ASH |
38 | //config: bool "ash (78 kb)" | 38 | //config: bool "ash (80 kb)" |
39 | //config: default y | 39 | //config: default y |
40 | //config: depends on !NOMMU | 40 | //config: depends on !NOMMU |
41 | //config: select SHELL_ASH | 41 | //config: select SHELL_ASH |
@@ -149,11 +149,23 @@ | |||
149 | //config: default y | 149 | //config: default y |
150 | //config: depends on SHELL_ASH | 150 | //config: depends on SHELL_ASH |
151 | //config: | 151 | //config: |
152 | //config:config ASH_SLEEP | 152 | // |
153 | //config: bool "sleep builtin" | 153 | ////config:config ASH_SLEEP |
154 | //config: default y | 154 | ////config: bool "sleep builtin" |
155 | //config: depends on SHELL_ASH | 155 | ////config: default y |
156 | //config: | 156 | ////config: depends on SHELL_ASH |
157 | ////config: | ||
158 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
159 | //Disabled for now. Has a few annoying problems: | ||
160 | // * sleepcmd() -> sleep_main(), the parsing of bad arguments exits the shell. | ||
161 | // * sleep_for_duration() in sleep_main() has to be interruptible for | ||
162 | // ^C traps to work, which may be a problem for other users | ||
163 | // of sleep_for_duration(). | ||
164 | // * BUT, if sleep_for_duration() is interruptible, then SIGCHLD interrupts it | ||
165 | // as well (try "/bin/sleep 1 & sleep 10"). | ||
166 | // * sleep_main() must not allocate anything as ^C in ash longjmp's. | ||
167 | // (currently, allocations are only on error paths, in message printing). | ||
168 | // | ||
157 | //config:config ASH_HELP | 169 | //config:config ASH_HELP |
158 | //config: bool "help builtin" | 170 | //config: bool "help builtin" |
159 | //config: default y | 171 | //config: default y |
@@ -599,7 +611,12 @@ struct globals_misc { | |||
599 | 611 | ||
600 | struct jmploc *exception_handler; | 612 | struct jmploc *exception_handler; |
601 | 613 | ||
602 | volatile int suppress_int; /* counter */ | 614 | /*volatile*/ int suppress_int; /* counter */ |
615 | /* ^^^^^^^ removed "volatile" since on x86, gcc turns suppress_int++ | ||
616 | * into ridiculous 3-insn sequence otherwise. | ||
617 | * We don't change suppress_int asyncronously (in a signal handler), | ||
618 | * but we do read it async. | ||
619 | */ | ||
603 | volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */ | 620 | volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */ |
604 | #if !ENABLE_PLATFORM_MINGW32 | 621 | #if !ENABLE_PLATFORM_MINGW32 |
605 | volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */ | 622 | volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */ |
@@ -954,7 +971,8 @@ int_on(void) | |||
954 | { | 971 | { |
955 | barrier(); | 972 | barrier(); |
956 | if (--suppress_int == 0 && pending_int) | 973 | if (--suppress_int == 0 && pending_int) |
957 | raise_interrupt(); | 974 | raise_interrupt(); /* does not return */ |
975 | barrier(); | ||
958 | } | 976 | } |
959 | #if DEBUG_INTONOFF | 977 | #if DEBUG_INTONOFF |
960 | # define INT_ON do { \ | 978 | # define INT_ON do { \ |
@@ -970,7 +988,8 @@ force_int_on(void) | |||
970 | barrier(); | 988 | barrier(); |
971 | suppress_int = 0; | 989 | suppress_int = 0; |
972 | if (pending_int) | 990 | if (pending_int) |
973 | raise_interrupt(); | 991 | raise_interrupt(); /* does not return */ |
992 | barrier(); | ||
974 | } | 993 | } |
975 | #define FORCE_INT_ON force_int_on() | 994 | #define FORCE_INT_ON force_int_on() |
976 | 995 | ||
@@ -980,7 +999,8 @@ force_int_on(void) | |||
980 | barrier(); \ | 999 | barrier(); \ |
981 | suppress_int = (v); \ | 1000 | suppress_int = (v); \ |
982 | if (suppress_int == 0 && pending_int) \ | 1001 | if (suppress_int == 0 && pending_int) \ |
983 | raise_interrupt(); \ | 1002 | raise_interrupt(); /* does not return */ \ |
1003 | barrier(); \ | ||
984 | } while (0) | 1004 | } while (0) |
985 | 1005 | ||
986 | 1006 | ||
@@ -2547,30 +2567,6 @@ getoptsreset(const char *value) | |||
2547 | #endif | 2567 | #endif |
2548 | 2568 | ||
2549 | /* | 2569 | /* |
2550 | * Compares two strings up to the first = or '\0'. The first | ||
2551 | * string must be terminated by '='; the second may be terminated by | ||
2552 | * either '=' or '\0'. | ||
2553 | */ | ||
2554 | static int | ||
2555 | varcmp(const char *p, const char *q) | ||
2556 | { | ||
2557 | int c, d; | ||
2558 | |||
2559 | while ((c = *p) == (d = *q)) { | ||
2560 | if (c == '\0' || c == '=') | ||
2561 | goto out; | ||
2562 | p++; | ||
2563 | q++; | ||
2564 | } | ||
2565 | if (c == '=') | ||
2566 | c = '\0'; | ||
2567 | if (d == '=') | ||
2568 | d = '\0'; | ||
2569 | out: | ||
2570 | return c - d; | ||
2571 | } | ||
2572 | |||
2573 | /* | ||
2574 | * Find the appropriate entry in the hash table from the name. | 2570 | * Find the appropriate entry in the hash table from the name. |
2575 | */ | 2571 | */ |
2576 | static struct var ** | 2572 | static struct var ** |
@@ -2881,7 +2877,7 @@ setvar(const char *name, const char *val, int flags) | |||
2881 | p = mempcpy(nameeq, name, namelen); | 2877 | p = mempcpy(nameeq, name, namelen); |
2882 | if (val) { | 2878 | if (val) { |
2883 | *p++ = '='; | 2879 | *p++ = '='; |
2884 | memcpy(p, val, vallen); | 2880 | strcpy(p, val); |
2885 | } | 2881 | } |
2886 | vp = setvareq(nameeq, flags | VNOSAVE); | 2882 | vp = setvareq(nameeq, flags | VNOSAVE); |
2887 | INT_ON; | 2883 | INT_ON; |
@@ -10485,7 +10481,7 @@ evaltree(union node *n, int flags) | |||
10485 | } | 10481 | } |
10486 | if (flags & EV_EXIT) { | 10482 | if (flags & EV_EXIT) { |
10487 | exexit: | 10483 | exexit: |
10488 | raise_exception(EXEND); | 10484 | raise_exception(EXEND); /* does not return */ |
10489 | } | 10485 | } |
10490 | 10486 | ||
10491 | popstackmark(&smark); | 10487 | popstackmark(&smark); |
@@ -11554,7 +11550,7 @@ evalcommand(union node *cmd, int flags) | |||
11554 | 11550 | ||
11555 | /* We have a redirection error. */ | 11551 | /* We have a redirection error. */ |
11556 | if (spclbltin > 0) | 11552 | if (spclbltin > 0) |
11557 | raise_exception(EXERROR); | 11553 | raise_exception(EXERROR); /* does not return */ |
11558 | 11554 | ||
11559 | goto out; | 11555 | goto out; |
11560 | } | 11556 | } |
@@ -13347,18 +13343,19 @@ simplecmd(void) | |||
13347 | if (args && app == &args->narg.next | 13343 | if (args && app == &args->narg.next |
13348 | && !vars && !redir | 13344 | && !vars && !redir |
13349 | ) { | 13345 | ) { |
13350 | struct builtincmd *bcmd; | 13346 | // struct builtincmd *bcmd; |
13351 | const char *name; | 13347 | // const char *name; |
13352 | 13348 | ||
13353 | /* We have a function */ | 13349 | /* We have a function */ |
13354 | if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP) | 13350 | if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP) |
13355 | raise_error_unexpected_syntax(TRP); | 13351 | raise_error_unexpected_syntax(TRP); |
13356 | name = n->narg.text; | 13352 | //bash allows functions named "123", "..", "return"! |
13357 | if (!goodname(name) | 13353 | // name = n->narg.text; |
13358 | || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd)) | 13354 | // if (!goodname(name) |
13359 | ) { | 13355 | // || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd)) |
13360 | raise_error_syntax("bad function name"); | 13356 | // ) { |
13361 | } | 13357 | // raise_error_syntax("bad function name"); |
13358 | // } | ||
13362 | n->type = NDEFUN; | 13359 | n->type = NDEFUN; |
13363 | checkkwd = CHKNL | CHKKWD | CHKALIAS; | 13360 | checkkwd = CHKNL | CHKKWD | CHKALIAS; |
13364 | n->ndefun.text = n->narg.text; | 13361 | n->ndefun.text = n->narg.text; |
@@ -15964,7 +15961,7 @@ procargs(char **argv) | |||
15964 | optlist[i] = 2; | 15961 | optlist[i] = 2; |
15965 | if (options(&login_sh)) { | 15962 | if (options(&login_sh)) { |
15966 | /* it already printed err message */ | 15963 | /* it already printed err message */ |
15967 | raise_exception(EXERROR); | 15964 | raise_exception(EXERROR); /* does not return */ |
15968 | } | 15965 | } |
15969 | xargv = argptr; | 15966 | xargv = argptr; |
15970 | xminusc = minusc; | 15967 | xminusc = minusc; |