fix running the ERR and EXIT traps in case of set -e and/or eval (includes Debian #696823)
This commit is contained in:
		
							
								
								
									
										96
									
								
								check.t
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								check.t
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | |||||||
| # $MirOS: src/bin/mksh/check.t,v 1.583 2013/01/01 03:32:41 tg Exp $ | # $MirOS: src/bin/mksh/check.t,v 1.584 2013/01/01 20:45:00 tg Exp $ | ||||||
| # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ | # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ | ||||||
| # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ | # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ | ||||||
| # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ | # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ | ||||||
| #- | #- | ||||||
| # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, | # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, | ||||||
| #	      2011, 2012 | #	      2011, 2012, 2013 | ||||||
| #	Thorsten Glaser <tg@mirbsd.org> | #	Thorsten Glaser <tg@mirbsd.org> | ||||||
| # | # | ||||||
| # Provided that these terms and disclaimer and all copyright notices | # Provided that these terms and disclaimer and all copyright notices | ||||||
| @@ -29,7 +29,7 @@ | |||||||
| # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD | # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD | ||||||
|  |  | ||||||
| expected-stdout: | expected-stdout: | ||||||
| 	@(#)MIRBSD KSH R41 2012/12/31 | 	@(#)MIRBSD KSH R41 2013/01/01 | ||||||
| description: | description: | ||||||
| 	Check version of shell. | 	Check version of shell. | ||||||
| stdin: | stdin: | ||||||
| @@ -38,7 +38,7 @@ name: KSH_VERSION | |||||||
| category: shell:legacy-no | category: shell:legacy-no | ||||||
| --- | --- | ||||||
| expected-stdout: | expected-stdout: | ||||||
| 	@(#)LEGACY KSH R41 2012/12/31 | 	@(#)LEGACY KSH R41 2013/01/01 | ||||||
| description: | description: | ||||||
| 	Check version of legacy shell. | 	Check version of legacy shell. | ||||||
| stdin: | stdin: | ||||||
| @@ -5821,6 +5821,94 @@ expected-stdout: | |||||||
| 	hi | 	hi | ||||||
| expected-exit: 9 | expected-exit: 9 | ||||||
| --- | --- | ||||||
|  | name: exit-trap-2 | ||||||
|  | description: | ||||||
|  | 	Check that ERR and EXIT traps are run just like ksh93 does. | ||||||
|  | 	GNU bash does not run ERtrap in eval-undef. | ||||||
|  | file-setup: file 644 "x" | ||||||
|  | 	v=; unset v | ||||||
|  | 	trap 'echo EXtrap' EXIT | ||||||
|  | 	trap 'echo ERtrap' ERR | ||||||
|  | 	set -e | ||||||
|  | 	echo "and run $1" | ||||||
|  | 	eval $1 | ||||||
|  | 	echo and out | ||||||
|  | file-setup: file 644 "xt" | ||||||
|  | 	v=; unset v | ||||||
|  | 	trap 'echo EXtrap' EXIT | ||||||
|  | 	trap 'echo ERtrap' ERR | ||||||
|  | 	set -e | ||||||
|  | 	echo 'and run true' | ||||||
|  | 	true | ||||||
|  | 	echo and out | ||||||
|  | file-setup: file 644 "xf" | ||||||
|  | 	v=; unset v | ||||||
|  | 	trap 'echo EXtrap' EXIT | ||||||
|  | 	trap 'echo ERtrap' ERR | ||||||
|  | 	set -e | ||||||
|  | 	echo 'and run false' | ||||||
|  | 	false | ||||||
|  | 	echo and out | ||||||
|  | file-setup: file 644 "xu" | ||||||
|  | 	v=; unset v | ||||||
|  | 	trap 'echo EXtrap' EXIT | ||||||
|  | 	trap 'echo ERtrap' ERR | ||||||
|  | 	set -e | ||||||
|  | 	echo 'and run ${v?}' | ||||||
|  | 	${v?} | ||||||
|  | 	echo and out | ||||||
|  | stdin: | ||||||
|  | 	runtest() { | ||||||
|  | 		rm -f rc | ||||||
|  | 		( | ||||||
|  | 			"$__progname" "$@" | ||||||
|  | 			echo $? >rc | ||||||
|  | 		) 2>&1 | sed \ | ||||||
|  | 		    -e 's/parameter not set/parameter null or not set/' \ | ||||||
|  | 		    -e 's/[[]6]//' -e 's/: eval: line 1//' -e 's/: line 6//' \ | ||||||
|  | 		    -e "s^${__progname%.exe}\.*e*x*e*: <stdin>\[[0-9]*]PROG" | ||||||
|  | 	} | ||||||
|  | 	echo : | ||||||
|  | 	runtest x true | ||||||
|  | 	echo = eval-true $(<rc) . | ||||||
|  | 	runtest x false | ||||||
|  | 	echo = eval-false $(<rc) . | ||||||
|  | 	runtest x '${v?}' | ||||||
|  | 	echo = eval-undef $(<rc) . | ||||||
|  | 	runtest xt | ||||||
|  | 	echo = noeval-true $(<rc) . | ||||||
|  | 	runtest xf | ||||||
|  | 	echo = noeval-false $(<rc) . | ||||||
|  | 	runtest xu | ||||||
|  | 	echo = noeval-undef $(<rc) . | ||||||
|  | expected-stdout: | ||||||
|  | 	: | ||||||
|  | 	and run true | ||||||
|  | 	and out | ||||||
|  | 	EXtrap | ||||||
|  | 	= eval-true 0 . | ||||||
|  | 	and run false | ||||||
|  | 	ERtrap | ||||||
|  | 	EXtrap | ||||||
|  | 	= eval-false 1 . | ||||||
|  | 	and run ${v?} | ||||||
|  | 	x: v: parameter null or not set | ||||||
|  | 	ERtrap | ||||||
|  | 	EXtrap | ||||||
|  | 	= eval-undef 1 . | ||||||
|  | 	and run true | ||||||
|  | 	and out | ||||||
|  | 	EXtrap | ||||||
|  | 	= noeval-true 0 . | ||||||
|  | 	and run false | ||||||
|  | 	ERtrap | ||||||
|  | 	EXtrap | ||||||
|  | 	= noeval-false 1 . | ||||||
|  | 	and run ${v?} | ||||||
|  | 	xu: v: parameter null or not set | ||||||
|  | 	EXtrap | ||||||
|  | 	= noeval-undef 1 . | ||||||
|  | --- | ||||||
| name: test-stlt-1 | name: test-stlt-1 | ||||||
| description: | description: | ||||||
| 	Check that test also can handle string1 < string2 etc. | 	Check that test also can handle string1 < string2 etc. | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								exec.c
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| /*- | /*- | ||||||
|  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, |  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, | ||||||
|  *		 2011, 2012 |  *		 2011, 2012, 2013 | ||||||
|  *	Thorsten Glaser <tg@mirbsd.org> |  *	Thorsten Glaser <tg@mirbsd.org> | ||||||
|  * |  * | ||||||
|  * Provided that these terms and disclaimer and all copyright notices |  * Provided that these terms and disclaimer and all copyright notices | ||||||
| @@ -23,7 +23,7 @@ | |||||||
|  |  | ||||||
| #include "sh.h" | #include "sh.h" | ||||||
|  |  | ||||||
| __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.110 2012/12/22 00:03:41 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.111 2013/01/01 20:45:02 tg Exp $"); | ||||||
|  |  | ||||||
| #ifndef MKSH_DEFAULT_EXECSHELL | #ifndef MKSH_DEFAULT_EXECSHELL | ||||||
| #define MKSH_DEFAULT_EXECSHELL	"/bin/sh" | #define MKSH_DEFAULT_EXECSHELL	"/bin/sh" | ||||||
| @@ -479,10 +479,15 @@ execute(struct op * volatile t, | |||||||
| 		unwind(LEXIT); | 		unwind(LEXIT); | ||||||
| 	if (rv != 0 && !(flags & XERROK) && | 	if (rv != 0 && !(flags & XERROK) && | ||||||
| 	    (xerrok == NULL || !*xerrok)) { | 	    (xerrok == NULL || !*xerrok)) { | ||||||
|  | 		if (Flag(FERREXIT) & 0x80) { | ||||||
|  | 			/* inside eval */ | ||||||
|  | 			Flag(FERREXIT) = 0; | ||||||
|  | 		} else { | ||||||
| 			trapsig(ksh_SIGERR); | 			trapsig(ksh_SIGERR); | ||||||
| 			if (Flag(FERREXIT)) | 			if (Flag(FERREXIT)) | ||||||
| 				unwind(LERROR); | 				unwind(LERROR); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 	return (rv); | 	return (rv); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								funcs.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								funcs.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| /*- | /*- | ||||||
|  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, |  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, | ||||||
|  *		 2010, 2011, 2012 |  *		 2010, 2011, 2012, 2013 | ||||||
|  *	Thorsten Glaser <tg@mirbsd.org> |  *	Thorsten Glaser <tg@mirbsd.org> | ||||||
|  * |  * | ||||||
|  * Provided that these terms and disclaimer and all copyright notices |  * Provided that these terms and disclaimer and all copyright notices | ||||||
| @@ -38,7 +38,7 @@ | |||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.236 2012/12/28 02:28:34 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.237 2013/01/01 20:45:02 tg Exp $"); | ||||||
|  |  | ||||||
| #if HAVE_KILLPG | #if HAVE_KILLPG | ||||||
| /* | /* | ||||||
| @@ -2216,7 +2216,7 @@ c_eval(const char **wp) | |||||||
| 	exstat |= 0x4000; | 	exstat |= 0x4000; | ||||||
|  |  | ||||||
| 	savef = Flag(FERREXIT); | 	savef = Flag(FERREXIT); | ||||||
| 	Flag(FERREXIT) = 0; | 	Flag(FERREXIT) |= 0x80; | ||||||
| 	rv = shell(s, false); | 	rv = shell(s, false); | ||||||
| 	Flag(FERREXIT) = savef; | 	Flag(FERREXIT) = savef; | ||||||
| 	source = saves; | 	source = saves; | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								main.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| /*- | /*- | ||||||
|  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, |  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, | ||||||
|  *		 2011, 2012 |  *		 2011, 2012, 2013 | ||||||
|  *	Thorsten Glaser <tg@mirbsd.org> |  *	Thorsten Glaser <tg@mirbsd.org> | ||||||
|  * |  * | ||||||
|  * Provided that these terms and disclaimer and all copyright notices |  * Provided that these terms and disclaimer and all copyright notices | ||||||
| @@ -34,7 +34,7 @@ | |||||||
| #include <locale.h> | #include <locale.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| __RCSID("$MirOS: src/bin/mksh/main.c,v 1.249 2012/12/17 23:18:07 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/main.c,v 1.250 2013/01/01 20:45:03 tg Exp $"); | ||||||
|  |  | ||||||
| extern char **environ; | extern char **environ; | ||||||
|  |  | ||||||
| @@ -873,18 +873,35 @@ void | |||||||
| unwind(int i) | unwind(int i) | ||||||
| { | { | ||||||
| 	/* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */ | 	/* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */ | ||||||
| 	if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR) && | 	if (i == LEXIT || (Flag(FERREXIT) == 1 && | ||||||
| 	    sigtraps[ksh_SIGEXIT].trap)) { | 	    (i == LERROR || i == LINTR) && sigtraps[ksh_SIGEXIT].trap)) { | ||||||
| 		++trap_nested; | 		++trap_nested; | ||||||
| 		runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1); | 		runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1); | ||||||
| 		--trap_nested; | 		--trap_nested; | ||||||
| 		i = LLEAVE; | 		i = LLEAVE; | ||||||
| 	} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) { | 	} else if (Flag(FERREXIT) == 1 && (i == LERROR || i == LINTR)) { | ||||||
| 		++trap_nested; | 		++trap_nested; | ||||||
| 		runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1); | 		runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1); | ||||||
| 		--trap_nested; | 		--trap_nested; | ||||||
| 		i = LLEAVE; | 		i = LLEAVE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * This is a kludge. We need to restore everything that was | ||||||
|  | 	 * changed in the new environment, see cid 1005090337C7A669439 | ||||||
|  | 	 * and 10050903386452ACBF1, but fail to even save things most of | ||||||
|  | 	 * the time. funcs.c:c_eval() changes FERREXIT temporarily to 0, | ||||||
|  | 	 * which needs to be restored thus (related to Debian #696823). | ||||||
|  | 	 * We did not save the shell flags, so we use a special or'd | ||||||
|  | 	 * value here... this is mostly to clean up behind *other* | ||||||
|  | 	 * callers of unwind(LERROR) here; exec.c has the regular case. | ||||||
|  | 	 */ | ||||||
|  | 	if (Flag(FERREXIT) & 0x80) { | ||||||
|  | 		/* GNU bash does not run this trapsig */ | ||||||
|  | 		trapsig(ksh_SIGERR); | ||||||
|  | 		Flag(FERREXIT) &= ~0x80; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	while (/* CONSTCOND */ 1) { | 	while (/* CONSTCOND */ 1) { | ||||||
| 		switch (e->type) { | 		switch (e->type) { | ||||||
| 		case E_PARSE: | 		case E_PARSE: | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								sh.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								sh.h
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ | |||||||
|  |  | ||||||
| /*- | /*- | ||||||
|  * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, |  * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, | ||||||
|  *	       2011, 2012 |  *	       2011, 2012, 2013 | ||||||
|  *	Thorsten Glaser <tg@mirbsd.org> |  *	Thorsten Glaser <tg@mirbsd.org> | ||||||
|  * |  * | ||||||
|  * Provided that these terms and disclaimer and all copyright notices |  * Provided that these terms and disclaimer and all copyright notices | ||||||
| @@ -164,9 +164,9 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef EXTERN | #ifdef EXTERN | ||||||
| __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.625 2013/01/01 03:32:43 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.626 2013/01/01 20:45:04 tg Exp $"); | ||||||
| #endif | #endif | ||||||
| #define MKSH_VERSION "R41 2012/12/31" | #define MKSH_VERSION "R41 2013/01/01" | ||||||
|  |  | ||||||
| /* arithmetic types: C implementation */ | /* arithmetic types: C implementation */ | ||||||
| #if !HAVE_CAN_INTTYPES | #if !HAVE_CAN_INTTYPES | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user