1c21dee17SSøren Schmidt /*- 29a14aa01SUlrich Spörlein * Copyright (c) 1994-1995 Søren Schmidt 3c21dee17SSøren Schmidt * All rights reserved. 4c21dee17SSøren Schmidt * 5c21dee17SSøren Schmidt * Redistribution and use in source and binary forms, with or without 6c21dee17SSøren Schmidt * modification, are permitted provided that the following conditions 7c21dee17SSøren Schmidt * are met: 8c21dee17SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 9c21dee17SSøren Schmidt * notice, this list of conditions and the following disclaimer 10c21dee17SSøren Schmidt * in this position and unchanged. 11c21dee17SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 12c21dee17SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 13c21dee17SSøren Schmidt * documentation and/or other materials provided with the distribution. 14c21dee17SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1521dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 16c21dee17SSøren Schmidt * 17c21dee17SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18c21dee17SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19c21dee17SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20c21dee17SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21c21dee17SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22c21dee17SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23c21dee17SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24c21dee17SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25c21dee17SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26c21dee17SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27c21dee17SSøren Schmidt */ 28c21dee17SSøren Schmidt 2916dbc7f2SDavid E. O'Brien #include <sys/cdefs.h> 301e8d246eSNate Lawson __FBSDID("$FreeBSD$"); 3116dbc7f2SDavid E. O'Brien 32c21dee17SSøren Schmidt #include <sys/param.h> 33c21dee17SSøren Schmidt #include <sys/systm.h> 34fb919e4dSMark Murray #include <sys/lock.h> 35fb919e4dSMark Murray #include <sys/mutex.h> 3629ddc19bSAlexander Leidinger #include <sys/sx.h> 37c21dee17SSøren Schmidt #include <sys/proc.h> 38c21dee17SSøren Schmidt #include <sys/signalvar.h> 39206a5d3aSIan Dowse #include <sys/syscallsubr.h> 40fb919e4dSMark Murray #include <sys/sysproto.h> 41c21dee17SSøren Schmidt 42aa8b2011SKonstantin Belousov #include <security/audit/audit.h> 43aa8b2011SKonstantin Belousov 44aefce619SRuslan Ermilov #include "opt_compat.h" 45aefce619SRuslan Ermilov 461997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 474af27623STim J. Robbins #include <machine/../linux32/linux.h> 484af27623STim J. Robbins #include <machine/../linux32/linux32_proto.h> 491997c537SDavid E. O'Brien #else 501997c537SDavid E. O'Brien #include <machine/../linux/linux.h> 511997c537SDavid E. O'Brien #include <machine/../linux/linux_proto.h> 524af27623STim J. Robbins #endif 53ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_signal.h> 54ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_util.h> 559b44bfc5SAlexander Leidinger #include <compat/linux/linux_emul.h> 5681338031SDmitry Chagin #include <compat/linux/linux_misc.h> 5781338031SDmitry Chagin 5881338031SDmitry Chagin static int linux_do_tkill(struct thread *td, struct thread *tdt, 5981338031SDmitry Chagin ksiginfo_t *ksi); 60fe4ed1e7SDmitry Chagin static void sicode_to_lsicode(int si_code, int *lsi_code); 61fe4ed1e7SDmitry Chagin 629b44bfc5SAlexander Leidinger 63*7f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 64ba9ef45bSMarcel Moolenaar void 655002a60fSMarcel Moolenaar linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 66956d3333SMarcel Moolenaar { 67d66a5066SPeter Wemm int b, l; 68c21dee17SSøren Schmidt 69956d3333SMarcel Moolenaar SIGEMPTYSET(*bss); 70956d3333SMarcel Moolenaar bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 71956d3333SMarcel Moolenaar bss->__bits[1] = lss->__bits[1]; 72956d3333SMarcel Moolenaar for (l = 1; l <= LINUX_SIGTBLSZ; l++) { 73956d3333SMarcel Moolenaar if (LINUX_SIGISMEMBER(*lss, l)) { 74956d3333SMarcel Moolenaar b = linux_to_bsd_signal[_SIG_IDX(l)]; 75956d3333SMarcel Moolenaar if (b) 76956d3333SMarcel Moolenaar SIGADDSET(*bss, b); 77d66a5066SPeter Wemm } 78d66a5066SPeter Wemm } 79c21dee17SSøren Schmidt } 80c21dee17SSøren Schmidt 8179363394SAndrew Gallatin void 825002a60fSMarcel Moolenaar bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 83956d3333SMarcel Moolenaar { 84d66a5066SPeter Wemm int b, l; 85c21dee17SSøren Schmidt 86956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(*lss); 87956d3333SMarcel Moolenaar lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 88956d3333SMarcel Moolenaar lss->__bits[1] = bss->__bits[1]; 89956d3333SMarcel Moolenaar for (b = 1; b <= LINUX_SIGTBLSZ; b++) { 90956d3333SMarcel Moolenaar if (SIGISMEMBER(*bss, b)) { 91956d3333SMarcel Moolenaar l = bsd_to_linux_signal[_SIG_IDX(b)]; 92956d3333SMarcel Moolenaar if (l) 93956d3333SMarcel Moolenaar LINUX_SIGADDSET(*lss, l); 94d66a5066SPeter Wemm } 95d66a5066SPeter Wemm } 96c21dee17SSøren Schmidt } 97*7f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 98c21dee17SSøren Schmidt 99a1ebcbfbSPeter Wemm static void 1005002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 101d66a5066SPeter Wemm { 102956d3333SMarcel Moolenaar 103956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 1044af27623STim J. Robbins bsa->sa_handler = PTRIN(lsa->lsa_handler); 105d66a5066SPeter Wemm bsa->sa_flags = 0; 1068f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 107d66a5066SPeter Wemm bsa->sa_flags |= SA_NOCLDSTOP; 10806ebbe77SMarcel Moolenaar if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 10906ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_NOCLDWAIT; 11006ebbe77SMarcel Moolenaar if (lsa->lsa_flags & LINUX_SA_SIGINFO) 11106ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_SIGINFO; 1128f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_ONSTACK) 113d66a5066SPeter Wemm bsa->sa_flags |= SA_ONSTACK; 1148f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_RESTART) 115d66a5066SPeter Wemm bsa->sa_flags |= SA_RESTART; 1168f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_ONESHOT) 117d66a5066SPeter Wemm bsa->sa_flags |= SA_RESETHAND; 1188f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_NOMASK) 119d66a5066SPeter Wemm bsa->sa_flags |= SA_NODEFER; 120d66a5066SPeter Wemm } 121d66a5066SPeter Wemm 122a1ebcbfbSPeter Wemm static void 1235002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 124d66a5066SPeter Wemm { 125956d3333SMarcel Moolenaar 126956d3333SMarcel Moolenaar bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 1271997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 1284af27623STim J. Robbins lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 1294af27623STim J. Robbins #else 1308f437f44SMartin Cracauer lsa->lsa_handler = bsa->sa_handler; 1314af27623STim J. Robbins #endif 1324af27623STim J. Robbins lsa->lsa_restorer = 0; /* unsupported */ 1338f437f44SMartin Cracauer lsa->lsa_flags = 0; 134d66a5066SPeter Wemm if (bsa->sa_flags & SA_NOCLDSTOP) 1358f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 13606ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_NOCLDWAIT) 13706ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 13806ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_SIGINFO) 13906ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_SIGINFO; 140d66a5066SPeter Wemm if (bsa->sa_flags & SA_ONSTACK) 1418f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONSTACK; 142d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESTART) 1438f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_RESTART; 144d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESETHAND) 1458f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONESHOT; 146d66a5066SPeter Wemm if (bsa->sa_flags & SA_NODEFER) 1478f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOMASK; 148d66a5066SPeter Wemm } 149c21dee17SSøren Schmidt 150ba9ef45bSMarcel Moolenaar int 151b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 1525002a60fSMarcel Moolenaar l_sigaction_t *linux_osa) 15306ebbe77SMarcel Moolenaar { 154206a5d3aSIan Dowse struct sigaction act, oact, *nsa, *osa; 155206a5d3aSIan Dowse int error, sig; 15606ebbe77SMarcel Moolenaar 157687c23beSAlexander Leidinger if (!LINUX_SIG_VALID(linux_sig)) 158956d3333SMarcel Moolenaar return (EINVAL); 15906ebbe77SMarcel Moolenaar 160206a5d3aSIan Dowse osa = (linux_osa != NULL) ? &oact : NULL; 161956d3333SMarcel Moolenaar if (linux_nsa != NULL) { 162206a5d3aSIan Dowse nsa = &act; 163ec99e322SMarcel Moolenaar linux_to_bsd_sigaction(linux_nsa, nsa); 164206a5d3aSIan Dowse } else 16506ebbe77SMarcel Moolenaar nsa = NULL; 16606ebbe77SMarcel Moolenaar 167956d3333SMarcel Moolenaar if (linux_sig <= LINUX_SIGTBLSZ) 168206a5d3aSIan Dowse sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; 169956d3333SMarcel Moolenaar else 170206a5d3aSIan Dowse sig = linux_sig; 171956d3333SMarcel Moolenaar 172206a5d3aSIan Dowse error = kern_sigaction(td, sig, nsa, osa, 0); 17306ebbe77SMarcel Moolenaar if (error) 174956d3333SMarcel Moolenaar return (error); 17506ebbe77SMarcel Moolenaar 176ec99e322SMarcel Moolenaar if (linux_osa != NULL) 177ec99e322SMarcel Moolenaar bsd_to_linux_sigaction(osa, linux_osa); 17806ebbe77SMarcel Moolenaar 179956d3333SMarcel Moolenaar return (0); 18006ebbe77SMarcel Moolenaar } 18106ebbe77SMarcel Moolenaar 182*7f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 183c21dee17SSøren Schmidt int 184b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args) 185d66a5066SPeter Wemm { 1865002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 187d66a5066SPeter Wemm int error; 188d66a5066SPeter Wemm 189d66a5066SPeter Wemm #ifdef DEBUG 19024593369SJonathan Lemon if (ldebug(signal)) 19124593369SJonathan Lemon printf(ARGS(signal, "%d, %p"), 192b61c60d4SDavid E. O'Brien args->sig, (void *)(uintptr_t)args->handler); 193d66a5066SPeter Wemm #endif 194d66a5066SPeter Wemm 19506ebbe77SMarcel Moolenaar nsa.lsa_handler = args->handler; 19606ebbe77SMarcel Moolenaar nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 197956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(nsa.lsa_mask); 198d66a5066SPeter Wemm 199b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, &nsa, &osa); 2004af27623STim J. Robbins td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 201d66a5066SPeter Wemm 202956d3333SMarcel Moolenaar return (error); 203d66a5066SPeter Wemm } 204*7f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 205d66a5066SPeter Wemm 206c21dee17SSøren Schmidt int 207b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 208c21dee17SSøren Schmidt { 2095002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 21006ebbe77SMarcel Moolenaar int error; 211c21dee17SSøren Schmidt 212c21dee17SSøren Schmidt #ifdef DEBUG 21324593369SJonathan Lemon if (ldebug(rt_sigaction)) 21424593369SJonathan Lemon printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 21524593369SJonathan Lemon (long)args->sig, (void *)args->act, 2165231fb20SDavid E. O'Brien (void *)args->oact, (long)args->sigsetsize); 217c21dee17SSøren Schmidt #endif 218d66a5066SPeter Wemm 2195002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 220956d3333SMarcel Moolenaar return (EINVAL); 22106ebbe77SMarcel Moolenaar 222956d3333SMarcel Moolenaar if (args->act != NULL) { 2235002a60fSMarcel Moolenaar error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 22406ebbe77SMarcel Moolenaar if (error) 225956d3333SMarcel Moolenaar return (error); 22606ebbe77SMarcel Moolenaar } 22706ebbe77SMarcel Moolenaar 228b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, 22906ebbe77SMarcel Moolenaar args->act ? &nsa : NULL, 23006ebbe77SMarcel Moolenaar args->oact ? &osa : NULL); 23106ebbe77SMarcel Moolenaar 232956d3333SMarcel Moolenaar if (args->oact != NULL && !error) { 2335002a60fSMarcel Moolenaar error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 23406ebbe77SMarcel Moolenaar } 23506ebbe77SMarcel Moolenaar 236956d3333SMarcel Moolenaar return (error); 23706ebbe77SMarcel Moolenaar } 23806ebbe77SMarcel Moolenaar 23906ebbe77SMarcel Moolenaar static int 240b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 2415002a60fSMarcel Moolenaar l_sigset_t *old) 24206ebbe77SMarcel Moolenaar { 243fe8cdcaeSJohn Baldwin sigset_t omask, nmask; 244fe8cdcaeSJohn Baldwin sigset_t *nmaskp; 245216af822SJohn Baldwin int error; 24606ebbe77SMarcel Moolenaar 247b40ce416SJulian Elischer td->td_retval[0] = 0; 248d66a5066SPeter Wemm 24919dde5cdSJohn Baldwin switch (how) { 25019dde5cdSJohn Baldwin case LINUX_SIG_BLOCK: 25119dde5cdSJohn Baldwin how = SIG_BLOCK; 25219dde5cdSJohn Baldwin break; 25319dde5cdSJohn Baldwin case LINUX_SIG_UNBLOCK: 25419dde5cdSJohn Baldwin how = SIG_UNBLOCK; 25519dde5cdSJohn Baldwin break; 25619dde5cdSJohn Baldwin case LINUX_SIG_SETMASK: 25719dde5cdSJohn Baldwin how = SIG_SETMASK; 25819dde5cdSJohn Baldwin break; 25919dde5cdSJohn Baldwin default: 26019dde5cdSJohn Baldwin return (EINVAL); 26119dde5cdSJohn Baldwin } 26206ebbe77SMarcel Moolenaar if (new != NULL) { 263fe8cdcaeSJohn Baldwin linux_to_bsd_sigset(new, &nmask); 264fe8cdcaeSJohn Baldwin nmaskp = &nmask; 265fe8cdcaeSJohn Baldwin } else 266fe8cdcaeSJohn Baldwin nmaskp = NULL; 26719dde5cdSJohn Baldwin error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 2682f7ed219SJohn Baldwin if (error == 0 && old != NULL) 269fe8cdcaeSJohn Baldwin bsd_to_linux_sigset(&omask, old); 27006ebbe77SMarcel Moolenaar 271956d3333SMarcel Moolenaar return (error); 27206ebbe77SMarcel Moolenaar } 27306ebbe77SMarcel Moolenaar 274*7f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 27506ebbe77SMarcel Moolenaar int 276b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 27706ebbe77SMarcel Moolenaar { 2785002a60fSMarcel Moolenaar l_osigset_t mask; 2795002a60fSMarcel Moolenaar l_sigset_t set, oset; 28006ebbe77SMarcel Moolenaar int error; 28106ebbe77SMarcel Moolenaar 28206ebbe77SMarcel Moolenaar #ifdef DEBUG 28324593369SJonathan Lemon if (ldebug(sigprocmask)) 28424593369SJonathan Lemon printf(ARGS(sigprocmask, "%d, *, *"), args->how); 28506ebbe77SMarcel Moolenaar #endif 28606ebbe77SMarcel Moolenaar 28706ebbe77SMarcel Moolenaar if (args->mask != NULL) { 2885002a60fSMarcel Moolenaar error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 28906ebbe77SMarcel Moolenaar if (error) 290956d3333SMarcel Moolenaar return (error); 291956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(set); 292956d3333SMarcel Moolenaar set.__bits[0] = mask; 29306ebbe77SMarcel Moolenaar } 29406ebbe77SMarcel Moolenaar 295b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 296956d3333SMarcel Moolenaar args->mask ? &set : NULL, 297956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 29806ebbe77SMarcel Moolenaar 299956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 300956d3333SMarcel Moolenaar mask = oset.__bits[0]; 3015002a60fSMarcel Moolenaar error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 30206ebbe77SMarcel Moolenaar } 30306ebbe77SMarcel Moolenaar 304956d3333SMarcel Moolenaar return (error); 30506ebbe77SMarcel Moolenaar } 306*7f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 30706ebbe77SMarcel Moolenaar 30806ebbe77SMarcel Moolenaar int 309b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 31006ebbe77SMarcel Moolenaar { 3115002a60fSMarcel Moolenaar l_sigset_t set, oset; 31206ebbe77SMarcel Moolenaar int error; 31306ebbe77SMarcel Moolenaar 31406ebbe77SMarcel Moolenaar #ifdef DEBUG 31524593369SJonathan Lemon if (ldebug(rt_sigprocmask)) 31624593369SJonathan Lemon printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 31724593369SJonathan Lemon args->how, (void *)args->mask, 3185231fb20SDavid E. O'Brien (void *)args->omask, (long)args->sigsetsize); 31906ebbe77SMarcel Moolenaar #endif 32006ebbe77SMarcel Moolenaar 3215002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 32206ebbe77SMarcel Moolenaar return EINVAL; 32306ebbe77SMarcel Moolenaar 32406ebbe77SMarcel Moolenaar if (args->mask != NULL) { 3255002a60fSMarcel Moolenaar error = copyin(args->mask, &set, sizeof(l_sigset_t)); 32606ebbe77SMarcel Moolenaar if (error) 327956d3333SMarcel Moolenaar return (error); 32806ebbe77SMarcel Moolenaar } 32906ebbe77SMarcel Moolenaar 330b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 331956d3333SMarcel Moolenaar args->mask ? &set : NULL, 332956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 33306ebbe77SMarcel Moolenaar 334956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 3355002a60fSMarcel Moolenaar error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 33606ebbe77SMarcel Moolenaar } 33706ebbe77SMarcel Moolenaar 338956d3333SMarcel Moolenaar return (error); 339c21dee17SSøren Schmidt } 340c21dee17SSøren Schmidt 341*7f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 342c21dee17SSøren Schmidt int 343b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 344c21dee17SSøren Schmidt { 345b40ce416SJulian Elischer struct proc *p = td->td_proc; 3465002a60fSMarcel Moolenaar l_sigset_t mask; 347956d3333SMarcel Moolenaar 348c21dee17SSøren Schmidt #ifdef DEBUG 3495002a60fSMarcel Moolenaar if (ldebug(sgetmask)) 3505002a60fSMarcel Moolenaar printf(ARGS(sgetmask, "")); 351c21dee17SSøren Schmidt #endif 352956d3333SMarcel Moolenaar 353216af822SJohn Baldwin PROC_LOCK(p); 3544093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &mask); 355216af822SJohn Baldwin PROC_UNLOCK(p); 356b40ce416SJulian Elischer td->td_retval[0] = mask.__bits[0]; 357956d3333SMarcel Moolenaar return (0); 358c21dee17SSøren Schmidt } 359c21dee17SSøren Schmidt 360c21dee17SSøren Schmidt int 361b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 362c21dee17SSøren Schmidt { 363b40ce416SJulian Elischer struct proc *p = td->td_proc; 3645002a60fSMarcel Moolenaar l_sigset_t lset; 365956d3333SMarcel Moolenaar sigset_t bset; 366c21dee17SSøren Schmidt 367c21dee17SSøren Schmidt #ifdef DEBUG 3685002a60fSMarcel Moolenaar if (ldebug(ssetmask)) 3695002a60fSMarcel Moolenaar printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 370c21dee17SSøren Schmidt #endif 371d66a5066SPeter Wemm 372216af822SJohn Baldwin PROC_LOCK(p); 3734093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &lset); 374b40ce416SJulian Elischer td->td_retval[0] = lset.__bits[0]; 375956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(lset); 376956d3333SMarcel Moolenaar lset.__bits[0] = args->mask; 377956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lset, &bset); 3784093529dSJeff Roberson td->td_sigmask = bset; 3794093529dSJeff Roberson SIG_CANTMASK(td->td_sigmask); 3804093529dSJeff Roberson signotify(td); 381216af822SJohn Baldwin PROC_UNLOCK(p); 382956d3333SMarcel Moolenaar return (0); 383c21dee17SSøren Schmidt } 384c21dee17SSøren Schmidt 385c21dee17SSøren Schmidt int 386b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 387c21dee17SSøren Schmidt { 388b40ce416SJulian Elischer struct proc *p = td->td_proc; 389956d3333SMarcel Moolenaar sigset_t bset; 3905002a60fSMarcel Moolenaar l_sigset_t lset; 3915002a60fSMarcel Moolenaar l_osigset_t mask; 392c21dee17SSøren Schmidt 393c21dee17SSøren Schmidt #ifdef DEBUG 39424593369SJonathan Lemon if (ldebug(sigpending)) 39524593369SJonathan Lemon printf(ARGS(sigpending, "*")); 396c21dee17SSøren Schmidt #endif 397956d3333SMarcel Moolenaar 398216af822SJohn Baldwin PROC_LOCK(p); 3991d9c5696SJuli Mallett bset = p->p_siglist; 4004093529dSJeff Roberson SIGSETOR(bset, td->td_siglist); 4014093529dSJeff Roberson SIGSETAND(bset, td->td_sigmask); 402216af822SJohn Baldwin PROC_UNLOCK(p); 4039d8643ecSJohn Baldwin bsd_to_linux_sigset(&bset, &lset); 404956d3333SMarcel Moolenaar mask = lset.__bits[0]; 405956d3333SMarcel Moolenaar return (copyout(&mask, args->mask, sizeof(mask))); 406c21dee17SSøren Schmidt } 407*7f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 40817138b61SAlexander Leidinger 40917138b61SAlexander Leidinger /* 41017138b61SAlexander Leidinger * MPSAFE 41117138b61SAlexander Leidinger */ 41217138b61SAlexander Leidinger int 41317138b61SAlexander Leidinger linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 41417138b61SAlexander Leidinger { 41517138b61SAlexander Leidinger struct proc *p = td->td_proc; 41617138b61SAlexander Leidinger sigset_t bset; 41717138b61SAlexander Leidinger l_sigset_t lset; 41817138b61SAlexander Leidinger 41917138b61SAlexander Leidinger if (args->sigsetsize > sizeof(lset)) 42017138b61SAlexander Leidinger return EINVAL; 42117138b61SAlexander Leidinger /* NOT REACHED */ 42217138b61SAlexander Leidinger 42317138b61SAlexander Leidinger #ifdef DEBUG 42417138b61SAlexander Leidinger if (ldebug(rt_sigpending)) 42517138b61SAlexander Leidinger printf(ARGS(rt_sigpending, "*")); 42617138b61SAlexander Leidinger #endif 42717138b61SAlexander Leidinger 42817138b61SAlexander Leidinger PROC_LOCK(p); 42917138b61SAlexander Leidinger bset = p->p_siglist; 43017138b61SAlexander Leidinger SIGSETOR(bset, td->td_siglist); 43117138b61SAlexander Leidinger SIGSETAND(bset, td->td_sigmask); 43217138b61SAlexander Leidinger PROC_UNLOCK(p); 43317138b61SAlexander Leidinger bsd_to_linux_sigset(&bset, &lset); 43417138b61SAlexander Leidinger return (copyout(&lset, args->set, args->sigsetsize)); 43517138b61SAlexander Leidinger } 436c21dee17SSøren Schmidt 437c9447c75SAlexander Leidinger /* 438c9447c75SAlexander Leidinger * MPSAFE 439c9447c75SAlexander Leidinger */ 440c9447c75SAlexander Leidinger int 441c9447c75SAlexander Leidinger linux_rt_sigtimedwait(struct thread *td, 442c9447c75SAlexander Leidinger struct linux_rt_sigtimedwait_args *args) 443c9447c75SAlexander Leidinger { 444f3481dd9SDmitry Chagin int error, sig; 445c9447c75SAlexander Leidinger l_timeval ltv; 446c9447c75SAlexander Leidinger struct timeval tv; 447c9447c75SAlexander Leidinger struct timespec ts, *tsa; 448c9447c75SAlexander Leidinger l_sigset_t lset; 449c9447c75SAlexander Leidinger sigset_t bset; 450c9447c75SAlexander Leidinger l_siginfo_t linfo; 451c9447c75SAlexander Leidinger ksiginfo_t info; 452c9447c75SAlexander Leidinger 453c9447c75SAlexander Leidinger #ifdef DEBUG 454c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 455c9447c75SAlexander Leidinger printf(ARGS(rt_sigtimedwait, "*")); 456c9447c75SAlexander Leidinger #endif 457c9447c75SAlexander Leidinger if (args->sigsetsize != sizeof(l_sigset_t)) 458c9447c75SAlexander Leidinger return (EINVAL); 459c9447c75SAlexander Leidinger 460c9447c75SAlexander Leidinger if ((error = copyin(args->mask, &lset, sizeof(lset)))) 461c9447c75SAlexander Leidinger return (error); 462c9447c75SAlexander Leidinger linux_to_bsd_sigset(&lset, &bset); 463c9447c75SAlexander Leidinger 464c9447c75SAlexander Leidinger tsa = NULL; 465c9447c75SAlexander Leidinger if (args->timeout) { 466c9447c75SAlexander Leidinger if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 467c9447c75SAlexander Leidinger return (error); 468c9447c75SAlexander Leidinger #ifdef DEBUG 469c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 4708c50c562SDmitry Chagin printf(LMSG("linux_rt_sigtimedwait: " 4718c50c562SDmitry Chagin "incoming timeout (%d/%d)\n"), 472c9447c75SAlexander Leidinger ltv.tv_sec, ltv.tv_usec); 473c9447c75SAlexander Leidinger #endif 474c9447c75SAlexander Leidinger tv.tv_sec = (long)ltv.tv_sec; 475c9447c75SAlexander Leidinger tv.tv_usec = (suseconds_t)ltv.tv_usec; 476c9447c75SAlexander Leidinger if (itimerfix(&tv)) { 477c9447c75SAlexander Leidinger /* 478c9447c75SAlexander Leidinger * The timeout was invalid. Convert it to something 479c9447c75SAlexander Leidinger * valid that will act as it does under Linux. 480c9447c75SAlexander Leidinger */ 481c9447c75SAlexander Leidinger tv.tv_sec += tv.tv_usec / 1000000; 482c9447c75SAlexander Leidinger tv.tv_usec %= 1000000; 483c9447c75SAlexander Leidinger if (tv.tv_usec < 0) { 484c9447c75SAlexander Leidinger tv.tv_sec -= 1; 485c9447c75SAlexander Leidinger tv.tv_usec += 1000000; 486c9447c75SAlexander Leidinger } 487c9447c75SAlexander Leidinger if (tv.tv_sec < 0) 488c9447c75SAlexander Leidinger timevalclear(&tv); 489c9447c75SAlexander Leidinger #ifdef DEBUG 490c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 4918c50c562SDmitry Chagin printf(LMSG("linux_rt_sigtimedwait: " 4928c50c562SDmitry Chagin "converted timeout (%jd/%ld)\n"), 49359038483SXin LI (intmax_t)tv.tv_sec, tv.tv_usec); 494c9447c75SAlexander Leidinger #endif 495c9447c75SAlexander Leidinger } 496c9447c75SAlexander Leidinger TIMEVAL_TO_TIMESPEC(&tv, &ts); 497c9447c75SAlexander Leidinger tsa = &ts; 498c9447c75SAlexander Leidinger } 499c9447c75SAlexander Leidinger error = kern_sigtimedwait(td, bset, &info, tsa); 500c9447c75SAlexander Leidinger #ifdef DEBUG 501c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 5028c50c562SDmitry Chagin printf(LMSG("linux_rt_sigtimedwait: " 5038c50c562SDmitry Chagin "sigtimedwait returning (%d)\n"), error); 504c9447c75SAlexander Leidinger #endif 505c9447c75SAlexander Leidinger if (error) 506c9447c75SAlexander Leidinger return (error); 507c9447c75SAlexander Leidinger 508f3481dd9SDmitry Chagin sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo); 509f3481dd9SDmitry Chagin 510c9447c75SAlexander Leidinger if (args->ptr) { 511c9447c75SAlexander Leidinger memset(&linfo, 0, sizeof(linfo)); 512f3481dd9SDmitry Chagin ksiginfo_to_lsiginfo(&info, &linfo, sig); 513c9447c75SAlexander Leidinger error = copyout(&linfo, args->ptr, sizeof(linfo)); 514c9447c75SAlexander Leidinger } 515f3481dd9SDmitry Chagin if (error == 0) 516f3481dd9SDmitry Chagin td->td_retval[0] = sig; 517c9447c75SAlexander Leidinger 518c9447c75SAlexander Leidinger return (error); 519c9447c75SAlexander Leidinger } 520c9447c75SAlexander Leidinger 521c21dee17SSøren Schmidt int 522b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args) 523c21dee17SSøren Schmidt { 524ef04503dSPeter Wemm struct kill_args /* { 525c21dee17SSøren Schmidt int pid; 526c21dee17SSøren Schmidt int signum; 527ef04503dSPeter Wemm } */ tmp; 528c21dee17SSøren Schmidt 529c21dee17SSøren Schmidt #ifdef DEBUG 53024593369SJonathan Lemon if (ldebug(kill)) 53124593369SJonathan Lemon printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 532c21dee17SSøren Schmidt #endif 533956d3333SMarcel Moolenaar 534956d3333SMarcel Moolenaar /* 535956d3333SMarcel Moolenaar * Allow signal 0 as a means to check for privileges 536956d3333SMarcel Moolenaar */ 53764742216SAlexander Leidinger if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 5389a6a64d3SDmitry Chagin return (EINVAL); 539956d3333SMarcel Moolenaar 540956d3333SMarcel Moolenaar if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) 541956d3333SMarcel Moolenaar tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; 542956d3333SMarcel Moolenaar else 543956d3333SMarcel Moolenaar tmp.signum = args->signum; 544956d3333SMarcel Moolenaar 545c21dee17SSøren Schmidt tmp.pid = args->pid; 5468451d0ddSKip Macy return (sys_kill(td, &tmp)); 547c21dee17SSøren Schmidt } 5489b44bfc5SAlexander Leidinger 549aa8b2011SKonstantin Belousov static int 55081338031SDmitry Chagin linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 551aa8b2011SKonstantin Belousov { 552aa8b2011SKonstantin Belousov struct proc *p; 553aa8b2011SKonstantin Belousov int error; 554aa8b2011SKonstantin Belousov 55581338031SDmitry Chagin p = tdt->td_proc; 55681338031SDmitry Chagin AUDIT_ARG_SIGNUM(ksi->ksi_signo); 55781338031SDmitry Chagin AUDIT_ARG_PID(p->p_pid); 55814961ba7SRobert Watson AUDIT_ARG_PROCESS(p); 55981338031SDmitry Chagin 56081338031SDmitry Chagin error = p_cansignal(td, p, ksi->ksi_signo); 56181338031SDmitry Chagin if (error != 0 || ksi->ksi_signo == 0) 562aa8b2011SKonstantin Belousov goto out; 563aa8b2011SKonstantin Belousov 56481338031SDmitry Chagin tdksignal(tdt, ksi->ksi_signo, ksi); 565aa8b2011SKonstantin Belousov 566aa8b2011SKonstantin Belousov out: 567aa8b2011SKonstantin Belousov PROC_UNLOCK(p); 568aa8b2011SKonstantin Belousov return (error); 569aa8b2011SKonstantin Belousov } 570aa8b2011SKonstantin Belousov 5719b44bfc5SAlexander Leidinger int 5729b44bfc5SAlexander Leidinger linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 5739b44bfc5SAlexander Leidinger { 57481338031SDmitry Chagin struct thread *tdt; 57581338031SDmitry Chagin ksiginfo_t ksi; 57681338031SDmitry Chagin int sig; 5779b44bfc5SAlexander Leidinger 5789b44bfc5SAlexander Leidinger #ifdef DEBUG 5799b44bfc5SAlexander Leidinger if (ldebug(tgkill)) 58081338031SDmitry Chagin printf(ARGS(tgkill, "%d, %d, %d"), 58181338031SDmitry Chagin args->tgid, args->pid, args->sig); 5829b44bfc5SAlexander Leidinger #endif 58381338031SDmitry Chagin 584aa8b2011SKonstantin Belousov if (args->pid <= 0 || args->tgid <=0) 585aa8b2011SKonstantin Belousov return (EINVAL); 5869b44bfc5SAlexander Leidinger 58781338031SDmitry Chagin /* 58881338031SDmitry Chagin * Allow signal 0 as a means to check for privileges 58981338031SDmitry Chagin */ 59081338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 59181338031SDmitry Chagin return (EINVAL); 59281338031SDmitry Chagin 59381338031SDmitry Chagin if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 59481338031SDmitry Chagin sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 59581338031SDmitry Chagin else 59681338031SDmitry Chagin sig = args->sig; 59781338031SDmitry Chagin 59881338031SDmitry Chagin tdt = linux_tdfind(td, args->pid, args->tgid); 59981338031SDmitry Chagin if (tdt == NULL) 60081338031SDmitry Chagin return (ESRCH); 60181338031SDmitry Chagin 60281338031SDmitry Chagin ksiginfo_init(&ksi); 60381338031SDmitry Chagin ksi.ksi_signo = sig; 604fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 60581338031SDmitry Chagin ksi.ksi_errno = 0; 60681338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 60781338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 60881338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 6099b44bfc5SAlexander Leidinger } 6109b44bfc5SAlexander Leidinger 61181338031SDmitry Chagin /* 61281338031SDmitry Chagin * Deprecated since 2.5.75. Replaced by tgkill(). 61381338031SDmitry Chagin */ 6149b44bfc5SAlexander Leidinger int 6159b44bfc5SAlexander Leidinger linux_tkill(struct thread *td, struct linux_tkill_args *args) 6169b44bfc5SAlexander Leidinger { 61781338031SDmitry Chagin struct thread *tdt; 61881338031SDmitry Chagin ksiginfo_t ksi; 61981338031SDmitry Chagin int sig; 62081338031SDmitry Chagin 6219b44bfc5SAlexander Leidinger #ifdef DEBUG 6229b44bfc5SAlexander Leidinger if (ldebug(tkill)) 6239b44bfc5SAlexander Leidinger printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 6249b44bfc5SAlexander Leidinger #endif 625aa8b2011SKonstantin Belousov if (args->tid <= 0) 626aa8b2011SKonstantin Belousov return (EINVAL); 6279b44bfc5SAlexander Leidinger 62881338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 62981338031SDmitry Chagin return (EINVAL); 63081338031SDmitry Chagin 63181338031SDmitry Chagin if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 63281338031SDmitry Chagin sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 63381338031SDmitry Chagin else 63481338031SDmitry Chagin sig = args->sig; 63581338031SDmitry Chagin 63681338031SDmitry Chagin tdt = linux_tdfind(td, args->tid, -1); 63781338031SDmitry Chagin if (tdt == NULL) 63881338031SDmitry Chagin return (ESRCH); 63981338031SDmitry Chagin 64081338031SDmitry Chagin ksiginfo_init(&ksi); 64181338031SDmitry Chagin ksi.ksi_signo = sig; 642fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 64381338031SDmitry Chagin ksi.ksi_errno = 0; 64481338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 64581338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 64681338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 647aa8b2011SKonstantin Belousov } 648aa8b2011SKonstantin Belousov 649aa8b2011SKonstantin Belousov void 650fe4ed1e7SDmitry Chagin ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 651aa8b2011SKonstantin Belousov { 652aa8b2011SKonstantin Belousov 653fe4ed1e7SDmitry Chagin siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); 654fe4ed1e7SDmitry Chagin } 655aa8b2011SKonstantin Belousov 656fe4ed1e7SDmitry Chagin static void 657fe4ed1e7SDmitry Chagin sicode_to_lsicode(int si_code, int *lsi_code) 658fe4ed1e7SDmitry Chagin { 659fe4ed1e7SDmitry Chagin 660fe4ed1e7SDmitry Chagin switch (si_code) { 661fe4ed1e7SDmitry Chagin case SI_USER: 662fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_USER; 663fe4ed1e7SDmitry Chagin break; 664fe4ed1e7SDmitry Chagin case SI_KERNEL: 665fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_KERNEL; 666fe4ed1e7SDmitry Chagin break; 667fe4ed1e7SDmitry Chagin case SI_QUEUE: 668fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_QUEUE; 669fe4ed1e7SDmitry Chagin break; 670fe4ed1e7SDmitry Chagin case SI_TIMER: 671fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TIMER; 672fe4ed1e7SDmitry Chagin break; 673fe4ed1e7SDmitry Chagin case SI_MESGQ: 674fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_MESGQ; 675fe4ed1e7SDmitry Chagin break; 676fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 677fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_ASYNCIO; 678fe4ed1e7SDmitry Chagin break; 679fe4ed1e7SDmitry Chagin case SI_LWP: 680fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TKILL; 681fe4ed1e7SDmitry Chagin break; 682fe4ed1e7SDmitry Chagin default: 683fe4ed1e7SDmitry Chagin *lsi_code = si_code; 684fe4ed1e7SDmitry Chagin break; 685fe4ed1e7SDmitry Chagin } 686fe4ed1e7SDmitry Chagin } 687fe4ed1e7SDmitry Chagin 688fe4ed1e7SDmitry Chagin void 689fe4ed1e7SDmitry Chagin siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 690fe4ed1e7SDmitry Chagin { 691fe4ed1e7SDmitry Chagin 692fe4ed1e7SDmitry Chagin /* sig alredy converted */ 693fe4ed1e7SDmitry Chagin lsi->lsi_signo = sig; 694fe4ed1e7SDmitry Chagin sicode_to_lsicode(si->si_code, &lsi->lsi_code); 695fe4ed1e7SDmitry Chagin 696fe4ed1e7SDmitry Chagin switch (si->si_code) { 697fe4ed1e7SDmitry Chagin case SI_LWP: 698fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 699fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 700fe4ed1e7SDmitry Chagin break; 701fe4ed1e7SDmitry Chagin 702fe4ed1e7SDmitry Chagin case SI_TIMER: 703fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 704fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 705fe4ed1e7SDmitry Chagin lsi->lsi_tid = si->si_timerid; 706fe4ed1e7SDmitry Chagin break; 707fe4ed1e7SDmitry Chagin 708fe4ed1e7SDmitry Chagin case SI_QUEUE: 709fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 710fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 711fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 712fe4ed1e7SDmitry Chagin break; 713fe4ed1e7SDmitry Chagin 714fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 715fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 716fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 717fe4ed1e7SDmitry Chagin break; 718fe4ed1e7SDmitry Chagin 719fe4ed1e7SDmitry Chagin default: 720aa8b2011SKonstantin Belousov switch (sig) { 721aa8b2011SKonstantin Belousov case LINUX_SIGPOLL: 722aa8b2011SKonstantin Belousov /* XXX si_fd? */ 723fe4ed1e7SDmitry Chagin lsi->lsi_band = si->si_band; 724aa8b2011SKonstantin Belousov break; 725fe4ed1e7SDmitry Chagin 726aa8b2011SKonstantin Belousov case LINUX_SIGCHLD: 727fe4ed1e7SDmitry Chagin lsi->lsi_errno = 0; 728fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 729fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 730fe4ed1e7SDmitry Chagin 731fe4ed1e7SDmitry Chagin if (si->si_code == CLD_STOPPED) 732fe4ed1e7SDmitry Chagin lsi->lsi_status = BSD_TO_LINUX_SIGNAL(si->si_status); 733fe4ed1e7SDmitry Chagin else if (si->si_code == CLD_CONTINUED) 734fe4ed1e7SDmitry Chagin lsi->lsi_status = BSD_TO_LINUX_SIGNAL(SIGCONT); 735fe4ed1e7SDmitry Chagin else 736fe4ed1e7SDmitry Chagin lsi->lsi_status = si->si_status; 737aa8b2011SKonstantin Belousov break; 738fe4ed1e7SDmitry Chagin 739aa8b2011SKonstantin Belousov case LINUX_SIGBUS: 740aa8b2011SKonstantin Belousov case LINUX_SIGILL: 741aa8b2011SKonstantin Belousov case LINUX_SIGFPE: 742aa8b2011SKonstantin Belousov case LINUX_SIGSEGV: 743fe4ed1e7SDmitry Chagin lsi->lsi_addr = PTROUT(si->si_addr); 744aa8b2011SKonstantin Belousov break; 745fe4ed1e7SDmitry Chagin 746aa8b2011SKonstantin Belousov default: 747fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 748fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 749fe4ed1e7SDmitry Chagin if (sig >= LINUX_SIGRTMIN) { 750fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 751fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 752fe4ed1e7SDmitry Chagin } 753aa8b2011SKonstantin Belousov break; 754aa8b2011SKonstantin Belousov } 755fe4ed1e7SDmitry Chagin break; 75609d6cb0aSDmitry Chagin } 7579b44bfc5SAlexander Leidinger } 7587ac9766dSDmitry Chagin 7597ac9766dSDmitry Chagin void 7607ac9766dSDmitry Chagin lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig) 7617ac9766dSDmitry Chagin { 7627ac9766dSDmitry Chagin 7637ac9766dSDmitry Chagin ksi->ksi_signo = sig; 7647ac9766dSDmitry Chagin ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */ 7657ac9766dSDmitry Chagin ksi->ksi_pid = lsi->lsi_pid; 7667ac9766dSDmitry Chagin ksi->ksi_uid = lsi->lsi_uid; 7677ac9766dSDmitry Chagin ksi->ksi_status = lsi->lsi_status; 7687ac9766dSDmitry Chagin ksi->ksi_addr = PTRIN(lsi->lsi_addr); 7697ac9766dSDmitry Chagin ksi->ksi_info.si_value.sival_int = lsi->lsi_int; 7707ac9766dSDmitry Chagin } 7717ac9766dSDmitry Chagin 7727ac9766dSDmitry Chagin int 7737ac9766dSDmitry Chagin linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) 7747ac9766dSDmitry Chagin { 7757ac9766dSDmitry Chagin l_siginfo_t linfo; 7767ac9766dSDmitry Chagin struct proc *p; 7777ac9766dSDmitry Chagin ksiginfo_t ksi; 7787ac9766dSDmitry Chagin int error; 7797ac9766dSDmitry Chagin int sig; 7807ac9766dSDmitry Chagin 7817ac9766dSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 7827ac9766dSDmitry Chagin return (EINVAL); 7837ac9766dSDmitry Chagin 7847ac9766dSDmitry Chagin error = copyin(args->info, &linfo, sizeof(linfo)); 7857ac9766dSDmitry Chagin if (error != 0) 7867ac9766dSDmitry Chagin return (error); 7877ac9766dSDmitry Chagin 7887ac9766dSDmitry Chagin if (linfo.lsi_code >= 0) 7897ac9766dSDmitry Chagin return (EPERM); 7907ac9766dSDmitry Chagin 7917ac9766dSDmitry Chagin if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 7927ac9766dSDmitry Chagin sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 7937ac9766dSDmitry Chagin else 7947ac9766dSDmitry Chagin sig = args->sig; 7957ac9766dSDmitry Chagin 7967ac9766dSDmitry Chagin error = ESRCH; 7977ac9766dSDmitry Chagin if ((p = pfind(args->pid)) != NULL || 7987ac9766dSDmitry Chagin (p = zpfind(args->pid)) != NULL) { 7997ac9766dSDmitry Chagin error = p_cansignal(td, p, sig); 8007ac9766dSDmitry Chagin if (error != 0) { 8017ac9766dSDmitry Chagin PROC_UNLOCK(p); 8027ac9766dSDmitry Chagin return (error); 8037ac9766dSDmitry Chagin } 8047ac9766dSDmitry Chagin 8057ac9766dSDmitry Chagin ksiginfo_init(&ksi); 8067ac9766dSDmitry Chagin lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 8077ac9766dSDmitry Chagin error = tdsendsignal(p, NULL, sig, &ksi); 8087ac9766dSDmitry Chagin PROC_UNLOCK(p); 8097ac9766dSDmitry Chagin } 8107ac9766dSDmitry Chagin 8117ac9766dSDmitry Chagin return (error); 8127ac9766dSDmitry Chagin } 813