1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 5891 raf * Common Development and Distribution License (the "License"). 6 5891 raf * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 5891 raf 22 0 stevel /* 23 5891 raf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 28 0 stevel 29 6812 raf #pragma weak _signal = signal 30 6812 raf #pragma weak _sighold = sighold 31 6812 raf #pragma weak _sigrelse = sigrelse 32 6812 raf #pragma weak _sigignore = sigignore 33 6812 raf #pragma weak _sigset = sigset 34 0 stevel 35 6812 raf #include "lint.h" 36 0 stevel #include <sys/types.h> 37 0 stevel #include <unistd.h> 38 0 stevel #include <errno.h> 39 0 stevel #include <signal.h> 40 0 stevel #include <wait.h> 41 0 stevel 42 0 stevel /* 43 0 stevel * Check for valid signal number as per SVID. 44 0 stevel */ 45 0 stevel #define CHECK_SIG(s, code) \ 46 0 stevel if ((s) <= 0 || (s) >= NSIG || (s) == SIGKILL || (s) == SIGSTOP) { \ 47 0 stevel errno = EINVAL; \ 48 0 stevel return (code); \ 49 0 stevel } 50 0 stevel 51 0 stevel /* 52 0 stevel * Equivalent to stopdefault set in the kernel implementation (sig.c). 53 0 stevel */ 54 0 stevel #define STOPDEFAULT(s) \ 55 0 stevel ((s) == SIGSTOP || (s) == SIGTSTP || (s) == SIGTTOU || (s) == SIGTTIN) 56 0 stevel 57 0 stevel 58 0 stevel /* 59 0 stevel * SVr3.x signal compatibility routines. They are now 60 0 stevel * implemented as library routines instead of system 61 0 stevel * calls. 62 0 stevel */ 63 0 stevel 64 0 stevel void(* 65 0 stevel signal(int sig, void(*func)(int)))(int) 66 0 stevel { 67 0 stevel struct sigaction nact; 68 0 stevel struct sigaction oact; 69 0 stevel 70 0 stevel CHECK_SIG(sig, SIG_ERR); 71 0 stevel 72 0 stevel nact.sa_handler = func; 73 0 stevel nact.sa_flags = SA_RESETHAND|SA_NODEFER; 74 0 stevel (void) sigemptyset(&nact.sa_mask); 75 0 stevel 76 0 stevel /* 77 0 stevel * Pay special attention if sig is SIGCHLD and 78 0 stevel * the disposition is SIG_IGN, per sysV signal man page. 79 0 stevel */ 80 0 stevel if (sig == SIGCHLD) { 81 0 stevel nact.sa_flags |= SA_NOCLDSTOP; 82 0 stevel if (func == SIG_IGN) 83 0 stevel nact.sa_flags |= SA_NOCLDWAIT; 84 0 stevel } 85 0 stevel 86 0 stevel if (STOPDEFAULT(sig)) 87 0 stevel nact.sa_flags |= SA_RESTART; 88 0 stevel 89 0 stevel if (sigaction(sig, &nact, &oact) < 0) 90 0 stevel return (SIG_ERR); 91 0 stevel 92 0 stevel return (oact.sa_handler); 93 0 stevel } 94 0 stevel 95 0 stevel int 96 0 stevel sighold(int sig) 97 0 stevel { 98 0 stevel sigset_t set; 99 0 stevel 100 0 stevel CHECK_SIG(sig, -1); 101 0 stevel 102 0 stevel /* 103 0 stevel * errno set on failure by either sigaddset or sigprocmask. 104 0 stevel */ 105 0 stevel (void) sigemptyset(&set); 106 0 stevel if (sigaddset(&set, sig) < 0) 107 0 stevel return (-1); 108 0 stevel return (sigprocmask(SIG_BLOCK, &set, (sigset_t *)0)); 109 0 stevel } 110 0 stevel 111 0 stevel int 112 0 stevel sigrelse(int sig) 113 0 stevel { 114 0 stevel sigset_t set; 115 0 stevel 116 0 stevel CHECK_SIG(sig, -1); 117 0 stevel 118 0 stevel /* 119 0 stevel * errno set on failure by either sigaddset or sigprocmask. 120 0 stevel */ 121 0 stevel (void) sigemptyset(&set); 122 0 stevel if (sigaddset(&set, sig) < 0) 123 0 stevel return (-1); 124 0 stevel return (sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)0)); 125 0 stevel } 126 0 stevel 127 0 stevel int 128 0 stevel sigignore(int sig) 129 0 stevel { 130 0 stevel struct sigaction act; 131 0 stevel sigset_t set; 132 0 stevel 133 0 stevel CHECK_SIG(sig, -1); 134 0 stevel 135 0 stevel act.sa_handler = SIG_IGN; 136 0 stevel act.sa_flags = 0; 137 0 stevel (void) sigemptyset(&act.sa_mask); 138 0 stevel 139 0 stevel /* 140 0 stevel * Pay special attention if sig is SIGCHLD and 141 0 stevel * the disposition is SIG_IGN, per sysV signal man page. 142 0 stevel */ 143 0 stevel if (sig == SIGCHLD) { 144 0 stevel act.sa_flags |= SA_NOCLDSTOP; 145 0 stevel act.sa_flags |= SA_NOCLDWAIT; 146 0 stevel } 147 0 stevel 148 0 stevel if (STOPDEFAULT(sig)) 149 0 stevel act.sa_flags |= SA_RESTART; 150 0 stevel 151 0 stevel if (sigaction(sig, &act, (struct sigaction *)0) < 0) 152 0 stevel return (-1); 153 0 stevel 154 0 stevel (void) sigemptyset(&set); 155 0 stevel if (sigaddset(&set, sig) < 0) 156 0 stevel return (-1); 157 0 stevel return (sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)0)); 158 0 stevel } 159 0 stevel 160 0 stevel int 161 5891 raf __sigpause(int sig) 162 0 stevel { 163 0 stevel sigset_t set; 164 0 stevel int rval; 165 0 stevel 166 0 stevel CHECK_SIG(sig, -1); 167 0 stevel 168 0 stevel /* 169 0 stevel * sigpause() is defined to unblock the signal 170 0 stevel * and not block it again on return. 171 0 stevel * sigsuspend() restores the original signal set, 172 0 stevel * so we have to unblock sig overtly. 173 0 stevel */ 174 0 stevel (void) sigprocmask(0, (sigset_t *)0, &set); 175 0 stevel if (sigdelset(&set, sig) < 0) 176 0 stevel return (-1); 177 0 stevel rval = sigsuspend(&set); 178 0 stevel (void) sigrelse(sig); 179 0 stevel return (rval); 180 0 stevel } 181 0 stevel 182 0 stevel void(* 183 0 stevel sigset(int sig, void(*func)(int)))(int) 184 0 stevel { 185 0 stevel struct sigaction nact; 186 0 stevel struct sigaction oact; 187 0 stevel sigset_t nset; 188 0 stevel sigset_t oset; 189 0 stevel int code; 190 0 stevel 191 0 stevel CHECK_SIG(sig, SIG_ERR); 192 0 stevel 193 0 stevel (void) sigemptyset(&nset); 194 0 stevel if (sigaddset(&nset, sig) < 0) 195 0 stevel return (SIG_ERR); 196 0 stevel 197 0 stevel if (func == SIG_HOLD) { 198 0 stevel if (sigprocmask(SIG_BLOCK, &nset, &oset) < 0) 199 0 stevel return (SIG_ERR); 200 0 stevel if (sigaction(sig, (struct sigaction *)0, &oact) < 0) 201 0 stevel return (SIG_ERR); 202 0 stevel } else { 203 0 stevel nact.sa_handler = func; 204 0 stevel nact.sa_flags = 0; 205 0 stevel (void) sigemptyset(&nact.sa_mask); 206 0 stevel /* 207 0 stevel * Pay special attention if sig is SIGCHLD and 208 0 stevel * the disposition is SIG_IGN, per sysV signal man page. 209 0 stevel */ 210 0 stevel if (sig == SIGCHLD) { 211 0 stevel nact.sa_flags |= SA_NOCLDSTOP; 212 0 stevel if (func == SIG_IGN) 213 0 stevel nact.sa_flags |= SA_NOCLDWAIT; 214 0 stevel } 215 0 stevel 216 0 stevel if (STOPDEFAULT(sig)) 217 0 stevel nact.sa_flags |= SA_RESTART; 218 0 stevel 219 0 stevel if (sigaction(sig, &nact, &oact) < 0) 220 0 stevel return (SIG_ERR); 221 0 stevel 222 0 stevel if (sigprocmask(SIG_UNBLOCK, &nset, &oset) < 0) 223 0 stevel return (SIG_ERR); 224 0 stevel } 225 0 stevel 226 0 stevel if ((code = sigismember(&oset, sig)) < 0) 227 0 stevel return (SIG_ERR); 228 0 stevel else if (code == 1) 229 0 stevel return (SIG_HOLD); 230 0 stevel 231 0 stevel return (oact.sa_handler); 232 0 stevel } 233