System V and SIGCLD

Chris Torek chris at umcp-cs.UUCP
Tue Oct 7 02:14:44 AEST 1986


>Bob Lenk writes:
>>Also, the precise semantics of how SIGCLD is "queued" do not agree
>>between System V documentation and implementation, so there could be
>>disagreement on what to standardize.

In article <2410003 at nucsrl.UUCP> naim at nucsrl.UUCP (Naim Abdullah) writes:
>Could you explain this a little bit further?  In what way, does the
>implementation differ from the documentation?

We have been through this one before.  I have neither SysV source
nor SysV documentation, but I believe my understanding to be correct.
At any rate, no one has proved this wrong:

The SysV documentation claims that SIGCLD is queued---that is, if
two children of a given process die `simultaneously', that that
process will receive two separate SIGCLDs.  The documentation is
wrong.  The signal is not queued.  However, any program handling
SIGCLD via the `recommended method' will indeed receive two SIGCLDs.

Three details are important to understanding this.  First, whenever
a signal is delivered in a SysV kernel, the signal disposition is
changed to SIG_DFL.  (This means that holding down one's interrupt
key will, unless the machine is stupendously fast, eventually kill
a program no matter how hard it tries to avoid this.  This and
other similar arguments are what is behind the Berkeley Reliable
Signals, which are, alas, thoroughly incompatible with previous
systems.)  Second, when the SIGCLD disposition is SIG_DFL, a SysV
kernel does nothing special: an exiting child remains exiting.
Third, and this is the key, whenever the SIGCLD disposition is
altered to SIG_CATCH---that is, to a catching routine---a SysV kernel
scans for exiting chilren.  If there are any, it sends exactly one
SIGCLD signal.  This, of course, alters the disposition back to
SIG_DFL, and the loop runs until there are no more children.

That this is indeed the implementation may be demonstrated by
running a small test program:

	#include <signal.h>

	catch()
	{
		int status;

		/* if the wait() is done before the signal(), this works. */
		(void) signal(SIGCLD, catch);
		(void) wait(&status);
	}

	main()
	{

		(void) signal(SIGCLD, catch);
		if (fork())
			_exit(1);
		exit(0);
	}

This program will eventually run out of stack space.

(It is true that there are other potential SIGCLD implementations
that might show the same behaviour.  But the one I outlined above
is a trivial change to a V7 kernel, and I do not doubt that those
who wrote the code followed the path of least resistance.)

I believe that signal queueing would in fact be a better solution
than either Berkeley Reliable Signals, which model machine interrupts
rather closely, or the SysV style SIGCLD signal.  Both work for
this specific case, though Berkeley did have to add a three-argument
`wait' syscall.  Berkeley's solution is more general than SysV's,
and I think it is therefore better, but it does seem to have `kludge
for acceptable efficiency' stamped all over it.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris at umcp-cs		ARPA:	chris at mimsy.umd.edu



More information about the Comp.unix.wizards mailing list