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:
parent
731de5ce76
commit
653d8e79b2
116
shell/ash.c
116
shell/ash.c
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user