aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c89
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 */
2554static int
2555varcmp(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 */
2576static struct var ** 2572static 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;