Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Feb 1998 22:10:44 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, cracauer@cons.org
Cc:        cracauer@FreeBSD.ORG, cvs-all@FreeBSD.ORG, cvs-bin@FreeBSD.ORG, cvs-committers@FreeBSD.ORG
Subject:   Re: cvs commit: src/bin/sh jobs.c
Message-ID:  <199802071110.WAA04970@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> 1) SIGINT/SIGQUIT are not restored after fork failure.
>
>That just needs 
>        if (oldsigs_valid) {
>               signal(SIGQUIT,oldsigquit);
>               signal(SIGINT,oldsigint);
>               oldsigs_valid = 0;
>        }
>in the (pid == -1) clause.

It also needs spaces after commas and uncorrupted tabs.

>> 2) SIGINT/SIGQUIT are always reset to SIG_DFL in the child.  This is
>>    wrong if these signals are ignored on entry to the shell.
>
>Under what circumstances will a child be entered with ignored signals?

Whenever the shell was started with ignored signals, and when the shell
is told to ignore signals using `trap'.

>One use I can think of is spawning subshells in a shellscript. If
>signals are always resetted to default, subshells will be exited at
>once and the whole shellscript will be terminated on one. This is also
>what bash and pdksh do. So below for an example.

I think the main use is for running process trees with SIGHUP ignored.
This is not so useful for SIGINT/SIGQUIT/SIGTERM, but still right.  It
would be surprising for subprocesses to reset to SIG_DFL just because
they are created by a shell.  I don't believe that bash or pdksh get
this wrong.

>Two test cases where your and my solutions differ:
>
>1)
>  #!/usr/src/bin/sh.work/sh 
>  emacs -nw
>  while `true` ; do foo=1 ; done
>
>After emacs exits, your version exits the loop only on SIGINT. SIGQUIT
>and SIGTERM are ignored. My solution exits on all three signals.

My version doesn't work because onsig() only forwards SIGINT to onint().
Other caught signals are effectively ignored unless they have a trap
handler.  The INTOFF/INTON stuff only controls SIGINT.

Some bugs are easier to reproduce if the emacs command is removed and
`true` is replaced by ":" so that more time is spent setting foo:

1a)
#!obj/sh 
while : ; do foo=1 ; done

Killing this with ^C often yields:

	sh in malloc(): warning: recursive call.

This is an old bug.  onintr() calls outstr("\n") to clean up
the output after the tty driver echos ^C.  outstr() calls malloc().
It is not OK to call malloc() from a signal handler.  phkmalloc detects
the problem and prints the warning if malloc() was active when the
signal occurred (this happens almost half the time for (1a) on one of my
systems).  It returns 0 immediately.  outstr() actually uses ckmalloc().
ckmalloc() calls error() when malloc() returns 0.  error() calls outstr()
which calls malloc()...

1b)
#!obj/sh
trap '' 2
while : ; do foo=1 ; done

This seems to work incorrectly with both sh and bash-1.  ^C correctly
doesn't kill it, but neither does ^\ or SIGTERM.  ^Z and SIGHUP work.

>2) 
>#!/usr/src/bin/sh.work/sh 
>(
>    (
>        emacs -nw
>        while `true` ; do foo=1 ; done
>    )
>    while `true` ; do foo=1 ; done
>)
>while `true` ; do foo=1 ; done
>
>After exiting emacs, my version drops out of all subshells and
>terminate the whole script on one SIGINT, which I think is the right
>thing to do. Your version needs three to exit the script. As I said,
>bash and pdksh need only one as well.

I agree that terminating on one SIGINT is right.  The different
behaviour seems to have something to do with the handling of exit
statuses from the children.  bash doesn't exit either for:

2a)
#!/usr/local/bin/bash
while : ; do catch2 ; echo $?; done

where catch2 exits with a non-signal status when it catches SIGINT.
It takes several SIGINTs to kill this - apparently SIGINTs are
effectively ignored if they occur while the child is alive.

>And your version ignores both SIGQUIT and SIGTERM, which probably
>isn't intended.

It wasn't intended, but gives the same behaviour as bash.  My version
actually catches them and then ignores them (unless they are trapped).

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802071110.WAA04970>