Date: Mon, 11 Nov 1996 00:59:08 +1100 From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@freefall.freebsd.org, peter@spinner.DIALix.COM Subject: Re: bin/1990 Message-ID: <199611101359.AAA09298@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
> A possible fix for the make/sh bug with SIGINT:
>
> - if (minusc) {
> + if (minusc && !eflag) {
I think this breaks the -e case in a different way. I think the shell
wait for the command to exit (even if not -c), and then:
a) if the the command was killed by a signal, exit.
b) if the exit status was nonzero, exit if -e, else continue.
c) if the exit status was 0, always continue.
This is complicated by job control and traps.
> This makes 'sh -ec' consider SIGINT as an 'error' worth aborting, and
> stops the long 'make fetch' command on ^C as it should.
> Incidently, I could find no other shells that ignored SIGINT while doing
> a 'sh -c' command.. Is this code really legitimate?? It looks like a
> gratuitous incompatability with "other" systems...
bash ignores the signal until the command completes, even without -c. So
does my version of sh. Bash seems to have similar bugs in the -e case.
Note that `fetch' catches SIGINT and exits with status 1, so the shell
has to catch signals if it wants to specially handle the case where a
signal ocurred. Here is a simpler example:
q.c
---
#include <signal.h>
void die(int s)
{
exit(1);
}
int main(void)
{
signal(SIGINT, die);
while (1)
;
}
---
shellprog:
---
#!/bin/sh
while :; do ./q; echo $?; done
---
This can be killed by exploiting the races in the loop (signals are only
masked while ./q is excecuting). There's something broken apart from
the signal handling changes for $? to be 1 and the loop to continue in
the -e case!
There seem to be some races in the code too - signals aren't masked
until after forking. However, I think the sigactions (in eval.c) are
the wrong way to do the masking. I think INTON/INTOFF are supposed to
work by trapping signals and deciding how to handle them later.
Other examples:
cat shellprog | bash -e # works correctly (aborts before echoing 1)
cat shellprog | sh -e # same
cat shellprog | bash # wants to loop for ever, even for SIGQUIT
cat shellprog | sh # same (with my version of sh)
Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611101359.AAA09298>
