1 /* $NetBSD: raise_default_signal.c,v 1.2 2007/09/28 09:07:16 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Luke Mewburn. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #if HAVE_NBTOOL_CONFIG_H 40 #include "nbtool_config.h" 41 #endif 42 43 #include <sys/cdefs.h> 44 #if defined(LIBC_SCCS) && !defined(lint) 45 __RCSID("$NetBSD: raise_default_signal.c,v 1.2 2007/09/28 09:07:16 lukem Exp $"); 46 #endif 47 48 #include <errno.h> 49 #include <signal.h> 50 #include <stdio.h> 51 #include <string.h> 52 #include <util.h> 53 54 #if ! HAVE_RAISE_DEFAULT_SIGNAL 55 /* 56 * raise_default_signal sig 57 * Raise the default signal handler for sig, by 58 * - block all signals 59 * - set the signal handler to SIG_DFL 60 * - raise the signal 61 * - unblock the signal to deliver it 62 * 63 * The original signal mask and signal handler is restored on exit 64 * (whether successful or not). 65 * 66 * Returns 0 on success, or -1 on failure with errno set to 67 * on of the values for sigemptyset(), sigaddset(), sigprocmask(), 68 * sigaction(), or raise(). 69 */ 70 int 71 raise_default_signal(int sig) 72 { 73 struct sigaction origact, act; 74 sigset_t origmask, fullmask, mask; 75 int retval, oerrno; 76 77 retval = -1; 78 79 /* Setup data structures */ 80 /* XXX memset(3) isn't async-safe according to signal(7) */ 81 (void)memset(&act, 0, sizeof(act)); 82 act.sa_handler = SIG_DFL; 83 act.sa_flags = 0; 84 if ((sigemptyset(&act.sa_mask) == -1) || 85 (sigfillset(&fullmask) == -1) || 86 (sigemptyset(&mask) == -1) || 87 (sigaddset(&mask, sig) == -1)) 88 goto restore_none; 89 90 /* Block all signals */ 91 if (sigprocmask(SIG_BLOCK, &fullmask, &origmask) == -1) 92 goto restore_none; 93 /* (use 'goto restore_mask' to restore state) */ 94 95 /* Enable the SIG_DFL handler */ 96 if (sigaction(sig, &act, &origact) == -1) 97 goto restore_mask; 98 /* (use 'goto restore_act' to restore state) */ 99 100 /* Raise the signal, and unblock the signal to deliver it */ 101 if ((raise(sig) == -1) || 102 (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)) 103 goto restore_act; 104 105 /* Flag successful raise() */ 106 retval = 0; 107 108 /* Restore the original handler */ 109 restore_act: 110 oerrno = errno; 111 (void)sigaction(sig, &origact, NULL); 112 errno = oerrno; 113 114 /* Restore the original mask */ 115 restore_mask: 116 oerrno = errno; 117 (void)sigprocmask(SIG_SETMASK, &origmask, NULL); 118 errno = oerrno; 119 120 restore_none: 121 return retval; 122 } 123 124 #endif /* ! HAVE_RAISE_DEFAULT_SIGNAL */ 125