aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-19 21:59:35 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-19 21:59:35 +0000
commit653d8e79b21f39fa97c3043296e36971bb8ef555 (patch)
tree5324e83352c2db22b9835036be98afa3f1860069
parent731de5ce76b42decdb8dce4277c839efde8b114f (diff)
downloadbusybox-w32-653d8e79b21f39fa97c3043296e36971bb8ef555.tar.gz
busybox-w32-653d8e79b21f39fa97c3043296e36971bb8ef555.tar.bz2
busybox-w32-653d8e79b21f39fa97c3043296e36971bb8ef555.zip
ash: make evaltree save/restore int suppression depth.
Hopefully this fixes bug 189. Not confirmed by users yet. function old new delta evaltree 809 842 +33 evalvar 1374 1376 +2
-rw-r--r--shell/ash.c116
1 files changed, 78 insertions, 38 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 9bb1d421e..a8383d805 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -30,7 +30,7 @@
30 */ 30 */
31 31
32/* 32/*
33 * The follow should be set to reflect the type of system you have: 33 * The following should be set to reflect the type of system you have:
34 * JOBS -> 1 if you have Berkeley job control, 0 otherwise. 34 * JOBS -> 1 if you have Berkeley job control, 0 otherwise.
35 * define SYSV if you are running under System V. 35 * define SYSV if you are running under System V.
36 * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) 36 * define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
@@ -40,6 +40,11 @@
40 * a quit signal will generate a core dump. 40 * a quit signal will generate a core dump.
41 */ 41 */
42#define DEBUG 0 42#define DEBUG 0
43/* Tweak debug output verbosity here */
44#define DEBUG_TIME 0
45#define DEBUG_PID 1
46#define DEBUG_SIG 1
47
43#define PROFILE 0 48#define PROFILE 0
44 49
45#define IFS_BROKEN 50#define IFS_BROKEN
@@ -47,9 +52,9 @@
47#define JOBS ENABLE_ASH_JOB_CONTROL 52#define JOBS ENABLE_ASH_JOB_CONTROL
48 53
49#if DEBUG 54#if DEBUG
50#ifndef _GNU_SOURCE 55# ifndef _GNU_SOURCE
51#define _GNU_SOURCE 56# define _GNU_SOURCE
52#endif 57# endif
53#endif 58#endif
54 59
55#include "busybox.h" /* for applet_names */ 60#include "busybox.h" /* for applet_names */
@@ -71,11 +76,11 @@
71#endif 76#endif
72 77
73#ifndef PIPE_BUF 78#ifndef PIPE_BUF
74#define PIPE_BUF 4096 /* amount of buffering in a pipe */ 79# define PIPE_BUF 4096 /* amount of buffering in a pipe */
75#endif 80#endif
76 81
77#if defined(__uClinux__) 82#if defined(__uClinux__)
78#error "Do not even bother, ash will not run on NOMMU machine" 83# error "Do not even bother, ash will not run on NOMMU machine"
79#endif 84#endif
80 85
81 86
@@ -86,14 +91,6 @@
86#define CMDTABLESIZE 31 /* should be prime */ 91#define CMDTABLESIZE 31 /* should be prime */
87 92
88 93
89/* ============ Misc helpers */
90
91#define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0)
92
93/* C99 says: "char" declaration may be signed or unsigned by default */
94#define signed_char2int(sc) ((int)((signed char)sc))
95
96
97/* ============ Shell options */ 94/* ============ Shell options */
98 95
99static const char *const optletters_optnames[] = { 96static const char *const optletters_optnames[] = {
@@ -257,7 +254,24 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
257} while (0) 254} while (0)
258 255
259 256
257/* ============ DEBUG */
258#if DEBUG
259static void trace_printf(const char *fmt, ...);
260static void trace_vprintf(const char *fmt, va_list va);
261# define TRACE(param) trace_printf param
262# define TRACEV(param) trace_vprintf param
263#else
264# define TRACE(param)
265# define TRACEV(param)
266#endif
267
268
260/* ============ Utility functions */ 269/* ============ Utility functions */
270#define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0)
271
272/* C99 say: "char" declaration may be signed or unsigned by default */
273#define signed_char2int(sc) ((int)(signed char)(sc))
274
261static int isdigit_str9(const char *str) 275static int isdigit_str9(const char *str)
262{ 276{
263 int maxlen = 9 + 1; /* max 9 digits: 999999999 */ 277 int maxlen = 9 + 1; /* max 9 digits: 999999999 */
@@ -296,6 +310,12 @@ raise_exception(int e)
296 exception_type = e; 310 exception_type = e;
297 longjmp(exception_handler->loc, 1); 311 longjmp(exception_handler->loc, 1);
298} 312}
313#if DEBUG
314#define raise_exception(e) do { \
315 TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
316 raise_exception(e); \
317} while (0)
318#endif
299 319
300/* 320/*
301 * Called from trap.c when a SIGINT is received. (If the user specifies 321 * Called from trap.c when a SIGINT is received. (If the user specifies
@@ -328,6 +348,12 @@ raise_interrupt(void)
328 raise_exception(ex_type); 348 raise_exception(ex_type);
329 /* NOTREACHED */ 349 /* NOTREACHED */
330} 350}
351#if DEBUG
352#define raise_interrupt() do { \
353 TRACE(("raising interrupt on line %d\n", __LINE__)); \
354 raise_interrupt(); \
355} while (0)
356#endif
331 357
332#if ENABLE_ASH_OPTIMIZE_FOR_SIZE 358#if ENABLE_ASH_OPTIMIZE_FOR_SIZE
333static void 359static void
@@ -346,7 +372,9 @@ force_int_on(void)
346 raise_interrupt(); 372 raise_interrupt();
347} 373}
348#define FORCE_INT_ON force_int_on() 374#define FORCE_INT_ON force_int_on()
349#else 375
376#else /* !ASH_OPTIMIZE_FOR_SIZE */
377
350#define INT_ON do { \ 378#define INT_ON do { \
351 xbarrier(); \ 379 xbarrier(); \
352 if (--suppressint == 0 && intpending) \ 380 if (--suppressint == 0 && intpending) \
@@ -358,7 +386,7 @@ force_int_on(void)
358 if (intpending) \ 386 if (intpending) \
359 raise_interrupt(); \ 387 raise_interrupt(); \
360} while (0) 388} while (0)
361#endif /* ASH_OPTIMIZE_FOR_SIZE */ 389#endif /* !ASH_OPTIMIZE_FOR_SIZE */
362 390
363#define SAVE_INT(v) ((v) = suppressint) 391#define SAVE_INT(v) ((v) = suppressint)
364 392
@@ -666,6 +694,12 @@ trace_printf(const char *fmt, ...)
666 694
667 if (debug != 1) 695 if (debug != 1)
668 return; 696 return;
697 if (DEBUG_TIME)
698 fprintf(tracefile, "%u ", (int) time(NULL));
699 if (DEBUG_PID)
700 fprintf(tracefile, "[%u] ", (int) getpid());
701 if (DEBUG_SIG)
702 fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint);
669 va_start(va, fmt); 703 va_start(va, fmt);
670 vfprintf(tracefile, fmt, va); 704 vfprintf(tracefile, fmt, va);
671 va_end(va); 705 va_end(va);
@@ -676,6 +710,12 @@ trace_vprintf(const char *fmt, va_list va)
676{ 710{
677 if (debug != 1) 711 if (debug != 1)
678 return; 712 return;
713 if (DEBUG_TIME)
714 fprintf(tracefile, "%u ", (int) time(NULL));
715 if (DEBUG_PID)
716 fprintf(tracefile, "[%u] ", (int) getpid());
717 if (DEBUG_SIG)
718 fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint);
679 vfprintf(tracefile, fmt, va); 719 vfprintf(tracefile, fmt, va);
680} 720}
681 721
@@ -980,14 +1020,6 @@ showtree(union node *n)
980 shtree(n, 1, NULL, stdout); 1020 shtree(n, 1, NULL, stdout);
981} 1021}
982 1022
983#define TRACE(param) trace_printf param
984#define TRACEV(param) trace_vprintf param
985
986#else
987
988#define TRACE(param)
989#define TRACEV(param)
990
991#endif /* DEBUG */ 1023#endif /* DEBUG */
992 1024
993 1025
@@ -7951,6 +7983,7 @@ dotrap(void)
7951 pendingsig = 0; 7983 pendingsig = 0;
7952 xbarrier(); 7984 xbarrier();
7953 7985
7986 TRACE(("dotrap entered\n"));
7954 for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) { 7987 for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
7955 int want_exexit; 7988 int want_exexit;
7956 char *t; 7989 char *t;
@@ -7962,15 +7995,20 @@ dotrap(void)
7962 * don't upset it by resetting gotsig[SIGINT-1] */ 7995 * don't upset it by resetting gotsig[SIGINT-1] */
7963 if (sig == SIGINT && !t) 7996 if (sig == SIGINT && !t)
7964 continue; 7997 continue;
7998
7999 TRACE(("sig %d is active, will run handler '%s'\n", sig, t));
7965 *g = 0; 8000 *g = 0;
7966 if (!t) 8001 if (!t)
7967 continue; 8002 continue;
7968 want_exexit = evalstring(t, SKIPEVAL); 8003 want_exexit = evalstring(t, SKIPEVAL);
7969 exitstatus = savestatus; 8004 exitstatus = savestatus;
7970 if (want_exexit) 8005 if (want_exexit) {
8006 TRACE(("dotrap returns %d\n", skip));
7971 return want_exexit; 8007 return want_exexit;
8008 }
7972 } 8009 }
7973 8010
8011 TRACE(("dotrap returns 0\n"));
7974 return 0; 8012 return 0;
7975} 8013}
7976 8014
@@ -7997,22 +8035,27 @@ evaltree(union node *n, int flags)
7997 int checkexit = 0; 8035 int checkexit = 0;
7998 void (*evalfn)(union node *, int); 8036 void (*evalfn)(union node *, int);
7999 int status; 8037 int status;
8038 int int_level;
8039
8040 SAVE_INT(int_level);
8000 8041
8001 if (n == NULL) { 8042 if (n == NULL) {
8002 TRACE(("evaltree(NULL) called\n")); 8043 TRACE(("evaltree(NULL) called\n"));
8003 goto out1; 8044 goto out1;
8004 } 8045 }
8005 TRACE(("pid %d, evaltree(%p: %d, %d) called\n", 8046 TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
8006 getpid(), n, n->type, flags));
8007 8047
8008 exception_handler = &jmploc; 8048 exception_handler = &jmploc;
8009 { 8049 {
8010 int err = setjmp(jmploc.loc); 8050 int err = setjmp(jmploc.loc);
8011 if (err) { 8051 if (err) {
8012 /* if it was a signal, check for trap handlers */ 8052 /* if it was a signal, check for trap handlers */
8013 if (exception_type == EXSIG) 8053 if (exception_type == EXSIG) {
8054 TRACE(("exception %d (EXSIG) in evaltree, err=%d\n", exception, err));
8014 goto out; 8055 goto out;
8056 }
8015 /* continue on the way out */ 8057 /* continue on the way out */
8058 TRACE(("exception %d in evaltree, propagating err=%d\n", exception, err));
8016 exception_handler = savehandler; 8059 exception_handler = savehandler;
8017 longjmp(exception_handler->loc, err); 8060 longjmp(exception_handler->loc, err);
8018 } 8061 }
@@ -8095,7 +8138,8 @@ evaltree(union node *n, int flags)
8095 if (exitstatus == 0) { 8138 if (exitstatus == 0) {
8096 n = n->nif.ifpart; 8139 n = n->nif.ifpart;
8097 goto evaln; 8140 goto evaln;
8098 } else if (n->nif.elsepart) { 8141 }
8142 if (n->nif.elsepart) {
8099 n = n->nif.elsepart; 8143 n = n->nif.elsepart;
8100 goto evaln; 8144 goto evaln;
8101 } 8145 }
@@ -8121,6 +8165,9 @@ evaltree(union node *n, int flags)
8121 exexit: 8165 exexit:
8122 raise_exception(EXEXIT); 8166 raise_exception(EXEXIT);
8123 } 8167 }
8168
8169 RESTORE_INT(int_level);
8170 TRACE(("leaving evaltree (no interrupts)\n"));
8124} 8171}
8125 8172
8126#if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3) 8173#if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
@@ -8998,6 +9045,7 @@ evalcommand(union node *cmd, int flags)
8998 if (forkshell(jp, cmd, FORK_FG) != 0) { 9045 if (forkshell(jp, cmd, FORK_FG) != 0) {
8999 exitstatus = waitforjob(jp); 9046 exitstatus = waitforjob(jp);
9000 INT_ON; 9047 INT_ON;
9048 TRACE(("forked child exited with %d\n", exitstatus));
9001 break; 9049 break;
9002 } 9050 }
9003 FORCE_INT_ON; 9051 FORCE_INT_ON;
@@ -13762,7 +13810,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
13762 exception_handler = &jmploc; 13810 exception_handler = &jmploc;
13763#if DEBUG 13811#if DEBUG
13764 opentrace(); 13812 opentrace();
13765 trace_puts("Shell args: "); 13813 TRACE(("Shell args: "));
13766 trace_puts_args(argv); 13814 trace_puts_args(argv);
13767#endif 13815#endif
13768 rootpid = getpid(); 13816 rootpid = getpid();
@@ -13847,14 +13895,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
13847 /* NOTREACHED */ 13895 /* NOTREACHED */
13848} 13896}
13849 13897
13850#if DEBUG
13851const char *applet_name = "debug stuff usage";
13852int main(int argc, char **argv)
13853{
13854 return ash_main(argc, argv);
13855}
13856#endif
13857
13858 13898
13859/*- 13899/*-
13860 * Copyright (c) 1989, 1991, 1993, 1994 13900 * Copyright (c) 1989, 1991, 1993, 1994