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