svn commit: r217175 - in head: bin/sh
tools/regression/bin/sh/builtins
Jilles Tjoelker
jilles at FreeBSD.org
Sat Jan 8 23:08:13 UTC 2011
Author: jilles
Date: Sat Jan 8 23:08:13 2011
New Revision: 217175
URL: http://svn.freebsd.org/changeset/base/217175
Log:
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 $?'.
Added:
head/tools/regression/bin/sh/builtins/exit3.0 (contents, props changed)
Modified:
head/bin/sh/main.c
head/bin/sh/trap.c
head/bin/sh/trap.h
Modified: head/bin/sh/main.c
==============================================================================
--- head/bin/sh/main.c Sat Jan 8 23:06:54 2011 (r217174)
+++ head/bin/sh/main.c Sat Jan 8 23:08:13 2011 (r217175)
@@ -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();
}
Modified: head/bin/sh/trap.c
==============================================================================
--- head/bin/sh/trap.c Sat Jan 8 23:06:54 2011 (r217174)
+++ head/bin/sh/trap.c Sat Jan 8 23:08:13 2011 (r217175)
@@ -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 unn
#if JOBS
setjobctl(0);
#endif
-l2: _exit(status);
+l2: _exit(exiting_exitstatus);
}
Modified: head/bin/sh/trap.h
==============================================================================
--- head/bin/sh/trap.h Sat Jan 8 23:06:54 2011 (r217174)
+++ head/bin/sh/trap.h Sat Jan 8 23:08:13 2011 (r217175)
@@ -46,3 +46,4 @@ void onsig(int);
void dotrap(void);
void setinteractive(int);
void exitshell(int) __dead2;
+void exitshell_savedstatus(void) __dead2;
Added: head/tools/regression/bin/sh/builtins/exit3.0
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/exit3.0 Sat Jan 8 23:08:13 2011 (r217175)
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+# exit without arguments differs from exit $? in an EXIT trap.
+
+trap 'false; exit' 0
More information about the svn-src-head
mailing list