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 {
404 volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */ 404 volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
405 volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */ 405 volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
406 volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */ 406 volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
407 smallint exception_type; /* kind of exception (0..5) */ 407 smallint exception_type; /* kind of exception: */
408 /* exceptions */
409#define EXINT 0 /* SIGINT received */ 408#define EXINT 0 /* SIGINT received */
410#define EXERROR 1 /* a generic error */ 409#define EXERROR 1 /* a generic error */
411#define EXEXIT 4 /* exit the shell */ 410#define EXEND 3 /* exit the shell */
411#define EXEXIT 4 /* exit the shell via exitcmd */
412 412
413 char nullstr[1]; /* zero length string */ 413 char nullstr[1]; /* zero length string */
414 414
@@ -8237,7 +8237,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
8237 exitstatus = exerrno; 8237 exitstatus = exerrno;
8238 TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n", 8238 TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
8239 prog, e, suppress_int)); 8239 prog, e, suppress_int));
8240 ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found")); 8240 ash_msg_and_raise(EXEND, "%s: %s", prog, errmsg(e, "not found"));
8241 /* NOTREACHED */ 8241 /* NOTREACHED */
8242} 8242}
8243 8243
@@ -9291,9 +9291,9 @@ evaltree(union node *n, int flags)
9291 dotrap(); 9291 dotrap();
9292 9292
9293 if (checkexit & status) 9293 if (checkexit & status)
9294 raise_exception(EXEXIT); 9294 raise_exception(EXEND);
9295 if (flags & EV_EXIT) 9295 if (flags & EV_EXIT)
9296 raise_exception(EXEXIT); 9296 raise_exception(EXEND);
9297 9297
9298 popstackmark(&smark); 9298 popstackmark(&smark);
9299 TRACE(("leaving evaltree (no interrupts)\n")); 9299 TRACE(("leaving evaltree (no interrupts)\n"));
@@ -14147,6 +14147,47 @@ ulimitcmd(int argc UNUSED_PARAM, char **argv)
14147/* ============ main() and helpers */ 14147/* ============ main() and helpers */
14148 14148
14149/* 14149/*
14150 * This routine is called when an error or an interrupt occurs in an
14151 * interactive shell and control is returned to the main command loop
14152 * but prior to exitshell.
14153 */
14154static void
14155exitreset(void)
14156{
14157 /* from eval.c: */
14158 if (savestatus >= 0) {
14159 if (exception_type == EXEXIT || evalskip == SKIPFUNCDEF)
14160 exitstatus = savestatus;
14161 savestatus = -1;
14162 }
14163 evalskip = 0;
14164 loopnest = 0;
14165
14166 /* from expand.c: */
14167 ifsfree();
14168
14169 /* from redir.c: */
14170 unwindredir(NULL);
14171}
14172
14173/*
14174 * This routine is called when an error or an interrupt occurs in an
14175 * interactive shell and control is returned to the main command loop.
14176 * (In dash, this function is auto-generated by build machinery).
14177 */
14178static void
14179reset(void)
14180{
14181 /* from input.c: */
14182 g_parsefile->left_in_buffer = 0;
14183 g_parsefile->left_in_line = 0; /* clear input buffer */
14184 popallfiles();
14185
14186 /* from var.c: */
14187 unwindlocalvars(NULL);
14188}
14189
14190/*
14150 * Called to exit the shell. 14191 * Called to exit the shell.
14151 */ 14192 */
14152static void 14193static void
@@ -14169,15 +14210,17 @@ exitshell(void)
14169 trap[0] = NULL; 14210 trap[0] = NULL;
14170 evalskip = 0; 14211 evalskip = 0;
14171 evalstring(p, 0); 14212 evalstring(p, 0);
14213 evalskip = SKIPFUNCDEF;
14172 /*free(p); - we'll exit soon */ 14214 /*free(p); - we'll exit soon */
14173 } 14215 }
14174 out: 14216 out:
14217 exitreset();
14175 /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}". 14218 /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
14176 * our setjobctl(0) does not panic if tcsetpgrp fails inside it. 14219 * our setjobctl(0) does not panic if tcsetpgrp fails inside it.
14177 */ 14220 */
14178 setjobctl(0); 14221 setjobctl(0);
14179 flush_stdout_stderr(); 14222 flush_stdout_stderr();
14180 _exit(savestatus); 14223 _exit(exitstatus);
14181 /* NOTREACHED */ 14224 /* NOTREACHED */
14182} 14225}
14183 14226
@@ -14337,46 +14380,6 @@ read_profile(const char *name)
14337 popfile(); 14380 popfile();
14338} 14381}
14339 14382
14340/*
14341 * This routine is called when an error or an interrupt occurs in an
14342 * interactive shell and control is returned to the main command loop
14343 * but prior to exitshell.
14344 */
14345static void
14346exitreset(void)
14347{
14348 /* from eval.c: */
14349 evalskip = 0;
14350 loopnest = 0;
14351 if (savestatus >= 0) {
14352 exitstatus = savestatus;
14353 savestatus = -1;
14354 }
14355
14356 /* from expand.c: */
14357 ifsfree();
14358
14359 /* from redir.c: */
14360 unwindredir(NULL);
14361}
14362
14363/*
14364 * This routine is called when an error or an interrupt occurs in an
14365 * interactive shell and control is returned to the main command loop.
14366 * (In dash, this function is auto-generated by build machinery).
14367 */
14368static void
14369reset(void)
14370{
14371 /* from input.c: */
14372 g_parsefile->left_in_buffer = 0;
14373 g_parsefile->left_in_line = 0; /* clear input buffer */
14374 popallfiles();
14375
14376 /* from var.c: */
14377 unwindlocalvars(NULL);
14378}
14379
14380#if PROFILE 14383#if PROFILE
14381static short profile_buf[16384]; 14384static short profile_buf[16384];
14382extern int etext(); 14385extern int etext();
@@ -14424,7 +14427,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
14424 14427
14425 e = exception_type; 14428 e = exception_type;
14426 s = state; 14429 s = state;
14427 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) { 14430 if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
14428 exitshell(); 14431 exitshell();
14429 } 14432 }
14430 14433