Skip site navigation (1)Skip section navigation (2)
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>