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.1 90/07/09$ 13 * 14 * @(#)hpux_sig.c 7.8 (Berkeley) 04/20/91 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 hpuxsigvec(p, uap, retval) 56 struct proc *p; 57 register struct args { 58 int signo; 59 struct sigvec *nsv; 60 struct sigvec *osv; 61 } *uap; 62 int *retval; 63 { 64 struct sigvec vec; 65 register struct sigacts *ps = p->p_sigacts; 66 register struct sigvec *sv; 67 register int sig; 68 int bit, error; 69 70 sig = hpuxtobsdsig(uap->signo); 71 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 72 return (EINVAL); 73 sv = &vec; 74 if (uap->osv) { 75 sv->sv_handler = ps->ps_sigact[sig]; 76 sv->sv_mask = ps->ps_catchmask[sig]; 77 bit = sigmask(sig); 78 sv->sv_flags = 0; 79 if ((ps->ps_sigonstack & bit) != 0) 80 sv->sv_flags |= SV_ONSTACK; 81 if ((ps->ps_sigintr & bit) != 0) 82 sv->sv_flags |= SV_INTERRUPT; 83 #if 0 84 /* XXX -- SOUSIG no longer exists, do something here */ 85 if (p->p_flag & SOUSIG) 86 sv->sv_flags |= HPUXSV_RESET; /* XXX */ 87 #endif 88 error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 89 if (error) 90 return (error); 91 } 92 if (uap->nsv) { 93 error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 94 if (error) 95 return (error); 96 if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 97 return (EINVAL); 98 sv->sv_flags ^= SA_RESTART; 99 setsigvec(p, sig, (struct sigaction *)sv); 100 #if 0 101 /* XXX -- SOUSIG no longer exists, do something here */ 102 if (sv->sv_flags & HPUXSV_RESET) 103 p->p_flag |= SOUSIG; /* XXX */ 104 #endif 105 } 106 return (0); 107 } 108 109 hpuxsigblock(p, uap, retval) 110 register struct proc *p; 111 struct args { 112 int mask; 113 } *uap; 114 int *retval; 115 { 116 117 (void) splhigh(); 118 *retval = bsdtohpuxmask(p->p_sigmask); 119 p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 120 (void) spl0(); 121 return (0); 122 } 123 124 hpuxsigsetmask(p, uap, retval) 125 struct proc *p; 126 struct args { 127 int mask; 128 } *uap; 129 int *retval; 130 { 131 132 (void) splhigh(); 133 *retval = bsdtohpuxmask(p->p_sigmask); 134 p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 135 (void) spl0(); 136 return (0); 137 } 138 139 hpuxsigpause(p, uap, retval) 140 struct proc *p; 141 struct args { 142 int mask; 143 } *uap; 144 int *retval; 145 { 146 147 uap->mask = hpuxtobsdmask(uap->mask); 148 return (sigsuspend(p, uap, retval)); 149 } 150 151 /* not totally correct, but close enuf' */ 152 hpuxkill(p, uap, retval) 153 struct proc *p; 154 struct args { 155 int pid; 156 int signo; 157 } *uap; 158 int *retval; 159 { 160 161 if (uap->signo) { 162 uap->signo = hpuxtobsdsig(uap->signo); 163 if (uap->signo == 0) 164 uap->signo = NSIG; 165 } 166 return (kill(p, uap, retval)); 167 } 168 169 /* 170 * The following (sigprocmask, sigpending, sigsuspend, sigaction are 171 * POSIX calls. Under BSD, the library routine dereferences the sigset_t 172 * pointers before traping. Not so under HP-UX. 173 */ 174 175 /* 176 * Manipulate signal mask. 177 * Note that we receive new mask, not pointer, 178 * and return old mask as return value; 179 * the library stub does the rest. 180 */ 181 hpuxsigprocmask(p, uap, retval) 182 register struct proc *p; 183 struct args { 184 int how; 185 hpuxsigset_t *set; 186 hpuxsigset_t *oset; 187 } *uap; 188 int *retval; 189 { 190 int mask, error = 0; 191 hpuxsigset_t sigset; 192 193 /* 194 * Copy out old mask first to ensure no errors. 195 * (proc sigmask should not be changed if call fails for any reason) 196 */ 197 if (uap->oset) { 198 bzero((caddr_t)&sigset, sizeof(sigset)); 199 sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask); 200 if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset))) 201 return (EFAULT); 202 } 203 if (uap->set) { 204 if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 205 return (EFAULT); 206 mask = hpuxtobsdmask(sigset.sigset[0]); 207 (void) splhigh(); 208 switch (uap->how) { 209 case HPUXSIG_BLOCK: 210 p->p_sigmask |= mask &~ sigcantmask; 211 break; 212 case HPUXSIG_UNBLOCK: 213 p->p_sigmask &= ~mask; 214 break; 215 case HPUXSIG_SETMASK: 216 p->p_sigmask = mask &~ sigcantmask; 217 break; 218 default: 219 error = EINVAL; 220 break; 221 } 222 (void) spl0(); 223 } 224 return (error); 225 } 226 227 hpuxsigpending(p, uap, retval) 228 register struct proc *p; 229 struct args { 230 hpuxsigset_t *set; 231 } *uap; 232 int *retval; 233 { 234 hpuxsigset_t sigset; 235 236 sigset.sigset[0] = bsdtohpuxmask(p->p_sig); 237 return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset))); 238 } 239 240 hpuxsigsuspend(p, uap, retval) 241 register struct proc *p; 242 struct args { 243 hpuxsigset_t *set; 244 } *uap; 245 int *retval; 246 { 247 register struct sigacts *ps = p->p_sigacts; 248 hpuxsigset_t sigset; 249 int mask; 250 251 if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 252 return (EFAULT); 253 mask = hpuxtobsdmask(sigset.sigset[0]); 254 ps->ps_oldmask = p->p_sigmask; 255 ps->ps_flags |= SA_OLDMASK; 256 p->p_sigmask = mask &~ sigcantmask; 257 (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0); 258 /* always return EINTR rather than ERESTART... */ 259 return (EINTR); 260 } 261 262 hpuxsigaction(p, uap, retval) 263 struct proc *p; 264 register struct args { 265 int signo; 266 struct hpuxsigaction *nsa; 267 struct hpuxsigaction *osa; 268 } *uap; 269 int *retval; 270 { 271 struct hpuxsigaction action; 272 register struct sigacts *ps = p->p_sigacts; 273 register struct hpuxsigaction *sa; 274 register int sig; 275 int bit; 276 277 sig = hpuxtobsdsig(uap->signo); 278 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 279 return (EINVAL); 280 281 sa = &action; 282 if (uap->osa) { 283 sa->sa_handler = ps->ps_sigact[sig]; 284 bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask)); 285 sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]); 286 bit = sigmask(sig); 287 sa->sa_flags = 0; 288 if ((ps->ps_sigonstack & bit) != 0) 289 sa->sa_flags |= HPUXSA_ONSTACK; 290 #if 0 291 /* XXX -- SOUSIG no longer exists, do something here */ 292 if (p->p_flag & SOUSIG) 293 sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */ 294 #endif 295 if (p->p_flag & SNOCLDSTOP) 296 sa->sa_flags |= HPUXSA_NOCLDSTOP; 297 if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action))) 298 return (EFAULT); 299 } 300 if (uap->nsa) { 301 struct sigaction act; 302 303 if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action))) 304 return (EFAULT); 305 if (sig == SIGCONT && sa->sa_handler == SIG_IGN) 306 return (EINVAL); 307 /* 308 * Create a sigaction struct for setsigvec 309 */ 310 act.sa_handler = sa->sa_handler; 311 act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]); 312 act.sa_flags == SA_RESTART; 313 if (sa->sa_flags & HPUXSA_ONSTACK) 314 act.sa_flags |= SA_ONSTACK; 315 if (sa->sa_flags & HPUXSA_NOCLDSTOP) 316 act.sa_flags |= SA_NOCLDSTOP; 317 setsigvec(p, sig, &act); 318 #if 0 319 /* XXX -- SOUSIG no longer exists, do something here */ 320 if (sa->sa_flags & HPUXSA_RESETHAND) 321 p->p_flag |= SOUSIG; /* XXX */ 322 #endif 323 } 324 return (0); 325 } 326 327 ohpuxssig(p, uap, retval) 328 struct proc *p; 329 struct args { 330 int signo; 331 sig_t fun; 332 } *uap; 333 int *retval; 334 { 335 register int a; 336 struct sigaction vec; 337 register struct sigaction *sa = &vec; 338 339 a = hpuxtobsdsig(uap->signo); 340 sa->sa_handler = uap->fun; 341 /* 342 * Kill processes trying to use job control facilities 343 * (this'll help us find any vestiges of the old stuff). 344 */ 345 if ((a &~ 0377) || 346 (sa->sa_handler != SIG_DFL && sa->sa_handler != SIG_IGN && 347 ((int)sa->sa_handler) & 1)) { 348 psignal(p, SIGSYS); 349 return (0); 350 } 351 if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 352 a == SIGCONT && sa->sa_handler == SIG_IGN) 353 return (EINVAL); 354 sa->sa_mask = 0; 355 sa->sa_flags = 0; 356 *retval = (int)p->p_sigacts->ps_sigact[a]; 357 setsigvec(p, a, sa); 358 #if 0 359 p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 360 #endif 361 return (0); 362 } 363 364 /* signal numbers: convert from HPUX to BSD */ 365 hpuxtobsdsig(sig) 366 register int sig; 367 { 368 if (--sig < 0 || sig >= NSIG) 369 return(0); 370 return((int)hpuxtobsdsigmap[sig]); 371 } 372 373 /* signal numbers: convert from BSD to HPUX */ 374 bsdtohpuxsig(sig) 375 register int sig; 376 { 377 if (--sig < 0 || sig >= NSIG) 378 return(0); 379 return((int)bsdtohpuxsigmap[sig]); 380 } 381 382 /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 383 hpuxtobsdmask(mask) 384 register int mask; 385 { 386 register int nmask, sig, nsig; 387 388 if (mask == 0 || mask == -1) 389 return(mask); 390 nmask = 0; 391 for (sig = 1; sig < NSIG; sig++) 392 if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 393 nmask |= sigmask(nsig); 394 return(nmask); 395 } 396 397 bsdtohpuxmask(mask) 398 register int mask; 399 { 400 register int nmask, sig, nsig; 401 402 if (mask == 0 || mask == -1) 403 return(mask); 404 nmask = 0; 405 for (sig = 1; sig < NSIG; sig++) 406 if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 407 nmask |= sigmask(nsig); 408 return(nmask); 409 } 410 #endif 411