1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: hpux_sig.c 1.4 92/01/20$ 13 * 14 * @(#)hpux_sig.c 7.11 (Berkeley) 07/10/92 15 */ 16 17 /* 18 * Signal related HPUX compatibility routines 19 */ 20 21 #ifdef HPUXCOMPAT 22 23 #include "param.h" 24 #include "systm.h" 25 #include "kernel.h" 26 #include "proc.h" 27 #include "signalvar.h" 28 #include "hpux.h" 29 30 /* indexed by HPUX signal number - 1 */ 31 char hpuxtobsdsigmap[NSIG] = { 32 /*01*/ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT, SIGFPE, 33 /*09*/ SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, 34 /*17*/ SIGUSR2, SIGCHLD, 0, SIGVTALRM,SIGPROF, SIGIO, SIGWINCH, SIGSTOP, 35 /*25*/ SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU, SIGURG, 0, 0, 0 36 }; 37 38 /* indexed by BSD signal number - 1 */ 39 char bsdtohpuxsigmap[NSIG] = { 40 /*01*/ 1, 2, 3, 4, 5, 6, 7, 8, 41 /*09*/ 9, 10, 11, 12, 13, 14, 15, 29, 42 /*17*/ 24, 25, 26, 18, 27, 28, 22, 0, 43 /*25*/ 0, 20, 21, 23, 0, 16, 17, 0 44 }; 45 46 /* 47 * XXX: In addition to mapping the signal number we also have 48 * to see if the "old" style signal mechinism is needed. 49 * If so, we set the OUSIG flag. This is not really correct 50 * as under HP-UX "old" style handling can be set on a per 51 * signal basis and we are setting it for all signals in one 52 * swell foop. I suspect we can get away with this since I 53 * doubt any program of interest mixes the two semantics. 54 */ 55 struct hpuxsigvec_args { 56 int signo; 57 struct sigvec *nsv; 58 struct sigvec *osv; 59 }; 60 hpuxsigvec(p, uap, retval) 61 struct proc *p; 62 register struct hpuxsigvec_args *uap; 63 int *retval; 64 { 65 struct sigvec vec; 66 register struct sigacts *ps = p->p_sigacts; 67 register struct sigvec *sv; 68 register int sig; 69 int bit, error; 70 71 sig = hpuxtobsdsig(uap->signo); 72 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 73 return (EINVAL); 74 sv = &vec; 75 if (uap->osv) { 76 sv->sv_handler = ps->ps_sigact[sig]; 77 sv->sv_mask = ps->ps_catchmask[sig]; 78 bit = sigmask(sig); 79 sv->sv_flags = 0; 80 if ((ps->ps_sigonstack & bit) != 0) 81 sv->sv_flags |= SV_ONSTACK; 82 if ((ps->ps_sigintr & bit) != 0) 83 sv->sv_flags |= SV_INTERRUPT; 84 #if 0 85 /* XXX -- SOUSIG no longer exists, do something here */ 86 if (p->p_flag & SOUSIG) 87 sv->sv_flags |= HPUXSV_RESET; /* XXX */ 88 #endif 89 error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 90 if (error) 91 return (error); 92 } 93 if (uap->nsv) { 94 error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 95 if (error) 96 return (error); 97 if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 98 return (EINVAL); 99 sv->sv_flags ^= SA_RESTART; 100 setsigvec(p, sig, (struct sigaction *)sv); 101 #if 0 102 /* XXX -- SOUSIG no longer exists, do something here */ 103 if (sv->sv_flags & HPUXSV_RESET) 104 p->p_flag |= SOUSIG; /* XXX */ 105 #endif 106 } 107 return (0); 108 } 109 110 struct hpuxsigblock_args { 111 int mask; 112 }; 113 hpuxsigblock(p, uap, retval) 114 register struct proc *p; 115 struct hpuxsigblock_args *uap; 116 int *retval; 117 { 118 119 (void) splhigh(); 120 *retval = bsdtohpuxmask(p->p_sigmask); 121 p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 122 (void) spl0(); 123 return (0); 124 } 125 126 struct hpuxsigsetmask_args { 127 int mask; 128 }; 129 hpuxsigsetmask(p, uap, retval) 130 struct proc *p; 131 struct hpuxsigsetmask_args *uap; 132 int *retval; 133 { 134 135 (void) splhigh(); 136 *retval = bsdtohpuxmask(p->p_sigmask); 137 p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 138 (void) spl0(); 139 return (0); 140 } 141 142 struct hpuxsigpause_args { 143 int mask; 144 }; 145 hpuxsigpause(p, uap, retval) 146 struct proc *p; 147 struct hpuxsigpause_args *uap; 148 int *retval; 149 { 150 151 uap->mask = hpuxtobsdmask(uap->mask); 152 return (sigsuspend(p, uap, retval)); 153 } 154 155 /* not totally correct, but close enuf' */ 156 struct hpuxkill_args { 157 int pid; 158 int signo; 159 }; 160 hpuxkill(p, uap, retval) 161 struct proc *p; 162 struct hpuxkill_args *uap; 163 int *retval; 164 { 165 166 if (uap->signo) { 167 uap->signo = hpuxtobsdsig(uap->signo); 168 if (uap->signo == 0) 169 uap->signo = NSIG; 170 } 171 return (kill(p, uap, retval)); 172 } 173 174 /* 175 * The following (sigprocmask, sigpending, sigsuspend, sigaction are 176 * POSIX calls. Under BSD, the library routine dereferences the sigset_t 177 * pointers before traping. Not so under HP-UX. 178 */ 179 180 /* 181 * Manipulate signal mask. 182 * Note that we receive new mask, not pointer, 183 * and return old mask as return value; 184 * the library stub does the rest. 185 */ 186 struct hpuxsigprocmask_args { 187 int how; 188 hpuxsigset_t *set; 189 hpuxsigset_t *oset; 190 }; 191 hpuxsigprocmask(p, uap, retval) 192 register struct proc *p; 193 struct hpuxsigprocmask_args *uap; 194 int *retval; 195 { 196 int mask, error = 0; 197 hpuxsigset_t sigset; 198 199 /* 200 * Copy out old mask first to ensure no errors. 201 * (proc sigmask should not be changed if call fails for any reason) 202 */ 203 if (uap->oset) { 204 bzero((caddr_t)&sigset, sizeof(sigset)); 205 sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask); 206 if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset))) 207 return (EFAULT); 208 } 209 if (uap->set) { 210 if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 211 return (EFAULT); 212 mask = hpuxtobsdmask(sigset.sigset[0]); 213 (void) splhigh(); 214 switch (uap->how) { 215 case HPUXSIG_BLOCK: 216 p->p_sigmask |= mask &~ sigcantmask; 217 break; 218 case HPUXSIG_UNBLOCK: 219 p->p_sigmask &= ~mask; 220 break; 221 case HPUXSIG_SETMASK: 222 p->p_sigmask = mask &~ sigcantmask; 223 break; 224 default: 225 error = EINVAL; 226 break; 227 } 228 (void) spl0(); 229 } 230 return (error); 231 } 232 233 struct hpuxsigpending_args { 234 hpuxsigset_t *set; 235 }; 236 hpuxsigpending(p, uap, retval) 237 register struct proc *p; 238 struct hpuxsigpending_args *uap; 239 int *retval; 240 { 241 hpuxsigset_t sigset; 242 243 sigset.sigset[0] = bsdtohpuxmask(p->p_sig); 244 return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset))); 245 } 246 247 struct hpuxsigsuspend_args { 248 hpuxsigset_t *set; 249 }; 250 hpuxsigsuspend(p, uap, retval) 251 register struct proc *p; 252 struct hpuxsigsuspend_args *uap; 253 int *retval; 254 { 255 register struct sigacts *ps = p->p_sigacts; 256 hpuxsigset_t sigset; 257 int mask; 258 259 if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 260 return (EFAULT); 261 mask = hpuxtobsdmask(sigset.sigset[0]); 262 ps->ps_oldmask = p->p_sigmask; 263 ps->ps_flags |= SAS_OLDMASK; 264 p->p_sigmask = mask &~ sigcantmask; 265 (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0); 266 /* always return EINTR rather than ERESTART... */ 267 return (EINTR); 268 } 269 270 struct hpuxsigaction_args { 271 int signo; 272 struct hpuxsigaction *nsa; 273 struct hpuxsigaction *osa; 274 }; 275 hpuxsigaction(p, uap, retval) 276 struct proc *p; 277 register struct hpuxsigaction_args *uap; 278 int *retval; 279 { 280 struct hpuxsigaction action; 281 register struct sigacts *ps = p->p_sigacts; 282 register struct hpuxsigaction *sa; 283 register int sig; 284 int bit; 285 286 sig = hpuxtobsdsig(uap->signo); 287 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 288 return (EINVAL); 289 290 sa = &action; 291 if (uap->osa) { 292 sa->sa_handler = ps->ps_sigact[sig]; 293 bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask)); 294 sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]); 295 bit = sigmask(sig); 296 sa->sa_flags = 0; 297 if ((ps->ps_sigonstack & bit) != 0) 298 sa->sa_flags |= HPUXSA_ONSTACK; 299 #if 0 300 /* XXX -- SOUSIG no longer exists, do something here */ 301 if (p->p_flag & SOUSIG) 302 sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */ 303 #endif 304 if (p->p_flag & SNOCLDSTOP) 305 sa->sa_flags |= HPUXSA_NOCLDSTOP; 306 if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action))) 307 return (EFAULT); 308 } 309 if (uap->nsa) { 310 struct sigaction act; 311 312 if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action))) 313 return (EFAULT); 314 if (sig == SIGCONT && sa->sa_handler == SIG_IGN) 315 return (EINVAL); 316 /* 317 * Create a sigaction struct for setsigvec 318 */ 319 act.sa_handler = sa->sa_handler; 320 act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]); 321 act.sa_flags == SA_RESTART; 322 if (sa->sa_flags & HPUXSA_ONSTACK) 323 act.sa_flags |= SA_ONSTACK; 324 if (sa->sa_flags & HPUXSA_NOCLDSTOP) 325 act.sa_flags |= SA_NOCLDSTOP; 326 setsigvec(p, sig, &act); 327 #if 0 328 /* XXX -- SOUSIG no longer exists, do something here */ 329 if (sa->sa_flags & HPUXSA_RESETHAND) 330 p->p_flag |= SOUSIG; /* XXX */ 331 #endif 332 } 333 return (0); 334 } 335 336 struct ohpuxssig_args { 337 int signo; 338 sig_t fun; 339 }; 340 ohpuxssig(p, uap, retval) 341 struct proc *p; 342 struct ohpuxssig_args *uap; 343 int *retval; 344 { 345 register int a; 346 struct sigaction vec; 347 register struct sigaction *sa = &vec; 348 349 a = hpuxtobsdsig(uap->signo); 350 sa->sa_handler = uap->fun; 351 /* 352 * Kill processes trying to use job control facilities 353 * (this'll help us find any vestiges of the old stuff). 354 */ 355 if ((a &~ 0377) || 356 (sa->sa_handler != SIG_DFL && sa->sa_handler != SIG_IGN && 357 ((int)sa->sa_handler) & 1)) { 358 psignal(p, SIGSYS); 359 return (0); 360 } 361 if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 362 a == SIGCONT && sa->sa_handler == SIG_IGN) 363 return (EINVAL); 364 sa->sa_mask = 0; 365 sa->sa_flags = 0; 366 *retval = (int)p->p_sigacts->ps_sigact[a]; 367 setsigvec(p, a, sa); 368 #if 0 369 p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 370 #endif 371 return (0); 372 } 373 374 /* signal numbers: convert from HPUX to BSD */ 375 hpuxtobsdsig(sig) 376 register int sig; 377 { 378 if (--sig < 0 || sig >= NSIG) 379 return(0); 380 return((int)hpuxtobsdsigmap[sig]); 381 } 382 383 /* signal numbers: convert from BSD to HPUX */ 384 bsdtohpuxsig(sig) 385 register int sig; 386 { 387 if (--sig < 0 || sig >= NSIG) 388 return(0); 389 return((int)bsdtohpuxsigmap[sig]); 390 } 391 392 /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 393 hpuxtobsdmask(mask) 394 register int mask; 395 { 396 register int nmask, sig, nsig; 397 398 if (mask == 0 || mask == -1) 399 return(mask); 400 nmask = 0; 401 for (sig = 1; sig < NSIG; sig++) 402 if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 403 nmask |= sigmask(nsig); 404 return(nmask); 405 } 406 407 bsdtohpuxmask(mask) 408 register int mask; 409 { 410 register int nmask, sig, nsig; 411 412 if (mask == 0 || mask == -1) 413 return(mask); 414 nmask = 0; 415 for (sig = 1; sig < NSIG; sig++) 416 if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 417 nmask |= sigmask(nsig); 418 return(nmask); 419 } 420 #endif 421