sh: Unify EXERROR and EXEXEC
The difference between EXERROR and EXEXEC was that EXEXEC passed along exitstatus and EXERROR set exitstatus to 2 in the handling code. By changing the places that raised EXERROR to set exitstatus to 2, the handling of EXERROR and EXEXEC becomes the same.
This commit is contained in:
parent
b8dfd02788
commit
4586c042eb
@ -35,7 +35,7 @@ EXCEPTIONS: Code for dealing with exceptions appears in
|
|||||||
exceptions.c. The C language doesn't include exception handling,
|
exceptions.c. The C language doesn't include exception handling,
|
||||||
so I implement it using setjmp and longjmp. The global variable
|
so I implement it using setjmp and longjmp. The global variable
|
||||||
exception contains the type of exception. EXERROR is raised by
|
exception contains the type of exception. EXERROR is raised by
|
||||||
calling error. EXINT is an interrupt.
|
calling error or errorwithstatus. EXINT is an interrupt.
|
||||||
|
|
||||||
INTERRUPTS: In an interactive shell, an interrupt will cause an
|
INTERRUPTS: In an interactive shell, an interrupt will cause an
|
||||||
EXINT exception to return to the main command loop. (Exception:
|
EXINT exception to return to the main command loop. (Exception:
|
||||||
|
@ -67,7 +67,7 @@ volatile sig_atomic_t suppressint;
|
|||||||
volatile sig_atomic_t intpending;
|
volatile sig_atomic_t intpending;
|
||||||
|
|
||||||
|
|
||||||
static void exverror(int, const char *, va_list) __printf0like(2, 0) __dead2;
|
static void verrorwithstatus(int, const char *, va_list) __printf0like(2, 0) __dead2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called to raise an exception. Since C doesn't include exceptions, we
|
* Called to raise an exception. Since C doesn't include exceptions, we
|
||||||
@ -154,7 +154,7 @@ warning(const char *msg, ...)
|
|||||||
* formatting. It then raises the error exception.
|
* formatting. It then raises the error exception.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
exverror(int cond, const char *msg, va_list ap)
|
verrorwithstatus(int status, const char *msg, va_list ap)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* An interrupt trumps an error. Certain places catch error
|
* An interrupt trumps an error. Certain places catch error
|
||||||
@ -168,14 +168,17 @@ exverror(int cond, const char *msg, va_list ap)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (msg)
|
if (msg)
|
||||||
TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
|
TRACE(("verrorwithstatus(%d, \"%s\") pid=%d\n",
|
||||||
|
status, msg, getpid()));
|
||||||
else
|
else
|
||||||
TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
|
TRACE(("verrorwithstatus(%d, NULL) pid=%d\n",
|
||||||
|
status, getpid()));
|
||||||
#endif
|
#endif
|
||||||
if (msg)
|
if (msg)
|
||||||
vwarning(msg, ap);
|
vwarning(msg, ap);
|
||||||
flushall();
|
flushall();
|
||||||
exraise(cond);
|
exitstatus = status;
|
||||||
|
exraise(EXERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -184,16 +187,16 @@ error(const char *msg, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
exverror(EXERROR, msg, ap);
|
verrorwithstatus(2, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
exerror(int cond, const char *msg, ...)
|
errorwithstatus(int status, const char *msg, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
exverror(cond, msg, ap);
|
verrorwithstatus(status, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,8 @@ extern volatile sig_atomic_t exception;
|
|||||||
|
|
||||||
/* exceptions */
|
/* exceptions */
|
||||||
#define EXINT 0 /* SIGINT received */
|
#define EXINT 0 /* SIGINT received */
|
||||||
#define EXERROR 1 /* a generic error */
|
#define EXERROR 1 /* a generic error with exitstatus */
|
||||||
#define EXEXEC 2 /* command execution failed */
|
#define EXEXIT 2 /* call exitshell(exitstatus) */
|
||||||
#define EXEXIT 3 /* call exitshell(exitstatus) */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,7 +82,7 @@ void exraise(int) __dead2;
|
|||||||
void onint(void) __dead2;
|
void onint(void) __dead2;
|
||||||
void warning(const char *, ...) __printflike(1, 2);
|
void warning(const char *, ...) __printflike(1, 2);
|
||||||
void error(const char *, ...) __printf0like(1, 2) __dead2;
|
void error(const char *, ...) __printf0like(1, 2) __dead2;
|
||||||
void exerror(int, const char *, ...) __printf0like(2, 3) __dead2;
|
void errorwithstatus(int, const char *, ...) __printf0like(2, 3) __dead2;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -466,13 +466,9 @@ evalredir(union node *n, int flags)
|
|||||||
handler = savehandler;
|
handler = savehandler;
|
||||||
e = exception;
|
e = exception;
|
||||||
popredir();
|
popredir();
|
||||||
if (e == EXERROR || e == EXEXEC) {
|
if (e == EXERROR && in_redirect) {
|
||||||
if (in_redirect) {
|
FORCEINTON;
|
||||||
if (e == EXERROR)
|
return;
|
||||||
exitstatus = 2;
|
|
||||||
FORCEINTON;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
longjmp(handler->loc, 1);
|
longjmp(handler->loc, 1);
|
||||||
} else {
|
} else {
|
||||||
@ -506,7 +502,7 @@ exphere(union node *redir, struct arglist *fn)
|
|||||||
forcelocal++;
|
forcelocal++;
|
||||||
savehandler = handler;
|
savehandler = handler;
|
||||||
if (setjmp(jmploc.loc))
|
if (setjmp(jmploc.loc))
|
||||||
need_longjmp = exception != EXERROR && exception != EXEXEC;
|
need_longjmp = exception != EXERROR;
|
||||||
else {
|
else {
|
||||||
handler = &jmploc;
|
handler = &jmploc;
|
||||||
expandarg(redir->nhere.doc, fn, 0);
|
expandarg(redir->nhere.doc, fn, 0);
|
||||||
@ -671,8 +667,6 @@ evalbackcmd(union node *n, struct backcmd *result)
|
|||||||
savehandler = handler;
|
savehandler = handler;
|
||||||
if (setjmp(jmploc.loc)) {
|
if (setjmp(jmploc.loc)) {
|
||||||
if (exception == EXERROR)
|
if (exception == EXERROR)
|
||||||
exitstatus = 2;
|
|
||||||
else if (exception == EXEXEC)
|
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
else if (exception != 0) {
|
else if (exception != 0) {
|
||||||
handler = savehandler;
|
handler = savehandler;
|
||||||
@ -1092,8 +1086,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
|||||||
e = exception;
|
e = exception;
|
||||||
if (e == EXINT)
|
if (e == EXINT)
|
||||||
exitstatus = SIGINT+128;
|
exitstatus = SIGINT+128;
|
||||||
else if (e != EXEXEC && e != EXEXIT)
|
|
||||||
exitstatus = 2;
|
|
||||||
goto cmddone;
|
goto cmddone;
|
||||||
}
|
}
|
||||||
handler = &jmploc;
|
handler = &jmploc;
|
||||||
@ -1142,8 +1134,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
|||||||
if (cmdentry.u.index != EXECCMD)
|
if (cmdentry.u.index != EXECCMD)
|
||||||
popredir();
|
popredir();
|
||||||
if (e != -1) {
|
if (e != -1) {
|
||||||
if ((e != EXERROR && e != EXEXEC)
|
if (e != EXERROR || cmdentry.special)
|
||||||
|| cmdentry.special)
|
|
||||||
exraise(e);
|
exraise(e);
|
||||||
popfilesupto(savetopfile);
|
popfilesupto(savetopfile);
|
||||||
if (flags != EV_BACKCMD)
|
if (flags != EV_BACKCMD)
|
||||||
|
@ -133,13 +133,10 @@ shellexec(char **argv, char **envp, const char *path, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map to POSIX errors */
|
/* Map to POSIX errors */
|
||||||
if (e == ENOENT || e == ENOTDIR) {
|
if (e == ENOENT || e == ENOTDIR)
|
||||||
exitstatus = 127;
|
errorwithstatus(127, "%s: not found", argv[0]);
|
||||||
exerror(EXEXEC, "%s: not found", argv[0]);
|
else
|
||||||
} else {
|
errorwithstatus(126, "%s: %s", argv[0], strerror(e));
|
||||||
exitstatus = 126;
|
|
||||||
exerror(EXEXEC, "%s: %s", argv[0], strerror(e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1006,7 +1006,7 @@ vforkexecshell(struct job *jp, char **argv, char **envp, const char *path, int i
|
|||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
TRACE(("Child shell %d\n", (int)getpid()));
|
TRACE(("Child shell %d\n", (int)getpid()));
|
||||||
if (setjmp(jmploc.loc))
|
if (setjmp(jmploc.loc))
|
||||||
_exit(exception == EXEXEC ? exitstatus : 2);
|
_exit(exitstatus);
|
||||||
if (pip != NULL) {
|
if (pip != NULL) {
|
||||||
close(pip[0]);
|
close(pip[0]);
|
||||||
if (pip[1] != 1) {
|
if (pip[1] != 1) {
|
||||||
|
@ -105,15 +105,6 @@ main(int argc, char *argv[])
|
|||||||
initcharset();
|
initcharset();
|
||||||
state = 0;
|
state = 0;
|
||||||
if (setjmp(main_handler.loc)) {
|
if (setjmp(main_handler.loc)) {
|
||||||
switch (exception) {
|
|
||||||
case EXERROR:
|
|
||||||
exitstatus = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 0 || iflag == 0 || ! rootshell ||
|
if (state == 0 || iflag == 0 || ! rootshell ||
|
||||||
exception == EXEXIT)
|
exception == EXEXIT)
|
||||||
exitshell(exitstatus);
|
exitshell(exitstatus);
|
||||||
|
Loading…
Reference in New Issue
Block a user