aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c99
1 files changed, 51 insertions, 48 deletions
diff --git a/shell/ash.c b/shell/ash.c
index bea24601c..fd2fc9f23 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -404,11 +404,11 @@ struct globals_misc {
volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
- smallint exception_type; /* kind of exception (0..5) */
- /* exceptions */
+ smallint exception_type; /* kind of exception: */
#define EXINT 0 /* SIGINT received */
#define EXERROR 1 /* a generic error */
-#define EXEXIT 4 /* exit the shell */
+#define EXEND 3 /* exit the shell */
+#define EXEXIT 4 /* exit the shell via exitcmd */
char nullstr[1]; /* zero length string */
@@ -8237,7 +8237,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
exitstatus = exerrno;
TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
prog, e, suppress_int));
- ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found"));
+ ash_msg_and_raise(EXEND, "%s: %s", prog, errmsg(e, "not found"));
/* NOTREACHED */
}
@@ -9291,9 +9291,9 @@ evaltree(union node *n, int flags)
dotrap();
if (checkexit & status)
- raise_exception(EXEXIT);
+ raise_exception(EXEND);
if (flags & EV_EXIT)
- raise_exception(EXEXIT);
+ raise_exception(EXEND);
popstackmark(&smark);
TRACE(("leaving evaltree (no interrupts)\n"));
@@ -14147,6 +14147,47 @@ ulimitcmd(int argc UNUSED_PARAM, char **argv)
/* ============ main() and helpers */
/*
+ * This routine is called when an error or an interrupt occurs in an
+ * interactive shell and control is returned to the main command loop
+ * but prior to exitshell.
+ */
+static void
+exitreset(void)
+{
+ /* from eval.c: */
+ if (savestatus >= 0) {
+ if (exception_type == EXEXIT || evalskip == SKIPFUNCDEF)
+ exitstatus = savestatus;
+ savestatus = -1;
+ }
+ evalskip = 0;
+ loopnest = 0;
+
+ /* from expand.c: */
+ ifsfree();
+
+ /* from redir.c: */
+ unwindredir(NULL);
+}
+
+/*
+ * This routine is called when an error or an interrupt occurs in an
+ * interactive shell and control is returned to the main command loop.
+ * (In dash, this function is auto-generated by build machinery).
+ */
+static void
+reset(void)
+{
+ /* from input.c: */
+ g_parsefile->left_in_buffer = 0;
+ g_parsefile->left_in_line = 0; /* clear input buffer */
+ popallfiles();
+
+ /* from var.c: */
+ unwindlocalvars(NULL);
+}
+
+/*
* Called to exit the shell.
*/
static void
@@ -14169,15 +14210,17 @@ exitshell(void)
trap[0] = NULL;
evalskip = 0;
evalstring(p, 0);
+ evalskip = SKIPFUNCDEF;
/*free(p); - we'll exit soon */
}
out:
+ exitreset();
/* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
* our setjobctl(0) does not panic if tcsetpgrp fails inside it.
*/
setjobctl(0);
flush_stdout_stderr();
- _exit(savestatus);
+ _exit(exitstatus);
/* NOTREACHED */
}
@@ -14337,46 +14380,6 @@ read_profile(const char *name)
popfile();
}
-/*
- * This routine is called when an error or an interrupt occurs in an
- * interactive shell and control is returned to the main command loop
- * but prior to exitshell.
- */
-static void
-exitreset(void)
-{
- /* from eval.c: */
- evalskip = 0;
- loopnest = 0;
- if (savestatus >= 0) {
- exitstatus = savestatus;
- savestatus = -1;
- }
-
- /* from expand.c: */
- ifsfree();
-
- /* from redir.c: */
- unwindredir(NULL);
-}
-
-/*
- * This routine is called when an error or an interrupt occurs in an
- * interactive shell and control is returned to the main command loop.
- * (In dash, this function is auto-generated by build machinery).
- */
-static void
-reset(void)
-{
- /* from input.c: */
- g_parsefile->left_in_buffer = 0;
- g_parsefile->left_in_line = 0; /* clear input buffer */
- popallfiles();
-
- /* from var.c: */
- unwindlocalvars(NULL);
-}
-
#if PROFILE
static short profile_buf[16384];
extern int etext();
@@ -14424,7 +14427,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
e = exception_type;
s = state;
- if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
+ if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
exitshell();
}