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
a641e44515
commit
bb324af62a
@ -35,7 +35,7 @@ EXCEPTIONS: Code for dealing with exceptions appears in
|
||||
exceptions.c. The C language doesn't include exception handling,
|
||||
so I implement it using setjmp and longjmp. The global variable
|
||||
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
|
||||
EXINT exception to return to the main command loop. (Exception:
|
||||
|
@ -67,7 +67,7 @@ volatile sig_atomic_t suppressint;
|
||||
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
|
||||
@ -154,7 +154,7 @@ warning(const char *msg, ...)
|
||||
* formatting. It then raises the error exception.
|
||||
*/
|
||||
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
|
||||
@ -168,14 +168,17 @@ exverror(int cond, const char *msg, va_list ap)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (msg)
|
||||
TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
|
||||
TRACE(("verrorwithstatus(%d, \"%s\") pid=%d\n",
|
||||
status, msg, getpid()));
|
||||
else
|
||||
TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
|
||||
TRACE(("verrorwithstatus(%d, NULL) pid=%d\n",
|
||||
status, getpid()));
|
||||
#endif
|
||||
if (msg)
|
||||
vwarning(msg, ap);
|
||||
flushall();
|
||||
exraise(cond);
|
||||
exitstatus = status;
|
||||
exraise(EXERROR);
|
||||
}
|
||||
|
||||
|
||||
@ -184,16 +187,16 @@ error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
exverror(EXERROR, msg, ap);
|
||||
verrorwithstatus(2, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
exerror(int cond, const char *msg, ...)
|
||||
errorwithstatus(int status, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
exverror(cond, msg, ap);
|
||||
verrorwithstatus(status, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -55,9 +55,8 @@ extern volatile sig_atomic_t exception;
|
||||
|
||||
/* exceptions */
|
||||
#define EXINT 0 /* SIGINT received */
|
||||
#define EXERROR 1 /* a generic error */
|
||||
#define EXEXEC 2 /* command execution failed */
|
||||
#define EXEXIT 3 /* call exitshell(exitstatus) */
|
||||
#define EXERROR 1 /* a generic error with exitstatus */
|
||||
#define EXEXIT 2 /* call exitshell(exitstatus) */
|
||||
|
||||
|
||||
/*
|
||||
@ -83,7 +82,7 @@ void exraise(int) __dead2;
|
||||
void onint(void) __dead2;
|
||||
void warning(const char *, ...) __printflike(1, 2);
|
||||
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;
|
||||
e = exception;
|
||||
popredir();
|
||||
if (e == EXERROR || e == EXEXEC) {
|
||||
if (in_redirect) {
|
||||
if (e == EXERROR)
|
||||
exitstatus = 2;
|
||||
FORCEINTON;
|
||||
return;
|
||||
}
|
||||
if (e == EXERROR && in_redirect) {
|
||||
FORCEINTON;
|
||||
return;
|
||||
}
|
||||
longjmp(handler->loc, 1);
|
||||
} else {
|
||||
@ -506,7 +502,7 @@ exphere(union node *redir, struct arglist *fn)
|
||||
forcelocal++;
|
||||
savehandler = handler;
|
||||
if (setjmp(jmploc.loc))
|
||||
need_longjmp = exception != EXERROR && exception != EXEXEC;
|
||||
need_longjmp = exception != EXERROR;
|
||||
else {
|
||||
handler = &jmploc;
|
||||
expandarg(redir->nhere.doc, fn, 0);
|
||||
@ -671,8 +667,6 @@ evalbackcmd(union node *n, struct backcmd *result)
|
||||
savehandler = handler;
|
||||
if (setjmp(jmploc.loc)) {
|
||||
if (exception == EXERROR)
|
||||
exitstatus = 2;
|
||||
else if (exception == EXEXEC)
|
||||
/* nothing */;
|
||||
else if (exception != 0) {
|
||||
handler = savehandler;
|
||||
@ -1092,8 +1086,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
e = exception;
|
||||
if (e == EXINT)
|
||||
exitstatus = SIGINT+128;
|
||||
else if (e != EXEXEC && e != EXEXIT)
|
||||
exitstatus = 2;
|
||||
goto cmddone;
|
||||
}
|
||||
handler = &jmploc;
|
||||
@ -1142,8 +1134,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
if (cmdentry.u.index != EXECCMD)
|
||||
popredir();
|
||||
if (e != -1) {
|
||||
if ((e != EXERROR && e != EXEXEC)
|
||||
|| cmdentry.special)
|
||||
if (e != EXERROR || cmdentry.special)
|
||||
exraise(e);
|
||||
popfilesupto(savetopfile);
|
||||
if (flags != EV_BACKCMD)
|
||||
|
@ -133,13 +133,10 @@ shellexec(char **argv, char **envp, const char *path, int idx)
|
||||
}
|
||||
|
||||
/* Map to POSIX errors */
|
||||
if (e == ENOENT || e == ENOTDIR) {
|
||||
exitstatus = 127;
|
||||
exerror(EXEXEC, "%s: not found", argv[0]);
|
||||
} else {
|
||||
exitstatus = 126;
|
||||
exerror(EXEXEC, "%s: %s", argv[0], strerror(e));
|
||||
}
|
||||
if (e == ENOENT || e == ENOTDIR)
|
||||
errorwithstatus(127, "%s: not found", argv[0]);
|
||||
else
|
||||
errorwithstatus(126, "%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) {
|
||||
TRACE(("Child shell %d\n", (int)getpid()));
|
||||
if (setjmp(jmploc.loc))
|
||||
_exit(exception == EXEXEC ? exitstatus : 2);
|
||||
_exit(exitstatus);
|
||||
if (pip != NULL) {
|
||||
close(pip[0]);
|
||||
if (pip[1] != 1) {
|
||||
|
@ -105,15 +105,6 @@ main(int argc, char *argv[])
|
||||
initcharset();
|
||||
state = 0;
|
||||
if (setjmp(main_handler.loc)) {
|
||||
switch (exception) {
|
||||
case EXERROR:
|
||||
exitstatus = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == 0 || iflag == 0 || ! rootshell ||
|
||||
exception == EXEXIT)
|
||||
exitshell(exitstatus);
|
||||
|
Loading…
Reference in New Issue
Block a user