change behaviour of argument-less exit in traps to match SUSv4; Debian #599484 (original patch from Jonathan Nieder, thanks!) in a variant that appears to handle nested traps well
This commit is contained in:
parent
e57379aab7
commit
27dce9168a
14
check.t
14
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.395 2010/10/01 19:04:37 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.396 2010/11/01 17:29:00 tg 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: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||
@ -25,7 +25,7 @@
|
||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R39 2010/10/01
|
||||
@(#)MIRBSD KSH R39 2010/11/01
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
@ -4845,6 +4845,16 @@ expected-stdout:
|
||||
E 0
|
||||
F 0
|
||||
---
|
||||
name: exit-trap-1
|
||||
description:
|
||||
Check that "exit" with no arguments behaves SUSv4 conformant.
|
||||
stdin:
|
||||
trap 'echo hi; exit' EXIT
|
||||
exit 9
|
||||
expected-stdout:
|
||||
hi
|
||||
expected-exit: 9
|
||||
---
|
||||
name: test-stlt-1
|
||||
description:
|
||||
Check that test also can handle string1 < string2 etc.
|
||||
|
5
funcs.c
5
funcs.c
@ -25,7 +25,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.163 2010/09/15 21:08:18 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.164 2010/11/01 17:29:02 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
/*
|
||||
@ -2293,7 +2293,8 @@ c_exitreturn(const char **wp)
|
||||
warningf(true, "%s: %s", arg, "bad number");
|
||||
} else
|
||||
exstat = n;
|
||||
}
|
||||
} else if (trap_exstat != -1)
|
||||
exstat = trap_exstat;
|
||||
if (wp[0][0] == 'r') { /* return */
|
||||
struct env *ep;
|
||||
|
||||
|
43
histrap.c
43
histrap.c
@ -26,7 +26,7 @@
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.102 2010/09/14 21:26:13 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.103 2010/11/01 17:29:03 tg Exp $");
|
||||
|
||||
/*-
|
||||
* MirOS: This is the default mapping type, and need not be specified.
|
||||
@ -1066,6 +1066,8 @@ inittraps(void)
|
||||
int i;
|
||||
const char *cs;
|
||||
|
||||
trap_exstat = -1;
|
||||
|
||||
/* Populate sigtraps based on sys_signame and sys_siglist. */
|
||||
for (i = 0; i <= NSIG; i++) {
|
||||
sigtraps[i].signal = i;
|
||||
@ -1271,22 +1273,29 @@ runtraps(int flag)
|
||||
intrsig = 0;
|
||||
if (flag & TF_FATAL)
|
||||
fatal_trap = 0;
|
||||
++trap_nested;
|
||||
for (p = sigtraps, i = NSIG+1; --i >= 0; p++)
|
||||
if (p->set && (!flag ||
|
||||
((p->flags & flag) && p->trap == NULL)))
|
||||
runtrap(p);
|
||||
runtrap(p, false);
|
||||
if (!--trap_nested)
|
||||
runtrap(NULL, true);
|
||||
}
|
||||
|
||||
void
|
||||
runtrap(Trap *p)
|
||||
runtrap(Trap *p, bool is_last)
|
||||
{
|
||||
int i = p->signal;
|
||||
char *trapstr = p->trap;
|
||||
int oexstat;
|
||||
int old_changed = 0;
|
||||
int old_changed = 0, i;
|
||||
char *trapstr;
|
||||
|
||||
if (p == NULL)
|
||||
/* just clean up, see runtraps() above */
|
||||
goto donetrap;
|
||||
i = p->signal;
|
||||
trapstr = p->trap;
|
||||
p->set = 0;
|
||||
if (trapstr == NULL) { /* SIG_DFL */
|
||||
if (trapstr == NULL) {
|
||||
/* SIG_DFL */
|
||||
if (p->flags & TF_FATAL) {
|
||||
/* eg, SIGHUP */
|
||||
exstat = 128 + i;
|
||||
@ -1297,22 +1306,23 @@ runtrap(Trap *p)
|
||||
exstat = 128 + i;
|
||||
unwind(LINTR);
|
||||
}
|
||||
return;
|
||||
goto donetrap;
|
||||
}
|
||||
if (trapstr[0] == '\0') /* SIG_IGN */
|
||||
return;
|
||||
if (trapstr[0] == '\0')
|
||||
/* SIG_IGN */
|
||||
goto donetrap;
|
||||
if (i == SIGEXIT_ || i == SIGERR_) { /* avoid recursion on these */
|
||||
old_changed = p->flags & TF_CHANGED;
|
||||
p->flags &= ~TF_CHANGED;
|
||||
p->trap = NULL;
|
||||
}
|
||||
oexstat = exstat;
|
||||
if (trap_exstat == -1)
|
||||
trap_exstat = exstat;
|
||||
/*
|
||||
* Note: trapstr is fully parsed before anything is executed, thus
|
||||
* no problem with afree(p->trap) in settrap() while still in use.
|
||||
*/
|
||||
command(trapstr, current_lineno);
|
||||
exstat = oexstat;
|
||||
if (i == SIGEXIT_ || i == SIGERR_) {
|
||||
if (p->flags & TF_CHANGED)
|
||||
/* don't clear TF_CHANGED */
|
||||
@ -1321,6 +1331,13 @@ runtrap(Trap *p)
|
||||
p->trap = trapstr;
|
||||
p->flags |= old_changed;
|
||||
}
|
||||
|
||||
donetrap:
|
||||
/* we're the last trap of a sequence executed */
|
||||
if (is_last && trap_exstat != -1) {
|
||||
exstat = trap_exstat;
|
||||
trap_exstat = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear pending traps and reset user's trap handlers; used after fork(2) */
|
||||
|
10
main.c
10
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.172 2010/09/14 21:26:14 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.173 2010/11/01 17:29:04 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -672,10 +672,14 @@ unwind(int i)
|
||||
/* 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) &&
|
||||
sigtraps[SIGEXIT_].trap)) {
|
||||
runtrap(&sigtraps[SIGEXIT_]);
|
||||
++trap_nested;
|
||||
runtrap(&sigtraps[SIGEXIT_], trap_nested == 1);
|
||||
--trap_nested;
|
||||
i = LLEAVE;
|
||||
} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) {
|
||||
runtrap(&sigtraps[SIGERR_]);
|
||||
++trap_nested;
|
||||
runtrap(&sigtraps[SIGERR_], trap_nested == 1);
|
||||
--trap_nested;
|
||||
i = LLEAVE;
|
||||
}
|
||||
while (1) {
|
||||
|
10
sh.h
10
sh.h
@ -154,9 +154,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.418 2010/10/08 17:56:57 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.419 2010/11/01 17:29:05 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R39 2010/10/01"
|
||||
#define MKSH_VERSION "R39 2010/11/01"
|
||||
|
||||
#ifndef MKSH_INCLUDES_ONLY
|
||||
|
||||
@ -584,6 +584,8 @@ EXTERN struct mksh_kshstate_v {
|
||||
int exstat_; /* exit status */
|
||||
int subst_exstat_; /* exit status of last $(..)/`..` */
|
||||
struct env env_; /* top-level parsing & execution env. */
|
||||
short trap_exstat_; /* exit status before running a trap */
|
||||
uint8_t trap_nested_; /* running nested traps */
|
||||
uint8_t shell_flags_[FNFLAGS];
|
||||
} kshstate_v;
|
||||
EXTERN struct mksh_kshstate_f {
|
||||
@ -602,6 +604,8 @@ EXTERN struct mksh_kshstate_f {
|
||||
#define kshppid kshstate_f.kshppid_
|
||||
#define exstat kshstate_v.exstat_
|
||||
#define subst_exstat kshstate_v.subst_exstat_
|
||||
#define trap_exstat kshstate_v.trap_exstat_
|
||||
#define trap_nested kshstate_v.trap_nested_
|
||||
|
||||
/* evil hack: return hash(kshstate_f concat (kshstate_f'.h:=hash(arg))) */
|
||||
uint32_t evilhash(const char *);
|
||||
@ -1526,7 +1530,7 @@ void intrcheck(void);
|
||||
int fatal_trap_check(void);
|
||||
int trap_pending(void);
|
||||
void runtraps(int intr);
|
||||
void runtrap(Trap *);
|
||||
void runtrap(Trap *, bool);
|
||||
void cleartraps(void);
|
||||
void restoresigs(void);
|
||||
void settrap(Trap *, const char *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user