1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Copyright (c) 1989, 1993 25 * The Regents of the University of California. All rights reserved. 26 * 27 * Redistribution and use in source and binary forms, with or without 28 * modification, are permitted provided that the following conditions 29 * are met: 30 * 1. Redistributions of source code must retain the above copyright 31 * notice, this list of conditions and the following disclaimer. 32 * 2. Redistributions in binary form must reproduce the above copyright 33 * notice, this list of conditions and the following disclaimer in the 34 * documentation and/or other materials provided with the distribution. 35 * 3. All advertising materials mentioning features or use of this software 36 * must display the following acknowledgement: 37 * This product includes software developed by the University of 38 * California, Berkeley and its contributors. 39 * 4. Neither the name of the University nor the names of its contributors 40 * may be used to endorse or promote products derived from this software 41 * without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 * SUCH DAMAGE. 54 */ 55 56#if __DARWIN_UNIX03 57#ifdef VARIANT_CANCELABLE 58#include <pthread.h> 59#endif /* VARIANT_CANCELABLE */ 60extern int __unix_conforming; 61#endif /* __DARWIN_UNIX03 */ 62 63#include <sys/param.h> 64#include <signal.h> 65#include <errno.h> 66 67#ifndef BUILDING_VARIANT 68#if defined(__DYNAMIC__) 69extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv); 70extern int _sigvec_nobind (int, struct sigvec *, struct sigvec *); 71#endif 72 73static int 74sigvec__(int signo, 75 struct sigvec *sv, 76 struct sigvec *osv, 77 int bind) 78{ 79 int ret; 80 81 if (sv) 82 sv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ 83#if defined(__DYNAMIC__) 84 if (bind) { 85#endif 86 ret = sigaction(signo, (struct sigaction *)sv, (struct sigaction *)osv); 87#if defined(__DYNAMIC__) 88 } else { 89 ret = _sigaction_nobind(signo, (struct sigaction *)sv, (struct sigaction *)osv); 90 } 91#endif 92 if (ret == 0 && osv) 93 osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ 94 return (ret); 95} 96 97int 98sigvec(int signo, 99 struct sigvec *sv, 100 struct sigvec *osv) 101{ 102 return sigvec__(signo, sv, osv, 1); 103} 104 105#if defined(__DYNAMIC__) 106int 107_sigvec_nobind(int signo, 108 struct sigvec *sv, 109 struct sigvec *osv) 110{ 111 return sigvec__(signo, sv, osv, 0); 112} 113#endif 114 115int 116sigsetmask(int mask) 117{ 118 int omask, n; 119 120 n = sigprocmask(SIG_SETMASK, (sigset_t *) &mask, (sigset_t *) &omask); 121 if (n) 122 return (n); 123 return (omask); 124} 125 126int 127sigblock(int mask) 128{ 129 int omask, n; 130 131 n = sigprocmask(SIG_BLOCK, (sigset_t *) &mask, (sigset_t *) &omask); 132 if (n) 133 return (n); 134 return (omask); 135} 136#endif /* !BUILDING_VARIANT */ 137 138#if __DARWIN_UNIX03 139int 140sigpause(int sig) 141{ 142 sigset_t mask; 143 144 if (__unix_conforming == 0) 145 __unix_conforming = 1; 146#ifdef VARIANT_CANCELABLE 147 pthread_testcancel(); 148#endif /* VARIANT_CANCELABLE */ 149 150 if ((sig <= 0) || (sig >= NSIG)) { 151 errno = EINVAL; 152 return(-1); 153 } 154 if (sigprocmask(SIG_BLOCK, (sigset_t *) 0, (sigset_t *) &mask) < 0) { 155 return(-1); 156 } 157 sigdelset(&mask, sig); 158 return (sigsuspend(&mask)); 159} 160#else 161int 162sigpause(int mask) 163{ 164 return (sigsuspend((sigset_t *)&mask)); 165} 166#endif /* __DARWIN_UNIX03 */ 167 168#ifndef BUILDING_VARIANT 169int 170sighold(int sig) 171{ 172 sigset_t mask; 173 174 if ((sig <= 0) || (sig >= NSIG)) { 175 errno = EINVAL; 176 return(-1); 177 } 178 sigemptyset(&mask); 179 sigaddset(&mask, sig); 180 return(sigprocmask(SIG_BLOCK, &mask,(sigset_t *)0)); 181} 182 183int 184sigrelse(int sig) 185{ 186 sigset_t mask; 187 188 if ((sig <= 0) || (sig >= NSIG)) { 189 errno = EINVAL; 190 return(-1); 191 } 192 sigemptyset(&mask); 193 sigaddset(&mask, sig); 194 return(sigprocmask(SIG_UNBLOCK, &mask,(sigset_t *)0)); 195} 196 197 198int 199sigignore(int sig) 200{ 201 return (signal(sig, SIG_IGN) == SIG_ERR ? -1 : 0); 202} 203 204void (*sigset(int sig, void (*disp)(int)))(int) { 205 sigset_t omask; 206 int blocked; 207 struct sigaction oact; 208 209 if ((sig <= 0) || (sig >= NSIG)) { 210 errno = EINVAL; 211 return (SIG_ERR); 212 } 213 if (-1 == sigprocmask(0, NULL, &omask)) 214 return (SIG_ERR); 215 blocked = sigismember(&omask, sig); 216 if (disp == SIG_HOLD) { 217 if (blocked) 218 return (SIG_HOLD); 219 if ((-1 == sigaction(sig, NULL, &oact)) || 220 (-1 == sighold(sig))) 221 return (SIG_ERR); 222 return (sig_t)oact.sa_handler; 223 } else { 224 if (blocked) { 225 if (-1 == sigrelse(sig)) 226 return (SIG_ERR); 227 } 228 sig_t rv = signal(sig, disp); 229 if (rv != SIG_ERR) 230 return blocked ? SIG_HOLD : rv; 231 else 232 return (rv); 233 } 234} 235#endif /* !BUILDING_VARIANT */ 236