diff options
author | Jilles Tjoelker <jilles@FreeBSD.org> | 2011-01-08 23:08:13 +0000 |
---|---|---|
committer | Jilles Tjoelker <jilles@FreeBSD.org> | 2011-01-08 23:08:13 +0000 |
commit | 70df11eaada12be76a93d0e7459a144c269ca1e9 (patch) | |
tree | 84939e2426e96e9045071ec8b0ff19c67e89c0c7 /bin | |
parent | a67b22d67f22790238a6b077c356f936053e7b7d (diff) | |
download | src-70df11eaada12be76a93d0e7459a144c269ca1e9.tar.gz src-70df11eaada12be76a93d0e7459a144c269ca1e9.zip |
sh: Make exit without parameters from EXIT trap POSIX-compliant.
It should use the original exit status, just like falling off the
end of the trap handler.
Outside an EXIT trap, 'exit' is still equivalent to 'exit $?'.
Notes
Notes:
svn path=/head/; revision=217175
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/main.c | 7 | ||||
-rw-r--r-- | bin/sh/trap.c | 18 | ||||
-rw-r--r-- | bin/sh/trap.h | 1 |
3 files changed, 19 insertions, 7 deletions
diff --git a/bin/sh/main.c b/bin/sh/main.c index 9298f696545d..88483b03d952 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -341,10 +341,7 @@ exitcmd(int argc, char **argv) if (stoppedjobs()) return 0; if (argc > 1) - exitstatus = number(argv[1]); + exitshell(number(argv[1])); else - exitstatus = oexitstatus; - exitshell(exitstatus); - /*NOTREACHED*/ - return 0; + exitshell_savedstatus(); } diff --git a/bin/sh/trap.c b/bin/sh/trap.c index e673ef685a3d..921e3f652abc 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -80,6 +80,9 @@ static volatile sig_atomic_t gotsig[NSIG]; static int ignore_sigchld; /* Used while handling SIGCHLD traps. */ volatile sig_atomic_t gotwinch; +static int exiting; /* exitshell() has been called */ +static int exiting_exitstatus; /* value passed to exitshell() */ + static int getsigaction(int, sig_t *); @@ -478,10 +481,21 @@ setinteractive(int on) void exitshell(int status) { + TRACE(("exitshell(%d) pid=%d\n", status, getpid())); + exiting = 1; + exiting_exitstatus = status; + exitshell_savedstatus(); +} + +void +exitshell_savedstatus(void) +{ struct jmploc loc1, loc2; char *p; - TRACE(("exitshell(%d) pid=%d\n", status, getpid())); + if (!exiting) + exiting_exitstatus = oexitstatus; + exitstatus = oexitstatus = exiting_exitstatus; if (setjmp(loc1.loc)) { goto l1; } @@ -498,5 +512,5 @@ l1: handler = &loc2; /* probably unnecessary */ #if JOBS setjobctl(0); #endif -l2: _exit(status); +l2: _exit(exiting_exitstatus); } diff --git a/bin/sh/trap.h b/bin/sh/trap.h index 8cc05da54dee..d8686ceaadde 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -46,3 +46,4 @@ void onsig(int); void dotrap(void); void setinteractive(int); void exitshell(int) __dead2; +void exitshell_savedstatus(void) __dead2; |