[comp.unix.wizards] Are signals safe during longjmp?

mangler@cit-vax.Caltech.Edu (Don Speck) (12/27/87)

I have a signal-catch routine where it would be handy to tell
the outside world that it's ready for another signal just before
doing a longjmp out of the signal routine, instead of doing it
in the mainline code after the longjmp has occurred.  Of course,
this raises the possibility of the following events:

a)  Receive a second signal before leaving the signal routine.
    Is there any Unix variant in which multiple occurances of
    the same signal may not "stack"?

b)  Receive a signal during the longjmp.  During a longjmp, is
    the stack guaranteed to be consistent enough for signal
    catching, i.e. about as consistent as in the midst of a
    function return?  The signal catch routine would only
    check a global flag (telling it not to do anything) and
    set a global flag of its own.  Is there any Unix variant
    in which this is not safe?	Will it trash the stack?

Perhaps the code will make it clearer:

jmp_buf jbuf;
int ready, caught;

catch() {
    /*	signal(SIGTRAP, catch);     /* (not reset when caught - unneeded) */
	caught++;
	if (!ready)	/* longjmp'ing, or prerequisite work not finished */
		return;
	ready = caught = 0;
	/* do some work whose response time is important */
	kill(otherprocess, SIGTRAP);
	/* other process will do its urgent work, and send back a SIGTRAP */
	/* meanwhile we go back to mainline code and get ready */
	/* there are no live local variables anywhere at this point */
	longjmp(jbuf, 1);
}

caller() {
	signal(SIGTRAP, catch);
	while (!eof) {
		/* do some prerequisite work */
		/* we may or may not get a signal during this work */
		if (setjmp(jbuf) == 0) {
			/* indicate that we're ready to act on the signal */
			ready++;
			while (!caught)
				pause();
			catch();
			/*NOTREACHED*/
		}
	}
}

Can I do this on all Unixes?  (i.e. not just those with signal masking)?

Don Speck   speck@vlsi.caltech.edu  {amdahl,scgvaxd}!cit-vax!speck