svr4_signal.c revision 48620
1/* 2 * Copyright (c) 1998 Mark Newton 3 * Copyright (c) 1994 Christos Zoulas 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/namei.h> 32#include <sys/proc.h> 33#include <sys/filedesc.h> 34#include <sys/mount.h> 35#include <sys/kernel.h> 36#include <sys/signal.h> 37#include <sys/signalvar.h> 38#include <sys/malloc.h> 39#include <sys/sysproto.h> 40 41#include <svr4/svr4.h> 42#include <svr4/svr4_types.h> 43#include <svr4/svr4_signal.h> 44#include <svr4/svr4_proto.h> 45#include <svr4/svr4_util.h> 46#include <svr4/svr4_ucontext.h> 47 48#define sigemptyset(s) memset((s), 0, sizeof(*(s))) 49#define sigismember(s, n) (*(s) & sigmask(n)) 50#define sigaddset(s, n) (*(s) |= sigmask(n)) 51 52#define svr4_sigmask(n) (1 << (((n) - 1) & 31)) 53#define svr4_sigword(n) (((n) - 1) >> 5) 54#define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s))) 55#define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n)) 56#define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n)) 57 58static __inline void svr4_sigfillset __P((svr4_sigset_t *)); 59void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *, 60 struct sigaction *)); 61void bsd_to_svr4_sigaction __P((const struct sigaction *, 62 struct svr4_sigaction *)); 63 64int bsd_to_svr4_sig[] = { 65 0, 66 SVR4_SIGHUP, 67 SVR4_SIGINT, 68 SVR4_SIGQUIT, 69 SVR4_SIGILL, 70 SVR4_SIGTRAP, 71 SVR4_SIGABRT, 72 SVR4_SIGEMT, 73 SVR4_SIGFPE, 74 SVR4_SIGKILL, 75 SVR4_SIGBUS, 76 SVR4_SIGSEGV, 77 SVR4_SIGSYS, 78 SVR4_SIGPIPE, 79 SVR4_SIGALRM, 80 SVR4_SIGTERM, 81 SVR4_SIGURG, 82 SVR4_SIGSTOP, 83 SVR4_SIGTSTP, 84 SVR4_SIGCONT, 85 SVR4_SIGCHLD, 86 SVR4_SIGTTIN, 87 SVR4_SIGTTOU, 88 SVR4_SIGIO, 89 SVR4_SIGXCPU, 90 SVR4_SIGXFSZ, 91 SVR4_SIGVTALRM, 92 SVR4_SIGPROF, 93 SVR4_SIGWINCH, 94 0, /* SIGINFO */ 95 SVR4_SIGUSR1, 96 SVR4_SIGUSR2, 97}; 98 99int svr4_to_bsd_sig[] = { 100 0, 101 SIGHUP, 102 SIGINT, 103 SIGQUIT, 104 SIGILL, 105 SIGTRAP, 106 SIGABRT, 107 SIGEMT, 108 SIGFPE, 109 SIGKILL, 110 SIGBUS, 111 SIGSEGV, 112 SIGSYS, 113 SIGPIPE, 114 SIGALRM, 115 SIGTERM, 116 SIGUSR1, 117 SIGUSR2, 118 SIGCHLD, 119 0, /* XXX NetBSD uses SIGPWR here, but we don't seem to have one */ 120 SIGWINCH, 121 SIGURG, 122 SIGIO, 123 SIGSTOP, 124 SIGTSTP, 125 SIGCONT, 126 SIGTTIN, 127 SIGTTOU, 128 SIGVTALRM, 129 SIGPROF, 130 SIGXCPU, 131 SIGXFSZ, 132}; 133 134static __inline void 135svr4_sigfillset(s) 136 svr4_sigset_t *s; 137{ 138 int i; 139 140 svr4_sigemptyset(s); 141 for (i = 1; i < SVR4_NSIG; i++) 142 svr4_sigaddset(s, i); 143} 144 145void 146svr4_to_bsd_sigset(sss, bss) 147 const svr4_sigset_t *sss; 148 sigset_t *bss; 149{ 150 int i, newsig; 151 152 sigemptyset(bss); 153 for (i = 1; i < SVR4_NSIG; i++) { 154 if (svr4_sigismember(sss, i)) { 155 newsig = svr4_to_bsd_sig[i]; 156 if (newsig) 157 sigaddset(bss, newsig); 158 } 159 } 160} 161 162 163void 164bsd_to_svr4_sigset(bss, sss) 165 const sigset_t *bss; 166 svr4_sigset_t *sss; 167{ 168 int i, newsig; 169 170 svr4_sigemptyset(sss); 171 for (i = 1; i < NSIG; i++) { 172 if (sigismember(bss, i)) { 173 newsig = bsd_to_svr4_sig[i]; 174 if (newsig) 175 svr4_sigaddset(sss, newsig); 176 } 177 } 178} 179 180 181/* 182 * XXX: Only a subset of the flags is currently implemented. 183 */ 184void 185svr4_to_bsd_sigaction(ssa, bsa) 186 const struct svr4_sigaction *ssa; 187 struct sigaction *bsa; 188{ 189 190 bsa->sa_handler = (sig_t) ssa->ssa_handler; 191 svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask); 192 bsa->sa_flags = 0; 193 if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0) 194 bsa->sa_flags |= SA_ONSTACK; 195 if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0) 196 bsa->sa_flags |= SA_RESETHAND; 197 if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0) 198 bsa->sa_flags |= SA_RESTART; 199 if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0) 200 DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n")); 201 if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0) 202 bsa->sa_flags |= SA_NOCLDSTOP; 203 if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0) 204 bsa->sa_flags |= SA_NODEFER; 205 if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0) 206 bsa->sa_flags |= SA_NOCLDWAIT; 207 if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0) 208 DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n")); 209} 210 211void 212bsd_to_svr4_sigaction(bsa, ssa) 213 const struct sigaction *bsa; 214 struct svr4_sigaction *ssa; 215{ 216 217 ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler; 218 bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask); 219 ssa->ssa_flags = 0; 220 if ((bsa->sa_flags & SA_ONSTACK) != 0) 221 ssa->ssa_flags |= SVR4_SA_ONSTACK; 222 if ((bsa->sa_flags & SA_RESETHAND) != 0) 223 ssa->ssa_flags |= SVR4_SA_RESETHAND; 224 if ((bsa->sa_flags & SA_RESTART) != 0) 225 ssa->ssa_flags |= SVR4_SA_RESTART; 226 if ((bsa->sa_flags & SA_NODEFER) != 0) 227 ssa->ssa_flags |= SVR4_SA_NODEFER; 228 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0) 229 ssa->ssa_flags |= SVR4_SA_NOCLDSTOP; 230} 231 232void 233svr4_to_bsd_sigaltstack(sss, bss) 234 const struct svr4_sigaltstack *sss; 235 struct sigaltstack *bss; 236{ 237 238 bss->ss_sp = sss->ss_sp; 239 bss->ss_size = sss->ss_size; 240 bss->ss_flags = 0; 241 if ((sss->ss_flags & SVR4_SS_DISABLE) != 0) 242 bss->ss_flags |= SS_DISABLE; 243 if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0) 244 bss->ss_flags |= SS_ONSTACK; 245 if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0) 246 /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n"); 247} 248 249void 250bsd_to_svr4_sigaltstack(bss, sss) 251 const struct sigaltstack *bss; 252 struct svr4_sigaltstack *sss; 253{ 254 255 sss->ss_sp = bss->ss_sp; 256 sss->ss_size = bss->ss_size; 257 sss->ss_flags = 0; 258 if ((bss->ss_flags & SS_DISABLE) != 0) 259 sss->ss_flags |= SVR4_SS_DISABLE; 260 if ((bss->ss_flags & SS_ONSTACK) != 0) 261 sss->ss_flags |= SVR4_SS_ONSTACK; 262} 263 264int 265svr4_sys_sigaction(p, uap) 266 register struct proc *p; 267 struct svr4_sys_sigaction_args *uap; 268{ 269 struct svr4_sigaction *nisa, *oisa, tmpisa; 270 struct sigaction *nbsa, *obsa, tmpbsa; 271 struct sigaction_args sa; 272 caddr_t sg; 273 int error; 274 275 sg = stackgap_init(); 276 nisa = SCARG(uap, nsa); 277 oisa = SCARG(uap, osa); 278 279 if (oisa != NULL) 280 obsa = stackgap_alloc(&sg, sizeof(struct sigaction)); 281 else 282 obsa = NULL; 283 284 if (nisa != NULL) { 285 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction)); 286 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0) 287 return error; 288 svr4_to_bsd_sigaction(&tmpisa, &tmpbsa); 289 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0) 290 return error; 291 } else 292 nbsa = NULL; 293 294 SCARG(&sa, signum) = svr4_to_bsd_sig[SCARG(uap, signum)]; 295 SCARG(&sa, nsa) = nbsa; 296 SCARG(&sa, osa) = obsa; 297 298 if ((error = sigaction(p, &sa)) != 0) 299 return error; 300 301 if (oisa != NULL) { 302 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0) 303 return error; 304 bsd_to_svr4_sigaction(&tmpbsa, &tmpisa); 305 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0) 306 return error; 307 } 308 309 return 0; 310} 311 312int 313svr4_sys_sigaltstack(p, uap) 314 register struct proc *p; 315 struct svr4_sys_sigaltstack_args *uap; 316{ 317 struct svr4_sigaltstack *nsss, *osss, tmpsss; 318 struct sigaltstack *nbss, *obss, tmpbss; 319 struct sigaltstack_args sa; 320 caddr_t sg; 321 int error, *retval; 322 323 retval = p->p_retval; 324 sg = stackgap_init(); 325 nsss = SCARG(uap, nss); 326 osss = SCARG(uap, oss); 327 328 if (osss != NULL) 329 obss = stackgap_alloc(&sg, sizeof(struct sigaltstack)); 330 else 331 obss = NULL; 332 333 if (nsss != NULL) { 334 nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack)); 335 if ((error = copyin(nsss, &tmpsss, sizeof(tmpsss))) != 0) 336 return error; 337 svr4_to_bsd_sigaltstack(&tmpsss, &tmpbss); 338 if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0) 339 return error; 340 } else 341 nbss = NULL; 342 343 SCARG(&sa, nss) = nbss; 344 SCARG(&sa, oss) = obss; 345 346 if ((error = sigaltstack(p, &sa)) != 0) 347 return error; 348 349 if (obss != NULL) { 350 if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0) 351 return error; 352 bsd_to_svr4_sigaltstack(&tmpbss, &tmpsss); 353 if ((error = copyout(&tmpsss, osss, sizeof(tmpsss))) != 0) 354 return error; 355 } 356 357 return 0; 358} 359 360/* 361 * Stolen from the ibcs2 one 362 */ 363int 364svr4_sys_signal(p, uap) 365 register struct proc *p; 366 struct svr4_sys_signal_args *uap; 367{ 368 int signum = svr4_to_bsd_sig[SVR4_SIGNO(SCARG(uap, signum))]; 369 int error, *retval; 370 caddr_t sg = stackgap_init(); 371 372 retval = p->p_retval; 373 if (signum <= 0 || signum >= SVR4_NSIG) 374 return (EINVAL); 375 376 switch (SVR4_SIGCALL(SCARG(uap, signum))) { 377 case SVR4_SIGDEFER_MASK: 378 if (SCARG(uap, handler) == SVR4_SIG_HOLD) 379 goto sighold; 380 /* FALLTHROUGH */ 381 382 case SVR4_SIGNAL_MASK: 383 { 384 struct sigaction_args sa_args; 385 struct sigaction *nbsa, *obsa, sa; 386 387 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction)); 388 obsa = stackgap_alloc(&sg, sizeof(struct sigaction)); 389 SCARG(&sa_args, signum) = signum; 390 SCARG(&sa_args, nsa) = nbsa; 391 SCARG(&sa_args, osa) = obsa; 392 393 sa.sa_handler = (sig_t) SCARG(uap, handler); 394 sigemptyset(&sa.sa_mask); 395 sa.sa_flags = 0; 396 397 if (signum != SIGALRM) 398 sa.sa_flags = SA_RESTART; 399 400 if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0) 401 return error; 402 if ((error = sigaction(p, &sa_args)) != 0) { 403 DPRINTF(("signal: sigaction failed: %d\n", 404 error)); 405 *retval = (int)SVR4_SIG_ERR; 406 return error; 407 } 408 if ((error = copyin(obsa, &sa, sizeof(sa))) != 0) 409 return error; 410 *retval = (int)sa.sa_handler; 411 return 0; 412 } 413 414 case SVR4_SIGHOLD_MASK: 415sighold: 416 { 417 struct sigprocmask_args sa; 418 419 SCARG(&sa, how) = SIG_BLOCK; 420 SCARG(&sa, mask) = sigmask(signum); 421 return sigprocmask(p, &sa); 422 } 423 424 case SVR4_SIGRELSE_MASK: 425 { 426 struct sigprocmask_args sa; 427 428 SCARG(&sa, how) = SIG_UNBLOCK; 429 SCARG(&sa, mask) = sigmask(signum); 430 return sigprocmask(p, &sa); 431 } 432 433 case SVR4_SIGIGNORE_MASK: 434 { 435 struct sigaction_args sa_args; 436 struct sigaction *bsa, sa; 437 438 bsa = stackgap_alloc(&sg, sizeof(struct sigaction)); 439 SCARG(&sa_args, signum) = signum; 440 SCARG(&sa_args, nsa) = bsa; 441 SCARG(&sa_args, osa) = NULL; 442 443 sa.sa_handler = SIG_IGN; 444 sigemptyset(&sa.sa_mask); 445 sa.sa_flags = 0; 446 if ((error = copyout(&sa, bsa, sizeof(sa))) != 0) 447 return error; 448 if ((error = sigaction(p, &sa_args)) != 0) { 449 DPRINTF(("sigignore: sigaction failed\n")); 450 return error; 451 } 452 return 0; 453 } 454 455 case SVR4_SIGPAUSE_MASK: 456 { 457 struct sigsuspend_args sa; 458 459 SCARG(&sa, mask) = p->p_sigmask & ~sigmask(signum); 460 return sigsuspend(p, &sa); 461 } 462 463 default: 464 return (ENOSYS); 465 } 466} 467 468 469int 470svr4_sys_sigprocmask(p, uap) 471 struct proc *p; 472 struct svr4_sys_sigprocmask_args *uap; 473{ 474 svr4_sigset_t sss; 475 sigset_t bss; 476 int error = 0, *retval; 477 478 retval = p->p_retval; 479 if (SCARG(uap, oset) != NULL) { 480 /* Fix the return value first if needed */ 481 bsd_to_svr4_sigset(&p->p_sigmask, &sss); 482 if ((error = copyout(&sss, SCARG(uap, oset), sizeof(sss))) != 0) 483 return error; 484 } 485 486 if (SCARG(uap, set) == NULL) 487 /* Just examine */ 488 return 0; 489 490 if ((error = copyin(SCARG(uap, set), &sss, sizeof(sss))) != 0) 491 return error; 492 493 svr4_to_bsd_sigset(&sss, &bss); 494 495 (void) splhigh(); 496 497 switch (SCARG(uap, how)) { 498 case SVR4_SIG_BLOCK: 499 p->p_sigmask |= bss & ~sigcantmask; 500 break; 501 502 case SVR4_SIG_UNBLOCK: 503 p->p_sigmask &= ~bss; 504 break; 505 506 case SVR4_SIG_SETMASK: 507 p->p_sigmask = bss & ~sigcantmask; 508 break; 509 510 default: 511 error = EINVAL; 512 break; 513 } 514 515 (void) spl0(); 516 517 return error; 518} 519 520int 521svr4_sys_sigpending(p, uap) 522 struct proc *p; 523 struct svr4_sys_sigpending_args *uap; 524{ 525 sigset_t bss; 526 int *retval; 527 svr4_sigset_t sss; 528 529 retval = p->p_retval; 530 switch (SCARG(uap, what)) { 531 case 1: /* sigpending */ 532 if (SCARG(uap, mask) == NULL) 533 return 0; 534 bss = p->p_siglist & p->p_sigmask; 535 bsd_to_svr4_sigset(&bss, &sss); 536 break; 537 538 case 2: /* sigfillset */ 539 svr4_sigfillset(&sss); 540 break; 541 542 default: 543 return EINVAL; 544 } 545 546 return copyout(&sss, SCARG(uap, mask), sizeof(sss)); 547} 548 549int 550svr4_sys_sigsuspend(p, uap) 551 register struct proc *p; 552 struct svr4_sys_sigsuspend_args *uap; 553{ 554 svr4_sigset_t sss; 555 sigset_t bss; 556 struct sigsuspend_args sa; 557 int error; 558 559 if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0) 560 return error; 561 562 svr4_to_bsd_sigset(&sss, &bss); 563 564 SCARG(&sa, mask) = bss; 565 return sigsuspend(p, &sa); 566} 567 568 569int 570svr4_sys_kill(p, uap) 571 register struct proc *p; 572 struct svr4_sys_kill_args *uap; 573{ 574 struct kill_args ka; 575 576 SCARG(&ka, pid) = SCARG(uap, pid); 577 SCARG(&ka, signum) = svr4_to_bsd_sig[SCARG(uap, signum)]; 578 return kill(p, &ka); 579} 580 581 582int 583svr4_sys_context(p, uap) 584 register struct proc *p; 585 struct svr4_sys_context_args *uap; 586{ 587 struct svr4_ucontext uc; 588 int error; 589 590 switch (uap->func) { 591 case 0: 592 DPRINTF(("getcontext(%p)\n", uap->uc)); 593 svr4_getcontext(p, &uc, p->p_sigmask, 594 p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK); 595 return copyout(&uc, uap->uc, sizeof(uc)); 596 597 case 1: 598 DPRINTF(("setcontext(%p)\n", uap->uc)); 599 if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0) 600 return error; 601 DPRINTF(("uc_flags = %x\n", uc.uc_flags)); 602 DPRINTF(("uc_sigmask = %x\n", uc.uc_sigmask)); 603 604 return svr4_setcontext(p, &uc); 605 606 default: 607 DPRINTF(("context(%d, %p)\n", uap->func, 608 uap->uc)); 609 return ENOSYS; 610 } 611 return 0; 612} 613 614int 615svr4_sys_pause(p, uap) 616 register struct proc *p; 617 struct svr4_sys_pause_args *uap; 618{ 619 struct sigsuspend_args bsa; 620 621 SCARG(&bsa, mask) = p->p_sigmask; 622 return sigsuspend(p, &bsa); 623} 624