1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1996 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "signalmap.h" 30 #include <sys/signal.h> 31 #include <sys/errno.h> 32 33 extern int errno; 34 void (*handlers[32])(); /* XXX - 32??? NSIG, maybe? */ 35 36 void 37 maphandler(int sig, int code, struct sigcontext *scp, char *addr) 38 { 39 switch (sig) { 40 case SIGBUS: 41 case SIGSEGV: 42 switch (FC_CODE(code)) { 43 case 3: /* 5.x value for FC_OBJERR */ 44 code = FC_MAKE_ERR(FC_ERRNO(code)); 45 break; 46 case 5: /* 5.x value for FC_NOMAP */ 47 code = FC_NOMAP; 48 break; 49 } 50 break; 51 } 52 __sendsig(maptooldsig(sig), code, scp, addr, handlers[sig]); 53 } 54 55 void (* 56 signal(int sig, void (*a)(int)))(int) 57 { 58 int newsig; 59 60 struct sigvec osv, sv; 61 62 sv.sv_handler = a; 63 sv.sv_mask = 0; 64 #ifdef S5EMUL 65 sv.sv_flags = SV_INTERRUPT|SV_RESETHAND; 66 #else 67 sv.sv_flags = 0; 68 #endif 69 if (sigvec(sig, &sv, &osv) < 0) 70 return (BADSIG); 71 return (osv.sv_handler); 72 } 73 74 75 int 76 sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec) 77 { 78 int newsig; 79 struct sigvec tvec, *tvecp; 80 void (*oldhand)(int); 81 82 if ((int)nvec == -1 || (int)ovec == -1) { 83 errno = EFAULT; 84 return (-1); 85 } 86 87 newsig = maptonewsig(sig); 88 oldhand = handlers[newsig]; 89 90 if ((tvecp = nvec) != 0) { 91 tvec = *nvec; 92 tvecp = &tvec; 93 /* 94 * To be compatible with the behavior of SunOS 4.x: 95 * If the new signal handler is SIG_IGN or SIG_DFL, 96 * do not change the signal's entry in the handler array. 97 * This allows a child of vfork(2) to set signal handlers 98 * to SIG_IGN or SIG_DFL without affecting the parent. 99 */ 100 if (tvecp->sv_handler != SIG_DFL && 101 tvecp->sv_handler != SIG_IGN) { 102 handlers[newsig] = tvecp->sv_handler; 103 tvecp->sv_handler = maphandler; 104 } 105 } 106 107 if (ucbsigvec(newsig, tvecp, ovec) == -1) { 108 handlers[newsig] = oldhand; 109 return (-1); 110 } 111 112 if (ovec && ovec->sv_handler != SIG_DFL && ovec->sv_handler != SIG_IGN) 113 ovec->sv_handler = oldhand; 114 115 return (0); 116 } 117 118 int 119 sigsetmask(int mask) 120 { 121 int ret; 122 ret = ucbsigsetmask(maptonewmask(mask)); 123 return (maptooldmask(ret)); 124 } 125 126 int 127 sigblock(int mask) 128 { 129 int ret; 130 ret = ucbsigblock(maptonewmask(mask)); 131 return (maptooldmask(ret)); 132 } 133 134 135 int 136 sigpause(int mask) 137 { 138 int ret; 139 return (ucbsigpause(maptonewmask(mask))); 140 } 141 142 int 143 siginterrupt(int sig, int flag) 144 { 145 return (ucbsiginterrupt(maptonewsig(sig), flag)); 146 } 147 148 149 int 150 maptonewsig(int sig) 151 { 152 switch (sig) { 153 case SIGURG: /* urgent condition on IO channel */ 154 return (XSIGURG); 155 case SIGSTOP: /* sendable stop signal not from tty */ 156 return (XSIGSTOP); 157 case SIGTSTP: /* stop signal from tty */ 158 return (XSIGTSTP); 159 case SIGCONT: /* continue a stopped process */ 160 return (XSIGCONT); 161 case SIGCLD: /* System V name for SIGCHLD */ 162 return (XSIGCLD); 163 case SIGTTIN: /* to readers pgrp upon background tty read */ 164 return (XSIGTTIN); 165 case SIGTTOU: /* like TTIN for output */ 166 return (XSIGTTOU); 167 case SIGIO: /* input/output possible signal */ 168 return (XSIGIO); 169 case SIGXCPU: /* exceeded CPU time limit */ 170 return (XSIGXCPU); 171 case SIGXFSZ: /* exceeded file size limit */ 172 return (XSIGXFSZ); 173 case SIGVTALRM: /* virtual time alarm */ 174 return (XSIGVTALRM); 175 case SIGPROF: /* profiling time alarm */ 176 return (XSIGPROF); 177 case SIGWINCH: /* window changed */ 178 return (XSIGWINCH); 179 case SIGLOST: /* resource lost, not supported */ 180 return (-1); 181 case SIGUSR1: 182 return (XSIGUSR1); 183 case SIGUSR2: /* user defined signal 2 */ 184 return (XSIGUSR2); 185 default: 186 return (sig); 187 } 188 } 189 190 int 191 maptooldsig(int sig) 192 { 193 switch (sig) { 194 case XSIGURG: /* urgent condition on IO channel */ 195 return (SIGURG); 196 case XSIGSTOP: /* sendable stop signal not from tty */ 197 return (SIGSTOP); 198 case XSIGTSTP: /* stop signal from tty */ 199 return (SIGTSTP); 200 case XSIGCONT: /* continue a stopped process */ 201 return (SIGCONT); 202 case XSIGCLD: /* System V name for SIGCHLD */ 203 return (SIGCLD); 204 case XSIGTTIN: /* to readers pgrp upon background tty read */ 205 return (SIGTTIN); 206 case XSIGTTOU: /* like TTIN for output */ 207 return (SIGTTOU); 208 case XSIGIO: /* input/output possible signal */ 209 return (SIGIO); 210 case XSIGXCPU: /* exceeded CPU time limit */ 211 return (SIGXCPU); 212 case XSIGXFSZ: /* exceeded file size limit */ 213 return (SIGXFSZ); 214 case XSIGVTALRM: /* virtual time alarm */ 215 return (SIGVTALRM); 216 case XSIGPROF: /* profiling time alarm */ 217 return (SIGPROF); 218 case XSIGWINCH: /* window changed */ 219 return (SIGWINCH); 220 case XSIGUSR1: 221 return (SIGUSR1); 222 case XSIGUSR2: /* user defined signal 2 */ 223 return (SIGUSR2); 224 case XSIGPWR: /* user defined signal 2 */ 225 return (-1); 226 default: 227 return (sig); 228 } 229 } 230 231 int 232 maptooldmask(int mask) 233 { 234 int omask; 235 236 omask = mask & 0x7FFF; /* these signo are same */ 237 238 if (mask & sigmask(XSIGURG)) 239 omask |= sigmask(SIGURG); 240 if (mask & sigmask(XSIGSTOP)) 241 omask |= sigmask(SIGSTOP); 242 if (mask & sigmask(XSIGTSTP)) 243 omask |= sigmask(SIGTSTP); 244 if (mask & sigmask(XSIGCONT)) 245 omask |= sigmask(SIGCONT); 246 if (mask & sigmask(XSIGCLD)) 247 omask |= sigmask(SIGCLD); 248 if (mask & sigmask(XSIGTTIN)) 249 omask |= sigmask(SIGTTIN); 250 if (mask & sigmask(XSIGTTOU)) 251 omask |= sigmask(SIGTTOU); 252 if (mask & sigmask(XSIGIO)) 253 omask |= sigmask(SIGIO); 254 if (mask & sigmask(XSIGXCPU)) 255 omask |= sigmask(SIGXCPU); 256 if (mask & sigmask(XSIGXFSZ)) 257 omask |= sigmask(SIGXFSZ); 258 if (mask & sigmask(XSIGVTALRM)) 259 omask |= sigmask(SIGVTALRM); 260 if (mask & sigmask(XSIGPROF)) 261 omask |= sigmask(SIGPROF); 262 if (mask & sigmask(XSIGWINCH)) 263 omask |= sigmask(SIGWINCH); 264 if (mask & sigmask(XSIGUSR1)) 265 omask |= sigmask(SIGUSR1); 266 if (mask & sigmask(XSIGUSR2)) 267 omask |= sigmask(SIGUSR2); 268 return (omask); 269 } 270 271 272 int 273 maptonewmask(int omask) 274 { 275 int mask; 276 277 if (omask == -1) { 278 return (-1); 279 } 280 281 mask = omask & 0x7FFF; /* these signo are the same */ 282 283 if (omask & sigmask(SIGURG)) 284 mask |= sigmask(XSIGURG); 285 if (omask & sigmask(SIGSTOP)) 286 mask |= sigmask(XSIGSTOP); 287 if (omask & sigmask(SIGTSTP)) 288 mask |= sigmask(XSIGTSTP); 289 if (omask & sigmask(SIGCONT)) 290 mask |= sigmask(XSIGCONT); 291 if (omask & sigmask(SIGCLD)) 292 mask |= sigmask(XSIGCLD); 293 if (omask & sigmask(SIGTTIN)) 294 mask |= sigmask(XSIGTTIN); 295 if (omask & sigmask(SIGTTOU)) 296 mask |= sigmask(XSIGTTOU); 297 if (omask & sigmask(SIGIO)) 298 mask |= sigmask(XSIGIO); 299 if (omask & sigmask(SIGXCPU)) 300 mask |= sigmask(XSIGXCPU); 301 if (omask & sigmask(SIGXFSZ)) 302 mask |= sigmask(XSIGXFSZ); 303 if (omask & sigmask(SIGVTALRM)) 304 mask |= sigmask(XSIGVTALRM); 305 if (omask & sigmask(SIGPROF)) 306 mask |= sigmask(XSIGPROF); 307 if (omask & sigmask(SIGWINCH)) 308 mask |= sigmask(XSIGWINCH); 309 if (omask & sigmask(SIGUSR1)) 310 mask |= sigmask(XSIGUSR1); 311 if (omask & sigmask(SIGUSR2)) 312 mask |= sigmask(XSIGUSR2); 313 return (mask); 314 } 315