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