Subject: Re: Sane exit from a program on receipt of a signal
To: Luke Mewburn <lukem@NetBSD.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-userlevel
Date: 07/20/2007 10:29:15
On Jul 20, 10:59am, lukem@NetBSD.org (Luke Mewburn) wrote:
-- Subject: Re: Sane exit from a program on receipt of a signal

| As der Mouse pointed out, this function could be useful for
| raising the default handler for signals that don't terminate
| the process (e.g, SIGTSTP).  As such, I'll leave it to the
| caller to invoke raise_default_unblock() and then explicitly
| exit depending upon the caller's needs.
| 
| 
| I've attached my second attempt.
| 
| Look ok?
| Put in libutil? (or somewhere else?)
| 

Try to restore things on failure?

christos

#include <signal.h>
#include <stdio.h>
#include <string.h>

int
raise_default_unblock(int sig)
{
	struct sigaction act, oact;
	sigset_t mask, omask;
	int oerrno;

	/* Setup structures to use */
	(void)memset(&act, 0, sizeof(act));
	if ((sigemptyset(&act.sa_mask) == -1) ||
	    (sigemptyset(&mask) == -1) ||
	    (sigaddset(&mask, sig) == -1))
		return -1;

	/* Restore signal handling to default */
	act.sa_handler = SIG_DFL;
	act.as_flags = 0;
	if (sigaction(sig, &act, &oact) == -1) 
		return -1;

	/* Unblock the signal */
	if (sigprocmask(SIG_UNBLOCK, &mask, &omask) == -1)
		goto out;

	/* Deliver the signal */
	if (raise(sig) != -1)
		return 0;

	oerrno = errno;
	(void)sigprocmask(SIG_SETMASK, &omask, NULL);
	errno = oerrno;
out:
	oerrno = errno;
	(void)sigaction(sig, &oact, NULL);
	errno = oerrno;
	return -1;
}