linux_signal.c revision 293498
1/*- 2 * Copyright (c) 1994-1995 S��ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 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: stable/10/sys/compat/linux/linux_signal.c 293498 2016-01-09 15:21:45Z dchagin $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/lock.h> 35#include <sys/mutex.h> 36#include <sys/sx.h> 37#include <sys/proc.h> 38#include <sys/signalvar.h> 39#include <sys/syscallsubr.h> 40#include <sys/sysproto.h> 41 42#include <security/audit/audit.h> 43 44#include "opt_compat.h" 45 46#ifdef COMPAT_LINUX32 47#include <machine/../linux32/linux.h> 48#include <machine/../linux32/linux32_proto.h> 49#else 50#include <machine/../linux/linux.h> 51#include <machine/../linux/linux_proto.h> 52#endif 53#include <compat/linux/linux_signal.h> 54#include <compat/linux/linux_util.h> 55#include <compat/linux/linux_emul.h> 56#include <compat/linux/linux_misc.h> 57 58static int linux_do_tkill(struct thread *td, struct thread *tdt, 59 ksiginfo_t *ksi); 60static void sicode_to_lsicode(int si_code, int *lsi_code); 61 62 63void 64linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 65{ 66 int b, l; 67 68 SIGEMPTYSET(*bss); 69 bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 70 bss->__bits[1] = lss->__bits[1]; 71 for (l = 1; l <= LINUX_SIGTBLSZ; l++) { 72 if (LINUX_SIGISMEMBER(*lss, l)) { 73 b = linux_to_bsd_signal[_SIG_IDX(l)]; 74 if (b) 75 SIGADDSET(*bss, b); 76 } 77 } 78} 79 80void 81bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 82{ 83 int b, l; 84 85 LINUX_SIGEMPTYSET(*lss); 86 lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 87 lss->__bits[1] = bss->__bits[1]; 88 for (b = 1; b <= LINUX_SIGTBLSZ; b++) { 89 if (SIGISMEMBER(*bss, b)) { 90 l = bsd_to_linux_signal[_SIG_IDX(b)]; 91 if (l) 92 LINUX_SIGADDSET(*lss, l); 93 } 94 } 95} 96 97static void 98linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 99{ 100 101 linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 102 bsa->sa_handler = PTRIN(lsa->lsa_handler); 103 bsa->sa_flags = 0; 104 if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 105 bsa->sa_flags |= SA_NOCLDSTOP; 106 if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 107 bsa->sa_flags |= SA_NOCLDWAIT; 108 if (lsa->lsa_flags & LINUX_SA_SIGINFO) 109 bsa->sa_flags |= SA_SIGINFO; 110 if (lsa->lsa_flags & LINUX_SA_ONSTACK) 111 bsa->sa_flags |= SA_ONSTACK; 112 if (lsa->lsa_flags & LINUX_SA_RESTART) 113 bsa->sa_flags |= SA_RESTART; 114 if (lsa->lsa_flags & LINUX_SA_ONESHOT) 115 bsa->sa_flags |= SA_RESETHAND; 116 if (lsa->lsa_flags & LINUX_SA_NOMASK) 117 bsa->sa_flags |= SA_NODEFER; 118} 119 120static void 121bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 122{ 123 124 bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 125#ifdef COMPAT_LINUX32 126 lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 127#else 128 lsa->lsa_handler = bsa->sa_handler; 129#endif 130 lsa->lsa_restorer = 0; /* unsupported */ 131 lsa->lsa_flags = 0; 132 if (bsa->sa_flags & SA_NOCLDSTOP) 133 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 134 if (bsa->sa_flags & SA_NOCLDWAIT) 135 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 136 if (bsa->sa_flags & SA_SIGINFO) 137 lsa->lsa_flags |= LINUX_SA_SIGINFO; 138 if (bsa->sa_flags & SA_ONSTACK) 139 lsa->lsa_flags |= LINUX_SA_ONSTACK; 140 if (bsa->sa_flags & SA_RESTART) 141 lsa->lsa_flags |= LINUX_SA_RESTART; 142 if (bsa->sa_flags & SA_RESETHAND) 143 lsa->lsa_flags |= LINUX_SA_ONESHOT; 144 if (bsa->sa_flags & SA_NODEFER) 145 lsa->lsa_flags |= LINUX_SA_NOMASK; 146} 147 148int 149linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 150 l_sigaction_t *linux_osa) 151{ 152 struct sigaction act, oact, *nsa, *osa; 153 int error, sig; 154 155 if (!LINUX_SIG_VALID(linux_sig)) 156 return (EINVAL); 157 158 osa = (linux_osa != NULL) ? &oact : NULL; 159 if (linux_nsa != NULL) { 160 nsa = &act; 161 linux_to_bsd_sigaction(linux_nsa, nsa); 162 } else 163 nsa = NULL; 164 165 if (linux_sig <= LINUX_SIGTBLSZ) 166 sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; 167 else 168 sig = linux_sig; 169 170 error = kern_sigaction(td, sig, nsa, osa, 0); 171 if (error) 172 return (error); 173 174 if (linux_osa != NULL) 175 bsd_to_linux_sigaction(osa, linux_osa); 176 177 return (0); 178} 179 180 181int 182linux_signal(struct thread *td, struct linux_signal_args *args) 183{ 184 l_sigaction_t nsa, osa; 185 int error; 186 187#ifdef DEBUG 188 if (ldebug(signal)) 189 printf(ARGS(signal, "%d, %p"), 190 args->sig, (void *)(uintptr_t)args->handler); 191#endif 192 193 nsa.lsa_handler = args->handler; 194 nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 195 LINUX_SIGEMPTYSET(nsa.lsa_mask); 196 197 error = linux_do_sigaction(td, args->sig, &nsa, &osa); 198 td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 199 200 return (error); 201} 202 203int 204linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 205{ 206 l_sigaction_t nsa, osa; 207 int error; 208 209#ifdef DEBUG 210 if (ldebug(rt_sigaction)) 211 printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 212 (long)args->sig, (void *)args->act, 213 (void *)args->oact, (long)args->sigsetsize); 214#endif 215 216 if (args->sigsetsize != sizeof(l_sigset_t)) 217 return (EINVAL); 218 219 if (args->act != NULL) { 220 error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 221 if (error) 222 return (error); 223 } 224 225 error = linux_do_sigaction(td, args->sig, 226 args->act ? &nsa : NULL, 227 args->oact ? &osa : NULL); 228 229 if (args->oact != NULL && !error) { 230 error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 231 } 232 233 return (error); 234} 235 236static int 237linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 238 l_sigset_t *old) 239{ 240 sigset_t omask, nmask; 241 sigset_t *nmaskp; 242 int error; 243 244 td->td_retval[0] = 0; 245 246 switch (how) { 247 case LINUX_SIG_BLOCK: 248 how = SIG_BLOCK; 249 break; 250 case LINUX_SIG_UNBLOCK: 251 how = SIG_UNBLOCK; 252 break; 253 case LINUX_SIG_SETMASK: 254 how = SIG_SETMASK; 255 break; 256 default: 257 return (EINVAL); 258 } 259 if (new != NULL) { 260 linux_to_bsd_sigset(new, &nmask); 261 nmaskp = &nmask; 262 } else 263 nmaskp = NULL; 264 error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 265 if (error == 0 && old != NULL) 266 bsd_to_linux_sigset(&omask, old); 267 268 return (error); 269} 270 271int 272linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 273{ 274 l_osigset_t mask; 275 l_sigset_t set, oset; 276 int error; 277 278#ifdef DEBUG 279 if (ldebug(sigprocmask)) 280 printf(ARGS(sigprocmask, "%d, *, *"), args->how); 281#endif 282 283 if (args->mask != NULL) { 284 error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 285 if (error) 286 return (error); 287 LINUX_SIGEMPTYSET(set); 288 set.__bits[0] = mask; 289 } 290 291 error = linux_do_sigprocmask(td, args->how, 292 args->mask ? &set : NULL, 293 args->omask ? &oset : NULL); 294 295 if (args->omask != NULL && !error) { 296 mask = oset.__bits[0]; 297 error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 298 } 299 300 return (error); 301} 302 303int 304linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 305{ 306 l_sigset_t set, oset; 307 int error; 308 309#ifdef DEBUG 310 if (ldebug(rt_sigprocmask)) 311 printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 312 args->how, (void *)args->mask, 313 (void *)args->omask, (long)args->sigsetsize); 314#endif 315 316 if (args->sigsetsize != sizeof(l_sigset_t)) 317 return EINVAL; 318 319 if (args->mask != NULL) { 320 error = copyin(args->mask, &set, sizeof(l_sigset_t)); 321 if (error) 322 return (error); 323 } 324 325 error = linux_do_sigprocmask(td, args->how, 326 args->mask ? &set : NULL, 327 args->omask ? &oset : NULL); 328 329 if (args->omask != NULL && !error) { 330 error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 331 } 332 333 return (error); 334} 335 336int 337linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 338{ 339 struct proc *p = td->td_proc; 340 l_sigset_t mask; 341 342#ifdef DEBUG 343 if (ldebug(sgetmask)) 344 printf(ARGS(sgetmask, "")); 345#endif 346 347 PROC_LOCK(p); 348 bsd_to_linux_sigset(&td->td_sigmask, &mask); 349 PROC_UNLOCK(p); 350 td->td_retval[0] = mask.__bits[0]; 351 return (0); 352} 353 354int 355linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 356{ 357 struct proc *p = td->td_proc; 358 l_sigset_t lset; 359 sigset_t bset; 360 361#ifdef DEBUG 362 if (ldebug(ssetmask)) 363 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 364#endif 365 366 PROC_LOCK(p); 367 bsd_to_linux_sigset(&td->td_sigmask, &lset); 368 td->td_retval[0] = lset.__bits[0]; 369 LINUX_SIGEMPTYSET(lset); 370 lset.__bits[0] = args->mask; 371 linux_to_bsd_sigset(&lset, &bset); 372 td->td_sigmask = bset; 373 SIG_CANTMASK(td->td_sigmask); 374 signotify(td); 375 PROC_UNLOCK(p); 376 return (0); 377} 378 379/* 380 * MPSAFE 381 */ 382int 383linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 384{ 385 struct proc *p = td->td_proc; 386 sigset_t bset; 387 l_sigset_t lset; 388 l_osigset_t mask; 389 390#ifdef DEBUG 391 if (ldebug(sigpending)) 392 printf(ARGS(sigpending, "*")); 393#endif 394 395 PROC_LOCK(p); 396 bset = p->p_siglist; 397 SIGSETOR(bset, td->td_siglist); 398 SIGSETAND(bset, td->td_sigmask); 399 PROC_UNLOCK(p); 400 bsd_to_linux_sigset(&bset, &lset); 401 mask = lset.__bits[0]; 402 return (copyout(&mask, args->mask, sizeof(mask))); 403} 404 405/* 406 * MPSAFE 407 */ 408int 409linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 410{ 411 struct proc *p = td->td_proc; 412 sigset_t bset; 413 l_sigset_t lset; 414 415 if (args->sigsetsize > sizeof(lset)) 416 return EINVAL; 417 /* NOT REACHED */ 418 419#ifdef DEBUG 420 if (ldebug(rt_sigpending)) 421 printf(ARGS(rt_sigpending, "*")); 422#endif 423 424 PROC_LOCK(p); 425 bset = p->p_siglist; 426 SIGSETOR(bset, td->td_siglist); 427 SIGSETAND(bset, td->td_sigmask); 428 PROC_UNLOCK(p); 429 bsd_to_linux_sigset(&bset, &lset); 430 return (copyout(&lset, args->set, args->sigsetsize)); 431} 432 433/* 434 * MPSAFE 435 */ 436int 437linux_rt_sigtimedwait(struct thread *td, 438 struct linux_rt_sigtimedwait_args *args) 439{ 440 int error, sig; 441 l_timeval ltv; 442 struct timeval tv; 443 struct timespec ts, *tsa; 444 l_sigset_t lset; 445 sigset_t bset; 446 l_siginfo_t linfo; 447 ksiginfo_t info; 448 449#ifdef DEBUG 450 if (ldebug(rt_sigtimedwait)) 451 printf(ARGS(rt_sigtimedwait, "*")); 452#endif 453 if (args->sigsetsize != sizeof(l_sigset_t)) 454 return (EINVAL); 455 456 if ((error = copyin(args->mask, &lset, sizeof(lset)))) 457 return (error); 458 linux_to_bsd_sigset(&lset, &bset); 459 460 tsa = NULL; 461 if (args->timeout) { 462 if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 463 return (error); 464#ifdef DEBUG 465 if (ldebug(rt_sigtimedwait)) 466 printf(LMSG("linux_rt_sigtimedwait: " 467 "incoming timeout (%d/%d)\n"), 468 ltv.tv_sec, ltv.tv_usec); 469#endif 470 tv.tv_sec = (long)ltv.tv_sec; 471 tv.tv_usec = (suseconds_t)ltv.tv_usec; 472 if (itimerfix(&tv)) { 473 /* 474 * The timeout was invalid. Convert it to something 475 * valid that will act as it does under Linux. 476 */ 477 tv.tv_sec += tv.tv_usec / 1000000; 478 tv.tv_usec %= 1000000; 479 if (tv.tv_usec < 0) { 480 tv.tv_sec -= 1; 481 tv.tv_usec += 1000000; 482 } 483 if (tv.tv_sec < 0) 484 timevalclear(&tv); 485#ifdef DEBUG 486 if (ldebug(rt_sigtimedwait)) 487 printf(LMSG("linux_rt_sigtimedwait: " 488 "converted timeout (%jd/%ld)\n"), 489 (intmax_t)tv.tv_sec, tv.tv_usec); 490#endif 491 } 492 TIMEVAL_TO_TIMESPEC(&tv, &ts); 493 tsa = &ts; 494 } 495 error = kern_sigtimedwait(td, bset, &info, tsa); 496#ifdef DEBUG 497 if (ldebug(rt_sigtimedwait)) 498 printf(LMSG("linux_rt_sigtimedwait: " 499 "sigtimedwait returning (%d)\n"), error); 500#endif 501 if (error) 502 return (error); 503 504 sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo); 505 506 if (args->ptr) { 507 memset(&linfo, 0, sizeof(linfo)); 508 ksiginfo_to_lsiginfo(&info, &linfo, sig); 509 error = copyout(&linfo, args->ptr, sizeof(linfo)); 510 } 511 if (error == 0) 512 td->td_retval[0] = sig; 513 514 return (error); 515} 516 517int 518linux_kill(struct thread *td, struct linux_kill_args *args) 519{ 520 struct kill_args /* { 521 int pid; 522 int signum; 523 } */ tmp; 524 525#ifdef DEBUG 526 if (ldebug(kill)) 527 printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 528#endif 529 530 /* 531 * Allow signal 0 as a means to check for privileges 532 */ 533 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 534 return (EINVAL); 535 536 if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) 537 tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; 538 else 539 tmp.signum = args->signum; 540 541 tmp.pid = args->pid; 542 return (sys_kill(td, &tmp)); 543} 544 545static int 546linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 547{ 548 struct proc *p; 549 int error; 550 551 p = tdt->td_proc; 552 AUDIT_ARG_SIGNUM(ksi->ksi_signo); 553 AUDIT_ARG_PID(p->p_pid); 554 AUDIT_ARG_PROCESS(p); 555 556 error = p_cansignal(td, p, ksi->ksi_signo); 557 if (error != 0 || ksi->ksi_signo == 0) 558 goto out; 559 560 tdksignal(tdt, ksi->ksi_signo, ksi); 561 562out: 563 PROC_UNLOCK(p); 564 return (error); 565} 566 567int 568linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 569{ 570 struct thread *tdt; 571 ksiginfo_t ksi; 572 int sig; 573 574#ifdef DEBUG 575 if (ldebug(tgkill)) 576 printf(ARGS(tgkill, "%d, %d, %d"), 577 args->tgid, args->pid, args->sig); 578#endif 579 580 if (args->pid <= 0 || args->tgid <=0) 581 return (EINVAL); 582 583 /* 584 * Allow signal 0 as a means to check for privileges 585 */ 586 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 587 return (EINVAL); 588 589 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 590 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 591 else 592 sig = args->sig; 593 594 tdt = linux_tdfind(td, args->pid, args->tgid); 595 if (tdt == NULL) 596 return (ESRCH); 597 598 ksiginfo_init(&ksi); 599 ksi.ksi_signo = sig; 600 ksi.ksi_code = SI_LWP; 601 ksi.ksi_errno = 0; 602 ksi.ksi_pid = td->td_proc->p_pid; 603 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 604 return (linux_do_tkill(td, tdt, &ksi)); 605} 606 607/* 608 * Deprecated since 2.5.75. Replaced by tgkill(). 609 */ 610int 611linux_tkill(struct thread *td, struct linux_tkill_args *args) 612{ 613 struct thread *tdt; 614 ksiginfo_t ksi; 615 int sig; 616 617#ifdef DEBUG 618 if (ldebug(tkill)) 619 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 620#endif 621 if (args->tid <= 0) 622 return (EINVAL); 623 624 if (!LINUX_SIG_VALID(args->sig)) 625 return (EINVAL); 626 627 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 628 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 629 else 630 sig = args->sig; 631 632 tdt = linux_tdfind(td, args->tid, -1); 633 if (tdt == NULL) 634 return (ESRCH); 635 636 ksiginfo_init(&ksi); 637 ksi.ksi_signo = sig; 638 ksi.ksi_code = SI_LWP; 639 ksi.ksi_errno = 0; 640 ksi.ksi_pid = td->td_proc->p_pid; 641 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 642 return (linux_do_tkill(td, tdt, &ksi)); 643} 644 645void 646ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 647{ 648 649 siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); 650} 651 652static void 653sicode_to_lsicode(int si_code, int *lsi_code) 654{ 655 656 switch (si_code) { 657 case SI_USER: 658 *lsi_code = LINUX_SI_USER; 659 break; 660 case SI_KERNEL: 661 *lsi_code = LINUX_SI_KERNEL; 662 break; 663 case SI_QUEUE: 664 *lsi_code = LINUX_SI_QUEUE; 665 break; 666 case SI_TIMER: 667 *lsi_code = LINUX_SI_TIMER; 668 break; 669 case SI_MESGQ: 670 *lsi_code = LINUX_SI_MESGQ; 671 break; 672 case SI_ASYNCIO: 673 *lsi_code = LINUX_SI_ASYNCIO; 674 break; 675 case SI_LWP: 676 *lsi_code = LINUX_SI_TKILL; 677 break; 678 default: 679 *lsi_code = si_code; 680 break; 681 } 682} 683 684void 685siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 686{ 687 688 /* sig alredy converted */ 689 lsi->lsi_signo = sig; 690 sicode_to_lsicode(si->si_code, &lsi->lsi_code); 691 692 switch (si->si_code) { 693 case SI_LWP: 694 lsi->lsi_pid = si->si_pid; 695 lsi->lsi_uid = si->si_uid; 696 break; 697 698 case SI_TIMER: 699 lsi->lsi_int = si->si_value.sival_int; 700 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 701 lsi->lsi_tid = si->si_timerid; 702 break; 703 704 case SI_QUEUE: 705 lsi->lsi_pid = si->si_pid; 706 lsi->lsi_uid = si->si_uid; 707 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 708 break; 709 710 case SI_ASYNCIO: 711 lsi->lsi_int = si->si_value.sival_int; 712 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 713 break; 714 715 default: 716 switch (sig) { 717 case LINUX_SIGPOLL: 718 /* XXX si_fd? */ 719 lsi->lsi_band = si->si_band; 720 break; 721 722 case LINUX_SIGCHLD: 723 lsi->lsi_errno = 0; 724 lsi->lsi_pid = si->si_pid; 725 lsi->lsi_uid = si->si_uid; 726 727 if (si->si_code == CLD_STOPPED) 728 lsi->lsi_status = BSD_TO_LINUX_SIGNAL(si->si_status); 729 else if (si->si_code == CLD_CONTINUED) 730 lsi->lsi_status = BSD_TO_LINUX_SIGNAL(SIGCONT); 731 else 732 lsi->lsi_status = si->si_status; 733 break; 734 735 case LINUX_SIGBUS: 736 case LINUX_SIGILL: 737 case LINUX_SIGFPE: 738 case LINUX_SIGSEGV: 739 lsi->lsi_addr = PTROUT(si->si_addr); 740 break; 741 742 default: 743 lsi->lsi_pid = si->si_pid; 744 lsi->lsi_uid = si->si_uid; 745 if (sig >= LINUX_SIGRTMIN) { 746 lsi->lsi_int = si->si_value.sival_int; 747 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 748 } 749 break; 750 } 751 break; 752 } 753} 754