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: 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 $
|
||||||
@ -25,7 +25,7 @@
|
|||||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R39 2010/10/01
|
@(#)MIRBSD KSH R39 2010/11/01
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -4845,6 +4845,16 @@ expected-stdout:
|
|||||||
E 0
|
E 0
|
||||||
F 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
|
name: test-stlt-1
|
||||||
description:
|
description:
|
||||||
Check that test also can handle string1 < string2 etc.
|
Check that test also can handle string1 < string2 etc.
|
||||||
|
5
funcs.c
5
funcs.c
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -2293,7 +2293,8 @@ c_exitreturn(const char **wp)
|
|||||||
warningf(true, "%s: %s", arg, "bad number");
|
warningf(true, "%s: %s", arg, "bad number");
|
||||||
} else
|
} else
|
||||||
exstat = n;
|
exstat = n;
|
||||||
}
|
} else if (trap_exstat != -1)
|
||||||
|
exstat = trap_exstat;
|
||||||
if (wp[0][0] == 'r') { /* return */
|
if (wp[0][0] == 'r') { /* return */
|
||||||
struct env *ep;
|
struct env *ep;
|
||||||
|
|
||||||
|
43
histrap.c
43
histrap.c
@ -26,7 +26,7 @@
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#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.
|
* MirOS: This is the default mapping type, and need not be specified.
|
||||||
@ -1066,6 +1066,8 @@ inittraps(void)
|
|||||||
int i;
|
int i;
|
||||||
const char *cs;
|
const char *cs;
|
||||||
|
|
||||||
|
trap_exstat = -1;
|
||||||
|
|
||||||
/* Populate sigtraps based on sys_signame and sys_siglist. */
|
/* Populate sigtraps based on sys_signame and sys_siglist. */
|
||||||
for (i = 0; i <= NSIG; i++) {
|
for (i = 0; i <= NSIG; i++) {
|
||||||
sigtraps[i].signal = i;
|
sigtraps[i].signal = i;
|
||||||
@ -1271,22 +1273,29 @@ runtraps(int flag)
|
|||||||
intrsig = 0;
|
intrsig = 0;
|
||||||
if (flag & TF_FATAL)
|
if (flag & TF_FATAL)
|
||||||
fatal_trap = 0;
|
fatal_trap = 0;
|
||||||
|
++trap_nested;
|
||||||
for (p = sigtraps, i = NSIG+1; --i >= 0; p++)
|
for (p = sigtraps, i = NSIG+1; --i >= 0; p++)
|
||||||
if (p->set && (!flag ||
|
if (p->set && (!flag ||
|
||||||
((p->flags & flag) && p->trap == NULL)))
|
((p->flags & flag) && p->trap == NULL)))
|
||||||
runtrap(p);
|
runtrap(p, false);
|
||||||
|
if (!--trap_nested)
|
||||||
|
runtrap(NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
runtrap(Trap *p)
|
runtrap(Trap *p, bool is_last)
|
||||||
{
|
{
|
||||||
int i = p->signal;
|
int old_changed = 0, i;
|
||||||
char *trapstr = p->trap;
|
char *trapstr;
|
||||||
int oexstat;
|
|
||||||
int old_changed = 0;
|
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
/* just clean up, see runtraps() above */
|
||||||
|
goto donetrap;
|
||||||
|
i = p->signal;
|
||||||
|
trapstr = p->trap;
|
||||||
p->set = 0;
|
p->set = 0;
|
||||||
if (trapstr == NULL) { /* SIG_DFL */
|
if (trapstr == NULL) {
|
||||||
|
/* SIG_DFL */
|
||||||
if (p->flags & TF_FATAL) {
|
if (p->flags & TF_FATAL) {
|
||||||
/* eg, SIGHUP */
|
/* eg, SIGHUP */
|
||||||
exstat = 128 + i;
|
exstat = 128 + i;
|
||||||
@ -1297,22 +1306,23 @@ runtrap(Trap *p)
|
|||||||
exstat = 128 + i;
|
exstat = 128 + i;
|
||||||
unwind(LINTR);
|
unwind(LINTR);
|
||||||
}
|
}
|
||||||
return;
|
goto donetrap;
|
||||||
}
|
}
|
||||||
if (trapstr[0] == '\0') /* SIG_IGN */
|
if (trapstr[0] == '\0')
|
||||||
return;
|
/* SIG_IGN */
|
||||||
|
goto donetrap;
|
||||||
if (i == SIGEXIT_ || i == SIGERR_) { /* avoid recursion on these */
|
if (i == SIGEXIT_ || i == SIGERR_) { /* avoid recursion on these */
|
||||||
old_changed = p->flags & TF_CHANGED;
|
old_changed = p->flags & TF_CHANGED;
|
||||||
p->flags &= ~TF_CHANGED;
|
p->flags &= ~TF_CHANGED;
|
||||||
p->trap = NULL;
|
p->trap = NULL;
|
||||||
}
|
}
|
||||||
oexstat = exstat;
|
if (trap_exstat == -1)
|
||||||
|
trap_exstat = exstat;
|
||||||
/*
|
/*
|
||||||
* Note: trapstr is fully parsed before anything is executed, thus
|
* Note: trapstr is fully parsed before anything is executed, thus
|
||||||
* no problem with afree(p->trap) in settrap() while still in use.
|
* no problem with afree(p->trap) in settrap() while still in use.
|
||||||
*/
|
*/
|
||||||
command(trapstr, current_lineno);
|
command(trapstr, current_lineno);
|
||||||
exstat = oexstat;
|
|
||||||
if (i == SIGEXIT_ || i == SIGERR_) {
|
if (i == SIGEXIT_ || i == SIGERR_) {
|
||||||
if (p->flags & TF_CHANGED)
|
if (p->flags & TF_CHANGED)
|
||||||
/* don't clear TF_CHANGED */
|
/* don't clear TF_CHANGED */
|
||||||
@ -1321,6 +1331,13 @@ runtrap(Trap *p)
|
|||||||
p->trap = trapstr;
|
p->trap = trapstr;
|
||||||
p->flags |= old_changed;
|
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) */
|
/* 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>
|
#include <locale.h>
|
||||||
#endif
|
#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;
|
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) */
|
/* 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) && (i == LERROR || i == LINTR) &&
|
||||||
sigtraps[SIGEXIT_].trap)) {
|
sigtraps[SIGEXIT_].trap)) {
|
||||||
runtrap(&sigtraps[SIGEXIT_]);
|
++trap_nested;
|
||||||
|
runtrap(&sigtraps[SIGEXIT_], trap_nested == 1);
|
||||||
|
--trap_nested;
|
||||||
i = LLEAVE;
|
i = LLEAVE;
|
||||||
} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) {
|
} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) {
|
||||||
runtrap(&sigtraps[SIGERR_]);
|
++trap_nested;
|
||||||
|
runtrap(&sigtraps[SIGERR_], trap_nested == 1);
|
||||||
|
--trap_nested;
|
||||||
i = LLEAVE;
|
i = LLEAVE;
|
||||||
}
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
|
10
sh.h
10
sh.h
@ -154,9 +154,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#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
|
#endif
|
||||||
#define MKSH_VERSION "R39 2010/10/01"
|
#define MKSH_VERSION "R39 2010/11/01"
|
||||||
|
|
||||||
#ifndef MKSH_INCLUDES_ONLY
|
#ifndef MKSH_INCLUDES_ONLY
|
||||||
|
|
||||||
@ -584,6 +584,8 @@ EXTERN struct mksh_kshstate_v {
|
|||||||
int exstat_; /* exit status */
|
int exstat_; /* exit status */
|
||||||
int subst_exstat_; /* exit status of last $(..)/`..` */
|
int subst_exstat_; /* exit status of last $(..)/`..` */
|
||||||
struct env env_; /* top-level parsing & execution env. */
|
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];
|
uint8_t shell_flags_[FNFLAGS];
|
||||||
} kshstate_v;
|
} kshstate_v;
|
||||||
EXTERN struct mksh_kshstate_f {
|
EXTERN struct mksh_kshstate_f {
|
||||||
@ -602,6 +604,8 @@ EXTERN struct mksh_kshstate_f {
|
|||||||
#define kshppid kshstate_f.kshppid_
|
#define kshppid kshstate_f.kshppid_
|
||||||
#define exstat kshstate_v.exstat_
|
#define exstat kshstate_v.exstat_
|
||||||
#define subst_exstat kshstate_v.subst_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))) */
|
/* evil hack: return hash(kshstate_f concat (kshstate_f'.h:=hash(arg))) */
|
||||||
uint32_t evilhash(const char *);
|
uint32_t evilhash(const char *);
|
||||||
@ -1526,7 +1530,7 @@ void intrcheck(void);
|
|||||||
int fatal_trap_check(void);
|
int fatal_trap_check(void);
|
||||||
int trap_pending(void);
|
int trap_pending(void);
|
||||||
void runtraps(int intr);
|
void runtraps(int intr);
|
||||||
void runtrap(Trap *);
|
void runtrap(Trap *, bool);
|
||||||
void cleartraps(void);
|
void cleartraps(void);
|
||||||
void restoresigs(void);
|
void restoresigs(void);
|
||||||
void settrap(Trap *, const char *);
|
void settrap(Trap *, const char *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user