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