diff options
-rw-r--r-- | shell/ash.c | 99 |
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 | */ | ||
14154 | static void | ||
14155 | exitreset(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 | */ | ||
14178 | static void | ||
14179 | reset(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 | */ |
14152 | static void | 14193 | static 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 | */ | ||
14345 | static void | ||
14346 | exitreset(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 | */ | ||
14368 | static void | ||
14369 | reset(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 |
14381 | static short profile_buf[16384]; | 14384 | static short profile_buf[16384]; |
14382 | extern int etext(); | 14385 | extern 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 | ||