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" /* SVr4.0 1.2 */ 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 maphandler(sig, code, scp, addr) 37 int sig, code; 38 struct sigcontext *scp; 39 char *addr; 40 { 41 switch (sig) { 42 case SIGBUS: 43 case SIGSEGV: 44 switch (FC_CODE(code)) { 45 case 3: /* 5.x value for FC_OBJERR */ 46 code = FC_MAKE_ERR(FC_ERRNO(code)); 47 break; 48 case 5: /* 5.x value for FC_NOMAP */ 49 code = FC_NOMAP; 50 break; 51 } 52 break; 53 } 54 __sendsig(maptooldsig(sig), code, scp, addr, handlers[sig]); 55 } 56 57 void (*signal(sig, a))() 58 int sig; 59 void (*a)(); 60 { 61 int newsig; 62 63 struct sigvec osv, sv; 64 65 sv.sv_handler = a; 66 sv.sv_mask = 0; 67 #ifdef S5EMUL 68 sv.sv_flags = SV_INTERRUPT|SV_RESETHAND; 69 #else 70 sv.sv_flags = 0; 71 #endif 72 if (sigvec(sig, &sv, &osv) < 0) 73 return (BADSIG); 74 return (osv.sv_handler); 75 } 76 77 78 sigvec(sig, nvec, ovec) 79 int sig; 80 struct sigvec *nvec, *ovec; 81 { 82 int newsig; 83 struct sigvec tvec, *tvecp; 84 void (*oldhand)(); 85 86 if ((int)nvec == -1 || (int)ovec == -1) { 87 errno = EFAULT; 88 return (-1); 89 } 90 91 newsig = maptonewsig(sig); 92 oldhand = handlers[newsig]; 93 94 if ((tvecp = nvec) != 0) { 95 tvec = *nvec; 96 tvecp = &tvec; 97 /* 98 * To be compatible with the behavior of SunOS 4.x: 99 * If the new signal handler is SIG_IGN or SIG_DFL, 100 * do not change the signal's entry in the handler array. 101 * This allows a child of vfork(2) to set signal handlers 102 * to SIG_IGN or SIG_DFL without affecting the parent. 103 */ 104 if (tvecp->sv_handler != SIG_DFL && 105 tvecp->sv_handler != SIG_IGN) { 106 handlers[newsig] = tvecp->sv_handler; 107 tvecp->sv_handler = maphandler; 108 } 109 } 110 111 if (ucbsigvec(newsig, tvecp, ovec) == -1) { 112 handlers[newsig] = oldhand; 113 return (-1); 114 } 115 116 if (ovec && ovec->sv_handler != SIG_DFL && ovec->sv_handler != SIG_IGN) 117 ovec->sv_handler = oldhand; 118 119 return (0); 120 } 121 122 sigsetmask(mask) 123 int mask; 124 { 125 int ret; 126 ret = ucbsigsetmask(maptonewmask(mask)); 127 return(maptooldmask(ret)); 128 } 129 130 sigblock(mask) 131 int mask; 132 { 133 int ret; 134 ret = ucbsigblock(maptonewmask(mask)); 135 return(maptooldmask(ret)); 136 } 137 138 139 int sigpause(mask) 140 int mask; 141 { 142 int ret; 143 return(ucbsigpause(maptonewmask(mask))); 144 } 145 146 siginterrupt(sig, flag) 147 int sig, flag; 148 { 149 return(ucbsiginterrupt(maptonewsig(sig), flag)); 150 } 151 152 153 maptonewsig(sig) 154 int sig; 155 { 156 switch (sig) { 157 case SIGURG: /* urgent condition on IO channel */ 158 return(XSIGURG); 159 case SIGSTOP: /* sendable stop signal not from tty */ 160 return(XSIGSTOP); 161 case SIGTSTP: /* stop signal from tty */ 162 return(XSIGTSTP); 163 case SIGCONT: /* continue a stopped process */ 164 return(XSIGCONT); 165 case SIGCLD: /* System V name for SIGCHLD */ 166 return(XSIGCLD); 167 case SIGTTIN: /* to readers pgrp upon background tty read */ 168 return(XSIGTTIN); 169 case SIGTTOU: /* like TTIN for output */ 170 return(XSIGTTOU); 171 case SIGIO: /* input/output possible signal */ 172 return(XSIGIO); 173 case SIGXCPU: /* exceeded CPU time limit */ 174 return(XSIGXCPU); 175 case SIGXFSZ: /* exceeded file size limit */ 176 return(XSIGXFSZ); 177 case SIGVTALRM: /* virtual time alarm */ 178 return(XSIGVTALRM); 179 case SIGPROF: /* profiling time alarm */ 180 return(XSIGPROF); 181 case SIGWINCH: /* window changed */ 182 return(XSIGWINCH); 183 case SIGLOST: /* resource lost, not supported */ 184 return(-1); 185 case SIGUSR1: 186 return(XSIGUSR1); 187 case SIGUSR2: /* user defined signal 2 */ 188 return(XSIGUSR2); 189 default: 190 return(sig); 191 } 192 } 193 194 195 maptooldsig(sig) 196 int sig; 197 { 198 switch (sig) { 199 case XSIGURG: /* urgent condition on IO channel */ 200 return(SIGURG); 201 case XSIGSTOP: /* sendable stop signal not from tty */ 202 return(SIGSTOP); 203 case XSIGTSTP: /* stop signal from tty */ 204 return(SIGTSTP); 205 case XSIGCONT: /* continue a stopped process */ 206 return(SIGCONT); 207 case XSIGCLD: /* System V name for SIGCHLD */ 208 return(SIGCLD); 209 case XSIGTTIN: /* to readers pgrp upon background tty read */ 210 return(SIGTTIN); 211 case XSIGTTOU: /* like TTIN for output */ 212 return(SIGTTOU); 213 case XSIGIO: /* input/output possible signal */ 214 return(SIGIO); 215 case XSIGXCPU: /* exceeded CPU time limit */ 216 return(SIGXCPU); 217 case XSIGXFSZ: /* exceeded file size limit */ 218 return(SIGXFSZ); 219 case XSIGVTALRM: /* virtual time alarm */ 220 return(SIGVTALRM); 221 case XSIGPROF: /* profiling time alarm */ 222 return(SIGPROF); 223 case XSIGWINCH: /* window changed */ 224 return(SIGWINCH); 225 case XSIGUSR1: 226 return(SIGUSR1); 227 case XSIGUSR2: /* user defined signal 2 */ 228 return(SIGUSR2); 229 case XSIGPWR: /* user defined signal 2 */ 230 return(-1); 231 default: 232 return(sig); 233 } 234 } 235 236 int maptooldmask(mask) 237 int mask; 238 { 239 int omask; 240 241 omask = mask & 0x7FFF; /* these signo are same */ 242 243 if (mask & sigmask(XSIGURG)) 244 omask |= sigmask(SIGURG); 245 if (mask & sigmask(XSIGSTOP)) 246 omask |= sigmask(SIGSTOP); 247 if (mask & sigmask(XSIGTSTP)) 248 omask |= sigmask(SIGTSTP); 249 if (mask & sigmask(XSIGCONT)) 250 omask |= sigmask(SIGCONT); 251 if (mask & sigmask(XSIGCLD)) 252 omask |= sigmask(SIGCLD); 253 if (mask & sigmask(XSIGTTIN)) 254 omask |= sigmask(SIGTTIN); 255 if (mask & sigmask(XSIGTTOU)) 256 omask |= sigmask(SIGTTOU); 257 if (mask & sigmask(XSIGIO)) 258 omask |= sigmask(SIGIO); 259 if (mask & sigmask(XSIGXCPU)) 260 omask |= sigmask(SIGXCPU); 261 if (mask & sigmask(XSIGXFSZ)) 262 omask |= sigmask(SIGXFSZ); 263 if (mask & sigmask(XSIGVTALRM)) 264 omask |= sigmask(SIGVTALRM); 265 if (mask & sigmask(XSIGPROF)) 266 omask |= sigmask(SIGPROF); 267 if (mask & sigmask(XSIGWINCH)) 268 omask |= sigmask(SIGWINCH); 269 if (mask & sigmask(XSIGUSR1)) 270 omask |= sigmask(SIGUSR1); 271 if (mask & sigmask(XSIGUSR2)) 272 omask |= sigmask(SIGUSR2); 273 return(omask); 274 } 275 276 277 int maptonewmask(omask) 278 int omask; 279 { 280 int mask; 281 282 if (omask == -1) { 283 return(-1); 284 } 285 286 mask = omask & 0x7FFF; /* these signo are the same */ 287 288 if (omask & sigmask(SIGURG)) 289 mask |= sigmask(XSIGURG); 290 if (omask & sigmask(SIGSTOP)) 291 mask |= sigmask(XSIGSTOP); 292 if (omask & sigmask(SIGTSTP)) 293 mask |= sigmask(XSIGTSTP); 294 if (omask & sigmask(SIGCONT)) 295 mask |= sigmask(XSIGCONT); 296 if (omask & sigmask(SIGCLD)) 297 mask |= sigmask(XSIGCLD); 298 if (omask & sigmask(SIGTTIN)) 299 mask |= sigmask(XSIGTTIN); 300 if (omask & sigmask(SIGTTOU)) 301 mask |= sigmask(XSIGTTOU); 302 if (omask & sigmask(SIGIO)) 303 mask |= sigmask(XSIGIO); 304 if (omask & sigmask(SIGXCPU)) 305 mask |= sigmask(XSIGXCPU); 306 if (omask & sigmask(SIGXFSZ)) 307 mask |= sigmask(XSIGXFSZ); 308 if (omask & sigmask(SIGVTALRM)) 309 mask |= sigmask(XSIGVTALRM); 310 if (omask & sigmask(SIGPROF)) 311 mask |= sigmask(XSIGPROF); 312 if (omask & sigmask(SIGWINCH)) 313 mask |= sigmask(XSIGWINCH); 314 if (omask & sigmask(SIGUSR1)) 315 mask |= sigmask(XSIGUSR1); 316 if (omask & sigmask(SIGUSR2)) 317 mask |= sigmask(XSIGUSR2); 318 return(mask); 319 } 320