use _setjmp/_longjmp on NeXTstep: its Intel port always restores the signal mask on siglongjmp, which we never have

This commit is contained in:
tg 2012-03-31 17:30:00 +00:00
parent 86c4ea4619
commit e67b98e21b
5 changed files with 67 additions and 69 deletions

20
exec.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.96 2011/09/07 15:24:14 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.97 2012/03/31 17:29:58 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -234,8 +234,7 @@ execute(struct op * volatile t,
*/
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
e->type = E_ERRH;
i = sigsetjmp(e->jbuf, 0);
if (i) {
if ((i = kshsetjmp(e->jbuf))) {
sigprocmask(SIG_SETMASK, &omask, NULL);
quitenv(NULL);
unwind(i);
@ -337,10 +336,7 @@ execute(struct op * volatile t,
(const char **)eval((const char **)t->vars,
DOBLANK | DOGLOB | DOTILDE);
e->type = E_LOOP;
while (/* CONSTCOND */ 1) {
i = sigsetjmp(e->jbuf, 0);
if (!i)
break;
while ((i = kshsetjmp(e->jbuf))) {
if ((e->flags&EF_BRKCONT_PASS) ||
(i != LBREAK && i != LCONTIN)) {
quitenv(NULL);
@ -375,10 +371,7 @@ execute(struct op * volatile t,
case TWHILE:
case TUNTIL:
e->type = E_LOOP;
while (/* CONSTCOND */ 1) {
i = sigsetjmp(e->jbuf, 0);
if (!i)
break;
while ((i = kshsetjmp(e->jbuf))) {
if ((e->flags&EF_BRKCONT_PASS) ||
(i != LBREAK && i != LCONTIN)) {
quitenv(NULL);
@ -733,8 +726,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
tp->flag |= FINUSE;
e->type = E_FUNC;
i = sigsetjmp(e->jbuf, 0);
if (i == 0) {
if (!(i = kshsetjmp(e->jbuf))) {
/* seems odd to pass XERROK here, but AT&T ksh does */
exstat = execute(tp->val.t, flags & XERROK, xerrok);
i = LRETURN;
@ -1424,7 +1416,7 @@ hereinval(const char *content, int sub, char **resbuf, struct shf *shf)
osource = source;
newenv(E_ERRH);
if (sigsetjmp(e->jbuf, 0)) {
if (kshsetjmp(e->jbuf)) {
source = osource;
quitenv(shf);
/* special to iosetup(): don't print error */

5
expr.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.54 2012/03/29 19:22:58 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.55 2012/03/31 17:29:59 tg Exp $");
/* The order of these enums is constrained by the order of opinfo[] */
enum token {
@ -199,8 +199,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
curstate.natural = false;
newenv(E_ERRH);
i = sigsetjmp(e->jbuf, 0);
if (i) {
if ((i = kshsetjmp(e->jbuf))) {
/* Clear EXPRINEVAL in of any variables we were playing with */
if (curstate.evaling)
curstate.evaling->flag &= ~EXPRINEVAL;

4
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.159 2012/03/29 19:23:00 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.160 2012/03/31 17:29:59 tg Exp $");
/*
* states while lexing word
@ -1514,7 +1514,7 @@ set_prompt(int to, Source *s)
ps1 = shf_sclose(shf);
saved_atemp = ATEMP;
newenv(E_ERRH);
if (sigsetjmp(e->jbuf, 0)) {
if (kshsetjmp(e->jbuf)) {
prompt = safe_prompt;
/*
* Don't print an error - assume it has already

89
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.213 2012/03/31 17:08:52 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.214 2012/03/31 17:30:00 tg Exp $");
extern char **environ;
@ -652,8 +652,7 @@ include(const char *name, int argc, const char **argv, int intr_ok)
old_argc = 0;
}
newenv(E_INCL);
i = sigsetjmp(e->jbuf, 0);
if (i) {
if ((i = kshsetjmp(e->jbuf))) {
quitenv(s ? s->u.shf : NULL);
if (old_argv) {
e->loc->argv = old_argv;
@ -728,49 +727,47 @@ shell(Source * volatile s, volatile int toplevel)
newenv(E_PARSE);
if (interactive)
really_exit = 0;
i = sigsetjmp(e->jbuf, 0);
if (i) {
switch (i) {
case LINTR:
/* we get here if SIGINT not caught or ignored */
case LERROR:
case LSHELL:
if (interactive) {
if (i == LINTR)
shellf("\n");
/*
* Reset any eof that was read as part of a
* multiline command.
*/
if (Flag(FIGNOREEOF) && s->type == SEOF &&
wastty)
s->type = SSTDIN;
/*
* Used by exit command to get back to
* top level shell. Kind of strange since
* interactive is set if we are reading from
* a tty, but to have stopped jobs, one only
* needs FMONITOR set (not FTALKING/SF_TTY)...
*/
/* toss any input we have so far */
s->start = s->str = null;
break;
}
/* FALLTHROUGH */
case LEXIT:
case LLEAVE:
case LRETURN:
source = old_source;
quitenv(NULL);
/* keep on going */
unwind(i);
/* NOTREACHED */
default:
source = old_source;
quitenv(NULL);
internal_errorf("%s %d", "shell", i);
/* NOTREACHED */
switch ((i = kshsetjmp(e->jbuf))) {
case 0:
break;
case LINTR:
/* we get here if SIGINT not caught or ignored */
case LERROR:
case LSHELL:
if (interactive) {
if (i == LINTR)
shellf("\n");
/*
* Reset any eof that was read as part of a
* multiline command.
*/
if (Flag(FIGNOREEOF) && s->type == SEOF && wastty)
s->type = SSTDIN;
/*
* Used by exit command to get back to
* top level shell. Kind of strange since
* interactive is set if we are reading from
* a tty, but to have stopped jobs, one only
* needs FMONITOR set (not FTALKING/SF_TTY)...
*/
/* toss any input we have so far */
s->start = s->str = null;
break;
}
/* FALLTHROUGH */
case LEXIT:
case LLEAVE:
case LRETURN:
source = old_source;
quitenv(NULL);
/* keep on going */
unwind(i);
/* NOTREACHED */
default:
source = old_source;
quitenv(NULL);
internal_errorf("%s %d", "shell", i);
/* NOTREACHED */
}
while (/* CONSTCOND */ 1) {
if (trap)
@ -845,7 +842,7 @@ unwind(int i)
case E_INCL:
case E_LOOP:
case E_ERRH:
siglongjmp(e->jbuf, i);
kshlongjmp(e->jbuf, i);
/* NOTREACHED */
case E_NONE:
if (i == LINTR)

18
sh.h
View File

@ -152,7 +152,7 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.538 2012/03/29 19:23:01 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.539 2012/03/31 17:30:00 tg Exp $");
#endif
#define MKSH_VERSION "R40 2012/03/29"
@ -582,6 +582,16 @@ enum sh_flag {
/*
* parsing & execution environment
*/
#if defined(NeXT) && !defined(__GLIBC__)
#define kshjmp_buf jmp_buf
#define kshsetjmp(jbuf) _setjmp(jbuf)
#define kshlongjmp _longjmp
#else
#define kshjmp_buf sigjmp_buf
#define kshsetjmp(jbuf) sigsetjmp((jbuf), 0)
#define kshlongjmp siglongjmp
#endif
extern struct env {
ALLOC_ITEM alloc_INT; /* internal, do not touch */
Area area; /* temporary allocation area */
@ -589,7 +599,7 @@ extern struct env {
struct block *loc; /* local variables and functions */
short *savefd; /* original redirected fds */
struct temp *temps; /* temp files */
sigjmp_buf jbuf; /* long jump back to env creator */
kshjmp_buf jbuf; /* long jump back to env creator */
uint8_t type; /* environment type - see below */
uint8_t flags; /* EF_* */
} *e;
@ -615,7 +625,7 @@ extern struct env {
/* Do returns stop at env type e? */
#define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL)
/* values for siglongjmp(e->jbuf, 0) */
/* values for kshlongjmp(e->jbuf, i) */
#define LRETURN 1 /* return statement */
#define LEXIT 2 /* exit statement */
#define LERROR 3 /* errorf() called */
@ -898,7 +908,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24); /* tty lines */
/* Used by v_evaluate() and setstr() to control action when error occurs */
#define KSH_UNWIND_ERROR 0 /* unwind the stack (longjmp) */
#define KSH_UNWIND_ERROR 0 /* unwind the stack (kshlongjmp) */
#define KSH_RETURN_ERROR 1 /* return 1/0 for success/failure */
/*