linux_signal.c (a7ac45761335b1d514804cd0bfe44bdb2c3a3e0c) linux_signal.c (4ab7403bbd76f466d482cd69035091c04e409c09)
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

--- 46 unchanged lines hidden (view full) ---

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
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

--- 46 unchanged lines hidden (view full) ---

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
63#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
64void
65linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
66{
67 int b, l;
68
69 SIGEMPTYSET(*bss);
70 bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
71 bss->__bits[1] = lss->__bits[1];
72 for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
73 if (LINUX_SIGISMEMBER(*lss, l)) {
74 b = linux_to_bsd_signal[_SIG_IDX(l)];
75 if (b)
76 SIGADDSET(*bss, b);
77 }
78 }
79}
80
81void
82bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
83{
84 int b, l;
85
86 LINUX_SIGEMPTYSET(*lss);
87 lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
88 lss->__bits[1] = bss->__bits[1];
89 for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
90 if (SIGISMEMBER(*bss, b)) {
91 l = bsd_to_linux_signal[_SIG_IDX(b)];
92 if (l)
93 LINUX_SIGADDSET(*lss, l);
94 }
95 }
96}
97#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
98
99static void
100linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
101{
102
103 linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
104 bsa->sa_handler = PTRIN(lsa->lsa_handler);
105 bsa->sa_flags = 0;
106 if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)

--- 51 unchanged lines hidden (view full) ---

158 return (EINVAL);
159
160 osa = (linux_osa != NULL) ? &oact : NULL;
161 if (linux_nsa != NULL) {
162 nsa = &act;
163 linux_to_bsd_sigaction(linux_nsa, nsa);
164 } else
165 nsa = NULL;
63static void
64linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
65{
66
67 linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
68 bsa->sa_handler = PTRIN(lsa->lsa_handler);
69 bsa->sa_flags = 0;
70 if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)

--- 51 unchanged lines hidden (view full) ---

122 return (EINVAL);
123
124 osa = (linux_osa != NULL) ? &oact : NULL;
125 if (linux_nsa != NULL) {
126 nsa = &act;
127 linux_to_bsd_sigaction(linux_nsa, nsa);
128 } else
129 nsa = NULL;
130 sig = linux_to_bsd_signal(linux_sig);
166
131
167 if (linux_sig <= LINUX_SIGTBLSZ)
168 sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
169 else
170 sig = linux_sig;
171
172 error = kern_sigaction(td, sig, nsa, osa, 0);
173 if (error)
174 return (error);
175
176 if (linux_osa != NULL)
177 bsd_to_linux_sigaction(osa, linux_osa);
178
179 return (0);

--- 104 unchanged lines hidden (view full) ---

284 printf(ARGS(sigprocmask, "%d, *, *"), args->how);
285#endif
286
287 if (args->mask != NULL) {
288 error = copyin(args->mask, &mask, sizeof(l_osigset_t));
289 if (error)
290 return (error);
291 LINUX_SIGEMPTYSET(set);
132 error = kern_sigaction(td, sig, nsa, osa, 0);
133 if (error)
134 return (error);
135
136 if (linux_osa != NULL)
137 bsd_to_linux_sigaction(osa, linux_osa);
138
139 return (0);

--- 104 unchanged lines hidden (view full) ---

244 printf(ARGS(sigprocmask, "%d, *, *"), args->how);
245#endif
246
247 if (args->mask != NULL) {
248 error = copyin(args->mask, &mask, sizeof(l_osigset_t));
249 if (error)
250 return (error);
251 LINUX_SIGEMPTYSET(set);
292 set.__bits[0] = mask;
252 set.__mask = mask;
293 }
294
295 error = linux_do_sigprocmask(td, args->how,
296 args->mask ? &set : NULL,
297 args->omask ? &oset : NULL);
298
299 if (args->omask != NULL && !error) {
253 }
254
255 error = linux_do_sigprocmask(td, args->how,
256 args->mask ? &set : NULL,
257 args->omask ? &oset : NULL);
258
259 if (args->omask != NULL && !error) {
300 mask = oset.__bits[0];
260 mask = oset.__mask;
301 error = copyout(&mask, args->omask, sizeof(l_osigset_t));
302 }
303
304 return (error);
305}
306#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
307
308int

--- 39 unchanged lines hidden (view full) ---

348#ifdef DEBUG
349 if (ldebug(sgetmask))
350 printf(ARGS(sgetmask, ""));
351#endif
352
353 PROC_LOCK(p);
354 bsd_to_linux_sigset(&td->td_sigmask, &mask);
355 PROC_UNLOCK(p);
261 error = copyout(&mask, args->omask, sizeof(l_osigset_t));
262 }
263
264 return (error);
265}
266#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
267
268int

--- 39 unchanged lines hidden (view full) ---

308#ifdef DEBUG
309 if (ldebug(sgetmask))
310 printf(ARGS(sgetmask, ""));
311#endif
312
313 PROC_LOCK(p);
314 bsd_to_linux_sigset(&td->td_sigmask, &mask);
315 PROC_UNLOCK(p);
356 td->td_retval[0] = mask.__bits[0];
316 td->td_retval[0] = mask.__mask;
357 return (0);
358}
359
360int
361linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
362{
363 struct proc *p = td->td_proc;
364 l_sigset_t lset;
365 sigset_t bset;
366
367#ifdef DEBUG
368 if (ldebug(ssetmask))
369 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
370#endif
371
372 PROC_LOCK(p);
373 bsd_to_linux_sigset(&td->td_sigmask, &lset);
317 return (0);
318}
319
320int
321linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
322{
323 struct proc *p = td->td_proc;
324 l_sigset_t lset;
325 sigset_t bset;
326
327#ifdef DEBUG
328 if (ldebug(ssetmask))
329 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
330#endif
331
332 PROC_LOCK(p);
333 bsd_to_linux_sigset(&td->td_sigmask, &lset);
374 td->td_retval[0] = lset.__bits[0];
334 td->td_retval[0] = lset.__mask;
375 LINUX_SIGEMPTYSET(lset);
335 LINUX_SIGEMPTYSET(lset);
376 lset.__bits[0] = args->mask;
336 lset.__mask = args->mask;
377 linux_to_bsd_sigset(&lset, &bset);
378 td->td_sigmask = bset;
379 SIG_CANTMASK(td->td_sigmask);
380 signotify(td);
381 PROC_UNLOCK(p);
382 return (0);
383}
384

--- 11 unchanged lines hidden (view full) ---

396#endif
397
398 PROC_LOCK(p);
399 bset = p->p_siglist;
400 SIGSETOR(bset, td->td_siglist);
401 SIGSETAND(bset, td->td_sigmask);
402 PROC_UNLOCK(p);
403 bsd_to_linux_sigset(&bset, &lset);
337 linux_to_bsd_sigset(&lset, &bset);
338 td->td_sigmask = bset;
339 SIG_CANTMASK(td->td_sigmask);
340 signotify(td);
341 PROC_UNLOCK(p);
342 return (0);
343}
344

--- 11 unchanged lines hidden (view full) ---

356#endif
357
358 PROC_LOCK(p);
359 bset = p->p_siglist;
360 SIGSETOR(bset, td->td_siglist);
361 SIGSETAND(bset, td->td_sigmask);
362 PROC_UNLOCK(p);
363 bsd_to_linux_sigset(&bset, &lset);
404 mask = lset.__bits[0];
364 mask = lset.__mask;
405 return (copyout(&mask, args->mask, sizeof(mask)));
406}
407#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
408
409/*
410 * MPSAFE
411 */
412int

--- 87 unchanged lines hidden (view full) ---

500#ifdef DEBUG
501 if (ldebug(rt_sigtimedwait))
502 printf(LMSG("linux_rt_sigtimedwait: "
503 "sigtimedwait returning (%d)\n"), error);
504#endif
505 if (error)
506 return (error);
507
365 return (copyout(&mask, args->mask, sizeof(mask)));
366}
367#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
368
369/*
370 * MPSAFE
371 */
372int

--- 87 unchanged lines hidden (view full) ---

460#ifdef DEBUG
461 if (ldebug(rt_sigtimedwait))
462 printf(LMSG("linux_rt_sigtimedwait: "
463 "sigtimedwait returning (%d)\n"), error);
464#endif
465 if (error)
466 return (error);
467
508 sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo);
468 sig = bsd_to_linux_signal(info.ksi_signo);
509
510 if (args->ptr) {
511 memset(&linfo, 0, sizeof(linfo));
512 ksiginfo_to_lsiginfo(&info, &linfo, sig);
513 error = copyout(&linfo, args->ptr, sizeof(linfo));
514 }
515 if (error == 0)
516 td->td_retval[0] = sig;

--- 15 unchanged lines hidden (view full) ---

532#endif
533
534 /*
535 * Allow signal 0 as a means to check for privileges
536 */
537 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
538 return (EINVAL);
539
469
470 if (args->ptr) {
471 memset(&linfo, 0, sizeof(linfo));
472 ksiginfo_to_lsiginfo(&info, &linfo, sig);
473 error = copyout(&linfo, args->ptr, sizeof(linfo));
474 }
475 if (error == 0)
476 td->td_retval[0] = sig;

--- 15 unchanged lines hidden (view full) ---

492#endif
493
494 /*
495 * Allow signal 0 as a means to check for privileges
496 */
497 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
498 return (EINVAL);
499
540 if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
541 tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
500 if (args->signum > 0)
501 tmp.signum = linux_to_bsd_signal(args->signum);
542 else
502 else
543 tmp.signum = args->signum;
503 tmp.signum = 0;
544
545 tmp.pid = args->pid;
546 return (sys_kill(td, &tmp));
547}
548
549static int
550linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi)
551{

--- 33 unchanged lines hidden (view full) ---

585 return (EINVAL);
586
587 /*
588 * Allow signal 0 as a means to check for privileges
589 */
590 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0)
591 return (EINVAL);
592
504
505 tmp.pid = args->pid;
506 return (sys_kill(td, &tmp));
507}
508
509static int
510linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi)
511{

--- 33 unchanged lines hidden (view full) ---

545 return (EINVAL);
546
547 /*
548 * Allow signal 0 as a means to check for privileges
549 */
550 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0)
551 return (EINVAL);
552
593 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ)
594 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)];
553 if (args->sig > 0)
554 sig = linux_to_bsd_signal(args->sig);
595 else
555 else
596 sig = args->sig;
556 sig = 0;
597
598 tdt = linux_tdfind(td, args->pid, args->tgid);
599 if (tdt == NULL)
600 return (ESRCH);
601
602 ksiginfo_init(&ksi);
603 ksi.ksi_signo = sig;
604 ksi.ksi_code = SI_LWP;

--- 18 unchanged lines hidden (view full) ---

623 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
624#endif
625 if (args->tid <= 0)
626 return (EINVAL);
627
628 if (!LINUX_SIG_VALID(args->sig))
629 return (EINVAL);
630
557
558 tdt = linux_tdfind(td, args->pid, args->tgid);
559 if (tdt == NULL)
560 return (ESRCH);
561
562 ksiginfo_init(&ksi);
563 ksi.ksi_signo = sig;
564 ksi.ksi_code = SI_LWP;

--- 18 unchanged lines hidden (view full) ---

583 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
584#endif
585 if (args->tid <= 0)
586 return (EINVAL);
587
588 if (!LINUX_SIG_VALID(args->sig))
589 return (EINVAL);
590
591 sig = linux_to_bsd_signal(args->sig);
631
592
632 sig = BSD_TO_LINUX_SIGNAL(args->sig);
633
634 tdt = linux_tdfind(td, args->tid, -1);
635 if (tdt == NULL)
636 return (ESRCH);
637
638 ksiginfo_init(&ksi);
639 ksi.ksi_signo = sig;
640 ksi.ksi_code = SI_LWP;
641 ksi.ksi_errno = 0;

--- 80 unchanged lines hidden (view full) ---

722 break;
723
724 case LINUX_SIGCHLD:
725 lsi->lsi_errno = 0;
726 lsi->lsi_pid = si->si_pid;
727 lsi->lsi_uid = si->si_uid;
728
729 if (si->si_code == CLD_STOPPED)
593 tdt = linux_tdfind(td, args->tid, -1);
594 if (tdt == NULL)
595 return (ESRCH);
596
597 ksiginfo_init(&ksi);
598 ksi.ksi_signo = sig;
599 ksi.ksi_code = SI_LWP;
600 ksi.ksi_errno = 0;

--- 80 unchanged lines hidden (view full) ---

681 break;
682
683 case LINUX_SIGCHLD:
684 lsi->lsi_errno = 0;
685 lsi->lsi_pid = si->si_pid;
686 lsi->lsi_uid = si->si_uid;
687
688 if (si->si_code == CLD_STOPPED)
730 lsi->lsi_status = BSD_TO_LINUX_SIGNAL(si->si_status);
689 lsi->lsi_status = bsd_to_linux_signal(si->si_status);
731 else if (si->si_code == CLD_CONTINUED)
690 else if (si->si_code == CLD_CONTINUED)
732 lsi->lsi_status = BSD_TO_LINUX_SIGNAL(SIGCONT);
691 lsi->lsi_status = bsd_to_linux_signal(SIGCONT);
733 else
734 lsi->lsi_status = si->si_status;
735 break;
736
737 case LINUX_SIGBUS:
738 case LINUX_SIGILL:
739 case LINUX_SIGFPE:
740 case LINUX_SIGSEGV:

--- 8 unchanged lines hidden (view full) ---

749 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
750 }
751 break;
752 }
753 break;
754 }
755}
756
692 else
693 lsi->lsi_status = si->si_status;
694 break;
695
696 case LINUX_SIGBUS:
697 case LINUX_SIGILL:
698 case LINUX_SIGFPE:
699 case LINUX_SIGSEGV:

--- 8 unchanged lines hidden (view full) ---

708 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
709 }
710 break;
711 }
712 break;
713 }
714}
715
757int
758linux_to_bsd_sigaltstack(int lsa)
759{
760 int bsa = 0;
761
762 if (lsa & LINUX_SS_DISABLE)
763 bsa |= SS_DISABLE;
764 /*
765 * Linux ignores SS_ONSTACK flag for ss
766 * parameter while FreeBSD prohibits it.
767 */
768 return (bsa);
769}
770
771int
772bsd_to_linux_sigaltstack(int bsa)
773{
774 int lsa = 0;
775
776 if (bsa & SS_DISABLE)
777 lsa |= LINUX_SS_DISABLE;
778 if (bsa & SS_ONSTACK)
779 lsa |= LINUX_SS_ONSTACK;
780 return (lsa);
781}
782
783void
784lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig)
785{
786
787 ksi->ksi_signo = sig;
788 ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */
789 ksi->ksi_pid = lsi->lsi_pid;
790 ksi->ksi_uid = lsi->lsi_uid;

--- 16 unchanged lines hidden (view full) ---

807
808 error = copyin(args->info, &linfo, sizeof(linfo));
809 if (error != 0)
810 return (error);
811
812 if (linfo.lsi_code >= 0)
813 return (EPERM);
814
716void
717lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig)
718{
719
720 ksi->ksi_signo = sig;
721 ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */
722 ksi->ksi_pid = lsi->lsi_pid;
723 ksi->ksi_uid = lsi->lsi_uid;

--- 16 unchanged lines hidden (view full) ---

740
741 error = copyin(args->info, &linfo, sizeof(linfo));
742 if (error != 0)
743 return (error);
744
745 if (linfo.lsi_code >= 0)
746 return (EPERM);
747
815 sig = BSD_TO_LINUX_SIGNAL(args->sig);
748 sig = linux_to_bsd_signal(args->sig);
816
817 error = ESRCH;
818 if ((p = pfind(args->pid)) != NULL ||
819 (p = zpfind(args->pid)) != NULL) {
820 error = p_cansignal(td, p, sig);
821 if (error != 0) {
822 PROC_UNLOCK(p);
823 return (error);
824 }
825
826 ksiginfo_init(&ksi);
827 lsiginfo_to_ksiginfo(&linfo, &ksi, sig);
828 error = tdsendsignal(p, NULL, sig, &ksi);
829 PROC_UNLOCK(p);
830 }
831
832 return (error);
833}
749
750 error = ESRCH;
751 if ((p = pfind(args->pid)) != NULL ||
752 (p = zpfind(args->pid)) != NULL) {
753 error = p_cansignal(td, p, sig);
754 if (error != 0) {
755 PROC_UNLOCK(p);
756 return (error);
757 }
758
759 ksiginfo_init(&ksi);
760 lsiginfo_to_ksiginfo(&linfo, &ksi, sig);
761 error = tdsendsignal(p, NULL, sig, &ksi);
762 PROC_UNLOCK(p);
763 }
764
765 return (error);
766}