Subject: Re: Sane exit from a program on receipt of a signal
To: Christos Zoulas <christos@zoulas.com>
From: Luke Mewburn <lukem@NetBSD.org>
List: tech-userlevel
Date: 07/25/2007 16:46:15
--SvyA5ywaG/v2A5dH
Content-Type: multipart/mixed; boundary="3loezlmesXOUD0D5"
Content-Disposition: inline


--3loezlmesXOUD0D5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Jul 20, 2007 at 10:29:15AM -0400, Christos Zoulas wrote:
  | Try to restore things on failure?

I've thought about that, and I'm not convinced that we need to.

Here's a minor rewrite of my 2nd attempt, based on some
feedback I received privately from a friend.
Changes:

 * Highlight that memset() isn't technically async safe per signal(7).
   I thought about removing it entirely, but as you & I chatted
   privately, memset() should be safe. (why wouldn't it be??)
   I want to avoid C99 features to zero it.
   The function should be portable to other platforms,
   which means we shouldn't assume BSD extensions like
   sigaction.sa_sigaction are present to explicitly zero.
   OTOH, autoconf can solve that problem :)

 * (Temporarily) block the signal whilst we set the default handler.

 * Raise the signal and then unblock it.

I've also renamed it to 'raise_default_signal()'



--3loezlmesXOUD0D5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="raise_default.c"

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

int
raise_default_signal(int sig)
{
	struct sigaction act;
	sigset_t mask;

		/* Block the signal */
	if ((sigemptyset(&mask) == -1) ||
	    (sigaddset(&mask, sig) == -1) ||
	    (sigprocmask(SIG_BLOCK, &mask, NULL) == -1))
		return -1;

		/* Setup default handler */
	memset(&act, 0, sizeof(&act));	/* XXX not async safe per signal(7) */
	act.sa_handler = SIG_DFL;
	act.sa_flags = 0;
	if (sigemptyset(&act.sa_mask) == -1)
		return -1;

		/* Restore the default handler, raise the signal */
	if ((sigaction(sig, &act, NULL) == -1) ||
	    (raise(sig) == -1))
		return -1;

		/* Unblock the signal */
	if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
		return -1;

	return 0;
}

--3loezlmesXOUD0D5--

--SvyA5ywaG/v2A5dH
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (NetBSD)

iD8DBQFGpvG3pBhtmn8zJHIRAh3rAJ9wdlqI8hCLuyY38fcNANkYRs2QZACeJKGw
91febrQhRkKv8heE9g0Nhfg=
=Ayrl
-----END PGP SIGNATURE-----

--SvyA5ywaG/v2A5dH--