Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions doc/es.1
Original file line number Diff line number Diff line change
Expand Up @@ -1773,18 +1773,11 @@ A signal prefixed by a slash
.Rc ( / )
is ignored in the current shell, but retains default behavior in
child processes.
In addition, the signal
.Cr sigint
may be preceded by the prefix
.Rc ( . )
to indicate that normal shell interrupt processing
(i.e., the printing of an extra newline)
occurs.
By default
.I es
starts up with the values
.Ds
.Cr ".sigint /sigquit /sigterm"
.Cr "sigint /sigquit /sigterm"
.De
.TP
\&
Expand Down
4 changes: 2 additions & 2 deletions es.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ extern char *sigmessage(int sig);

#define SIGCHK() sigchk()
typedef enum {
sig_nochange, sig_catch, sig_default, sig_ignore, sig_noop, sig_special
sig_nochange, sig_catch, sig_default, sig_ignore, sig_noop
} Sigeffect;
extern Sigeffect esignal(int sig, Sigeffect effect);
extern void setsigeffects(const Sigeffect effects[]);
Expand All @@ -350,13 +350,13 @@ extern List *mksiglist(void);
extern void initsignals(Boolean interactive, Boolean allowdumps);
extern Atomic slow;
extern sigjmp_buf slowlabel;
extern Boolean sigint_newline;
extern void sigchk(void);
extern Boolean issilentsignal(List *e);
extern void exitonsignal(List *e);
extern void setsigdefaults(void);
extern void blocksignals(void);
extern void unblocksignals(void);
extern void clearsignal(int sig);


/* open.c */
Expand Down
9 changes: 3 additions & 6 deletions eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ extern List *forkexec(char *file, List *list, Boolean inchild) {
}
gcenable();
status = ewaitfor(pid);
if ((status & 0xff) == 0) {
sigint_newline = FALSE;
SIGCHK();
sigint_newline = TRUE;
} else
SIGCHK();
if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGINT)
clearsignal(SIGINT);
SIGCHK();
printstatus(0, status);
return mklist(mkterm(mkstatus(status), NULL), NULL);
}
Expand Down
4 changes: 3 additions & 1 deletion initial.es
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,9 @@ fn %interactive-loop {
echo >[1=2] $msg
$fn-%dispatch false
} {~ $e signal} {
if {!~ $type sigint sigterm sigquit} {
if {~ $type sigint sigtstp sigquit} {
echo # this is the newline for (^C ^Z ^\)
} {!~ $type sigterm} {
echo >[1=2] caught unexpected signal: $type
}
} {
Expand Down
1 change: 0 additions & 1 deletion prim-sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ PRIM(setsignals) {
switch (*s) {
case '-': effect = sig_ignore; s++; break;
case '/': effect = sig_noop; s++; break;
case '.': effect = sig_special; s++; break;
}
sig = signumber(s);
if (sig < 0)
Expand Down
29 changes: 9 additions & 20 deletions signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

typedef void (*Sighandler)(int);

Boolean sigint_newline = TRUE;

static Atomic sigcount;
static Atomic caught[NSIG];
static Sigeffect sigeffect[NSIG];
Expand Down Expand Up @@ -124,12 +122,6 @@ extern Sigeffect esignal(int sig, Sigeffect effect) {
return old;
}
break;
case sig_special:
if (sig != SIGINT) {
eprint("$&setsignals: special handler not defined for %s\n", signame(sig));
return old;
}
FALLTHROUGH;
case sig_catch:
if (setsignal(sig, catcher) == SIG_ERR) {
eprint("$&setsignals: cannot catch %s\n", signame(sig));
Expand Down Expand Up @@ -196,7 +188,7 @@ extern void initsignals(Boolean interactive, Boolean allowdumps) {
}

if (interactive || sigeffect[SIGINT] == sig_default)
esignal(SIGINT, sig_special);
esignal(SIGINT, sig_catch);
if (!allowdumps) {
if (interactive)
esignal(SIGTERM, sig_noop);
Expand All @@ -214,7 +206,7 @@ extern void setsigdefaults(void) {
int sig;
for (sig = 1; sig < NSIG; sig++) {
Sigeffect e = sigeffect[sig];
if (e == sig_catch || e == sig_noop || e == sig_special)
if (e == sig_catch || e == sig_noop)
esignal(sig, sig_default);
}
}
Expand Down Expand Up @@ -247,6 +239,13 @@ extern void exitonsignal(List *exception) {
esignal(sig, e);
}

extern void clearsignal(int sig) {
if (caught[sig]) {
caught[sig] = FALSE;
--sigcount;
}
}

extern List *mksiglist(void) {
int sig = NSIG;
Sigeffect effects[NSIG];
Expand All @@ -260,7 +259,6 @@ extern List *mksiglist(void) {
case sig_catch: prefix = '\0'; break;
case sig_ignore: prefix = '-'; break;
case sig_noop: prefix = '/'; break;
case sig_special: prefix = '.'; break;
}
Ref(char *, name, signame(sig));
if (prefix != '\0')
Expand Down Expand Up @@ -322,15 +320,6 @@ extern void sigchk(void) {
while (gcisblocked())
gcenable();
throw(e);
case sig_special:
assert(sig == SIGINT);
/* this is the newline you see when you hit ^C while typing a command */
if (sigint_newline)
eprint("\n");
sigint_newline = TRUE;
while (gcisblocked())
gcenable();
throw(e);
case sig_noop:
break;
default:
Expand Down
8 changes: 4 additions & 4 deletions test/tests/trip.es
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ never succeeded
}

test 'signals in exception catchers' {
local (signals = sigint) {
local (signals = sigterm) {
let (
was-blocked = false
thrown = ()
Expand All @@ -169,7 +169,7 @@ test 'signals in exception catchers' {
thrown = $*
} {
catch @ e {
kill -INT $pid
kill -TERM $pid
was-blocked = true
} {
throw exception
Expand All @@ -182,15 +182,15 @@ test 'signals in exception catchers' {
catch @ {
thrown = $*
} {
catch @ e {kill -INT $pid} {throw exception}
catch @ e {kill -TERM $pid} {throw exception}
}
assert {~ $thrown(1) signal} second signal is caught
}
let (thrown = ()) {
catch @ {
thrown = $*
} {
catch @ e {kill -INT $pid; throw exception} {throw exception}
catch @ e {kill -TERM $pid; throw exception} {throw exception}
}
assert {~ $thrown(1) signal} signal exception has precedence within catcher
}
Expand Down