1
0
Fork 0
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:
Peter Stephenson 2001-09-24 10:12:51 +00:00
parent cd59ad72b6
commit 11b0734108
3 changed files with 50 additions and 9 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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 *