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
This commit is contained in:
Denis Vlasenko 2009-03-19 21:59:35 +00:00
parent 731de5ce76
commit 653d8e79b2

View File

@ -30,7 +30,7 @@
*/ */
/* /*
* The follow should be set to reflect the type of system you have: * The following should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise. * JOBS -> 1 if you have Berkeley job control, 0 otherwise.
* define SYSV if you are running under System V. * define SYSV if you are running under System V.
* define DEBUG=1 to compile in debugging ('set -o debug' to turn on) * define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
@ -40,6 +40,11 @@
* a quit signal will generate a core dump. * a quit signal will generate a core dump.
*/ */
#define DEBUG 0 #define DEBUG 0
/* Tweak debug output verbosity here */
#define DEBUG_TIME 0
#define DEBUG_PID 1
#define DEBUG_SIG 1
#define PROFILE 0 #define PROFILE 0
#define IFS_BROKEN #define IFS_BROKEN
@ -47,9 +52,9 @@
#define JOBS ENABLE_ASH_JOB_CONTROL #define JOBS ENABLE_ASH_JOB_CONTROL
#if DEBUG #if DEBUG
#ifndef _GNU_SOURCE # ifndef _GNU_SOURCE
#define _GNU_SOURCE # define _GNU_SOURCE
#endif # endif
#endif #endif
#include "busybox.h" /* for applet_names */ #include "busybox.h" /* for applet_names */
@ -71,11 +76,11 @@
#endif #endif
#ifndef PIPE_BUF #ifndef PIPE_BUF
#define PIPE_BUF 4096 /* amount of buffering in a pipe */ # define PIPE_BUF 4096 /* amount of buffering in a pipe */
#endif #endif
#if defined(__uClinux__) #if defined(__uClinux__)
#error "Do not even bother, ash will not run on NOMMU machine" # error "Do not even bother, ash will not run on NOMMU machine"
#endif #endif
@ -86,14 +91,6 @@
#define CMDTABLESIZE 31 /* should be prime */ #define CMDTABLESIZE 31 /* should be prime */
/* ============ Misc helpers */
#define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0)
/* C99 says: "char" declaration may be signed or unsigned by default */
#define signed_char2int(sc) ((int)((signed char)sc))
/* ============ Shell options */ /* ============ Shell options */
static const char *const optletters_optnames[] = { static const char *const optletters_optnames[] = {
@ -257,7 +254,24 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
} while (0) } while (0)
/* ============ DEBUG */
#if DEBUG
static void trace_printf(const char *fmt, ...);
static void trace_vprintf(const char *fmt, va_list va);
# define TRACE(param) trace_printf param
# define TRACEV(param) trace_vprintf param
#else
# define TRACE(param)
# define TRACEV(param)
#endif
/* ============ Utility functions */ /* ============ Utility functions */
#define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0)
/* C99 say: "char" declaration may be signed or unsigned by default */
#define signed_char2int(sc) ((int)(signed char)(sc))
static int isdigit_str9(const char *str) static int isdigit_str9(const char *str)
{ {
int maxlen = 9 + 1; /* max 9 digits: 999999999 */ int maxlen = 9 + 1; /* max 9 digits: 999999999 */
@ -296,6 +310,12 @@ raise_exception(int e)
exception_type = e; exception_type = e;
longjmp(exception_handler->loc, 1); longjmp(exception_handler->loc, 1);
} }
#if DEBUG
#define raise_exception(e) do { \
TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
raise_exception(e); \
} while (0)
#endif
/* /*
* Called from trap.c when a SIGINT is received. (If the user specifies * Called from trap.c when a SIGINT is received. (If the user specifies
@ -328,6 +348,12 @@ raise_interrupt(void)
raise_exception(ex_type); raise_exception(ex_type);
/* NOTREACHED */ /* NOTREACHED */
} }
#if DEBUG
#define raise_interrupt() do { \
TRACE(("raising interrupt on line %d\n", __LINE__)); \
raise_interrupt(); \
} while (0)
#endif
#if ENABLE_ASH_OPTIMIZE_FOR_SIZE #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
static void static void
@ -346,7 +372,9 @@ force_int_on(void)
raise_interrupt(); raise_interrupt();
} }
#define FORCE_INT_ON force_int_on() #define FORCE_INT_ON force_int_on()
#else
#else /* !ASH_OPTIMIZE_FOR_SIZE */
#define INT_ON do { \ #define INT_ON do { \
xbarrier(); \ xbarrier(); \
if (--suppressint == 0 && intpending) \ if (--suppressint == 0 && intpending) \
@ -358,7 +386,7 @@ force_int_on(void)
if (intpending) \ if (intpending) \
raise_interrupt(); \ raise_interrupt(); \
} while (0) } while (0)
#endif /* ASH_OPTIMIZE_FOR_SIZE */ #endif /* !ASH_OPTIMIZE_FOR_SIZE */
#define SAVE_INT(v) ((v) = suppressint) #define SAVE_INT(v) ((v) = suppressint)
@ -666,6 +694,12 @@ trace_printf(const char *fmt, ...)
if (debug != 1) if (debug != 1)
return; return;
if (DEBUG_TIME)
fprintf(tracefile, "%u ", (int) time(NULL));
if (DEBUG_PID)
fprintf(tracefile, "[%u] ", (int) getpid());
if (DEBUG_SIG)
fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint);
va_start(va, fmt); va_start(va, fmt);
vfprintf(tracefile, fmt, va); vfprintf(tracefile, fmt, va);
va_end(va); va_end(va);
@ -676,6 +710,12 @@ trace_vprintf(const char *fmt, va_list va)
{ {
if (debug != 1) if (debug != 1)
return; return;
if (DEBUG_TIME)
fprintf(tracefile, "%u ", (int) time(NULL));
if (DEBUG_PID)
fprintf(tracefile, "[%u] ", (int) getpid());
if (DEBUG_SIG)
fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint);
vfprintf(tracefile, fmt, va); vfprintf(tracefile, fmt, va);
} }
@ -980,14 +1020,6 @@ showtree(union node *n)
shtree(n, 1, NULL, stdout); shtree(n, 1, NULL, stdout);
} }
#define TRACE(param) trace_printf param
#define TRACEV(param) trace_vprintf param
#else
#define TRACE(param)
#define TRACEV(param)
#endif /* DEBUG */ #endif /* DEBUG */
@ -7951,6 +7983,7 @@ dotrap(void)
pendingsig = 0; pendingsig = 0;
xbarrier(); xbarrier();
TRACE(("dotrap entered\n"));
for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) { for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
int want_exexit; int want_exexit;
char *t; char *t;
@ -7962,15 +7995,20 @@ dotrap(void)
* don't upset it by resetting gotsig[SIGINT-1] */ * don't upset it by resetting gotsig[SIGINT-1] */
if (sig == SIGINT && !t) if (sig == SIGINT && !t)
continue; continue;
TRACE(("sig %d is active, will run handler '%s'\n", sig, t));
*g = 0; *g = 0;
if (!t) if (!t)
continue; continue;
want_exexit = evalstring(t, SKIPEVAL); want_exexit = evalstring(t, SKIPEVAL);
exitstatus = savestatus; exitstatus = savestatus;
if (want_exexit) if (want_exexit) {
TRACE(("dotrap returns %d\n", skip));
return want_exexit; return want_exexit;
}
} }
TRACE(("dotrap returns 0\n"));
return 0; return 0;
} }
@ -7997,22 +8035,27 @@ evaltree(union node *n, int flags)
int checkexit = 0; int checkexit = 0;
void (*evalfn)(union node *, int); void (*evalfn)(union node *, int);
int status; int status;
int int_level;
SAVE_INT(int_level);
if (n == NULL) { if (n == NULL) {
TRACE(("evaltree(NULL) called\n")); TRACE(("evaltree(NULL) called\n"));
goto out1; goto out1;
} }
TRACE(("pid %d, evaltree(%p: %d, %d) called\n", TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
getpid(), n, n->type, flags));
exception_handler = &jmploc; exception_handler = &jmploc;
{ {
int err = setjmp(jmploc.loc); int err = setjmp(jmploc.loc);
if (err) { if (err) {
/* if it was a signal, check for trap handlers */ /* if it was a signal, check for trap handlers */
if (exception_type == EXSIG) if (exception_type == EXSIG) {
TRACE(("exception %d (EXSIG) in evaltree, err=%d\n", exception, err));
goto out; goto out;
}
/* continue on the way out */ /* continue on the way out */
TRACE(("exception %d in evaltree, propagating err=%d\n", exception, err));
exception_handler = savehandler; exception_handler = savehandler;
longjmp(exception_handler->loc, err); longjmp(exception_handler->loc, err);
} }
@ -8095,7 +8138,8 @@ evaltree(union node *n, int flags)
if (exitstatus == 0) { if (exitstatus == 0) {
n = n->nif.ifpart; n = n->nif.ifpart;
goto evaln; goto evaln;
} else if (n->nif.elsepart) { }
if (n->nif.elsepart) {
n = n->nif.elsepart; n = n->nif.elsepart;
goto evaln; goto evaln;
} }
@ -8121,6 +8165,9 @@ evaltree(union node *n, int flags)
exexit: exexit:
raise_exception(EXEXIT); raise_exception(EXEXIT);
} }
RESTORE_INT(int_level);
TRACE(("leaving evaltree (no interrupts)\n"));
} }
#if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3) #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
@ -8998,6 +9045,7 @@ evalcommand(union node *cmd, int flags)
if (forkshell(jp, cmd, FORK_FG) != 0) { if (forkshell(jp, cmd, FORK_FG) != 0) {
exitstatus = waitforjob(jp); exitstatus = waitforjob(jp);
INT_ON; INT_ON;
TRACE(("forked child exited with %d\n", exitstatus));
break; break;
} }
FORCE_INT_ON; FORCE_INT_ON;
@ -13762,7 +13810,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
exception_handler = &jmploc; exception_handler = &jmploc;
#if DEBUG #if DEBUG
opentrace(); opentrace();
trace_puts("Shell args: "); TRACE(("Shell args: "));
trace_puts_args(argv); trace_puts_args(argv);
#endif #endif
rootpid = getpid(); rootpid = getpid();
@ -13847,14 +13895,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
/* NOTREACHED */ /* NOTREACHED */
} }
#if DEBUG
const char *applet_name = "debug stuff usage";
int main(int argc, char **argv)
{
return ash_main(argc, argv);
}
#endif
/*- /*-
* Copyright (c) 1989, 1991, 1993, 1994 * Copyright (c) 1989, 1991, 1993, 1994