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