mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-28 05:00:59 +01:00
* Src/builtin.c, Src/exec.c: Unwind function calls before exiting
shell from exit command to allow EXIT traps to run.
This commit is contained in:
parent
cd59ad72b6
commit
11b0734108
3 changed files with 50 additions and 9 deletions
|
|
@ -1,3 +1,8 @@
|
|||
2001-09-24 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* Src/builtin.c, Src/exec.c: Unwind function calls before exiting
|
||||
shell from exit command to allow EXIT traps to run.
|
||||
|
||||
2001-09-21 Andrew Main (Zefram) <zefram@zsh.org>
|
||||
|
||||
* Doc/Zsh/contrib.yo, Functions/Misc/tetris: Tetris game for ZLE.
|
||||
|
|
|
|||
|
|
@ -3202,6 +3202,11 @@ err:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Flag that we should exit the shell as soon as all functions return. */
|
||||
/**/
|
||||
int
|
||||
exit_pending;
|
||||
|
||||
/* break, bye, continue, exit, logout, return -- most of these take *
|
||||
* one numeric argument, and the other (logout) is related to return. *
|
||||
* (return is treated as a logout when in a login shell.) */
|
||||
|
|
@ -3248,9 +3253,21 @@ bin_break(char *name, char **argv, char *ops, int func)
|
|||
zerrnam(name, "not login shell", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
zexit(num, 0);
|
||||
break;
|
||||
/*FALLTHROUGH*/
|
||||
case BIN_EXIT:
|
||||
if (locallevel) {
|
||||
/*
|
||||
* We don't exit directly from functions to allow tidying
|
||||
* up, in particular EXIT traps. We still need to perform
|
||||
* the usual interactive tests to see if we can exit at
|
||||
* all, however.
|
||||
*/
|
||||
if (stopmsg || (zexit(0,2), !stopmsg)) {
|
||||
retflag = 1;
|
||||
breaks = loops;
|
||||
exit_pending = (num << 1) | 1;
|
||||
}
|
||||
} else
|
||||
zexit(num, 0);
|
||||
break;
|
||||
}
|
||||
|
|
@ -3290,16 +3307,19 @@ checkjobs(void)
|
|||
}
|
||||
|
||||
/* exit the shell. val is the return value of the shell. *
|
||||
* from_signal should be non-zero if zexit is being called *
|
||||
* because of a signal. */
|
||||
* from_where is
|
||||
* 1 if zexit is called because of a signal
|
||||
* 2 if we can't actually exit yet (e.g. functions need
|
||||
* terminating) but should perform the usual interactive tests.
|
||||
*/
|
||||
|
||||
/**/
|
||||
mod_export void
|
||||
zexit(int val, int from_signal)
|
||||
zexit(int val, int from_where)
|
||||
{
|
||||
static int in_exit;
|
||||
|
||||
if (isset(MONITOR) && !stopmsg && !from_signal) {
|
||||
if (isset(MONITOR) && !stopmsg && from_where != 1) {
|
||||
scanjobs(); /* check if jobs need printing */
|
||||
if (isset(CHECKJOBS))
|
||||
checkjobs(); /* check if any jobs are running/stopped */
|
||||
|
|
@ -3308,12 +3328,12 @@ zexit(int val, int from_signal)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (in_exit++ && from_signal)
|
||||
if (from_where == 2 || (in_exit++ && from_where))
|
||||
return;
|
||||
|
||||
if (isset(MONITOR)) {
|
||||
/* send SIGHUP to any jobs left running */
|
||||
killrunjobs(from_signal);
|
||||
killrunjobs(from_where == 1);
|
||||
}
|
||||
if (isset(RCS) && interact) {
|
||||
if (!nohistsave)
|
||||
|
|
|
|||
16
Src/exec.c
16
Src/exec.c
|
|
@ -3429,6 +3429,22 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval)
|
|||
if (noreturnval)
|
||||
lastval = oldlastval;
|
||||
popheap();
|
||||
|
||||
if (exit_pending) {
|
||||
if (locallevel) {
|
||||
/* Still functions to return: force them to do so. */
|
||||
retflag = 1;
|
||||
breaks = loops;
|
||||
} else {
|
||||
/*
|
||||
* All functions finished: time to exit the shell.
|
||||
* We already did the `stopmsg' test when the
|
||||
* exit command was handled.
|
||||
*/
|
||||
stopmsg = 1;
|
||||
zexit(exit_pending >> 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This finally executes a shell function and any function wrappers *
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue