1c21dee17SSøren Schmidt /*- 2*7f2d13d6SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*7f2d13d6SPedro F. Giffuni * 49a14aa01SUlrich Spörlein * Copyright (c) 1994-1995 Søren Schmidt 5c21dee17SSøren Schmidt * All rights reserved. 6c21dee17SSøren Schmidt * 7c21dee17SSøren Schmidt * Redistribution and use in source and binary forms, with or without 8c21dee17SSøren Schmidt * modification, are permitted provided that the following conditions 9c21dee17SSøren Schmidt * are met: 10c21dee17SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 11c21dee17SSøren Schmidt * notice, this list of conditions and the following disclaimer 12c21dee17SSøren Schmidt * in this position and unchanged. 13c21dee17SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 14c21dee17SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 15c21dee17SSøren Schmidt * documentation and/or other materials provided with the distribution. 16c21dee17SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1721dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 18c21dee17SSøren Schmidt * 19c21dee17SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20c21dee17SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21c21dee17SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22c21dee17SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23c21dee17SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24c21dee17SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25c21dee17SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26c21dee17SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27c21dee17SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28c21dee17SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29c21dee17SSøren Schmidt */ 30c21dee17SSøren Schmidt 3116dbc7f2SDavid E. O'Brien #include <sys/cdefs.h> 321e8d246eSNate Lawson __FBSDID("$FreeBSD$"); 3316dbc7f2SDavid E. O'Brien 34c21dee17SSøren Schmidt #include <sys/param.h> 35c21dee17SSøren Schmidt #include <sys/systm.h> 36fb919e4dSMark Murray #include <sys/lock.h> 37fb919e4dSMark Murray #include <sys/mutex.h> 3829ddc19bSAlexander Leidinger #include <sys/sx.h> 39c21dee17SSøren Schmidt #include <sys/proc.h> 40c21dee17SSøren Schmidt #include <sys/signalvar.h> 41206a5d3aSIan Dowse #include <sys/syscallsubr.h> 42fb919e4dSMark Murray #include <sys/sysproto.h> 43c21dee17SSøren Schmidt 44aa8b2011SKonstantin Belousov #include <security/audit/audit.h> 45aa8b2011SKonstantin Belousov 46aefce619SRuslan Ermilov #include "opt_compat.h" 47aefce619SRuslan Ermilov 481997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 494af27623STim J. Robbins #include <machine/../linux32/linux.h> 504af27623STim J. Robbins #include <machine/../linux32/linux32_proto.h> 511997c537SDavid E. O'Brien #else 521997c537SDavid E. O'Brien #include <machine/../linux/linux.h> 531997c537SDavid E. O'Brien #include <machine/../linux/linux_proto.h> 544af27623STim J. Robbins #endif 55ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_signal.h> 56ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_util.h> 579b44bfc5SAlexander Leidinger #include <compat/linux/linux_emul.h> 5881338031SDmitry Chagin #include <compat/linux/linux_misc.h> 5981338031SDmitry Chagin 6081338031SDmitry Chagin static int linux_do_tkill(struct thread *td, struct thread *tdt, 6181338031SDmitry Chagin ksiginfo_t *ksi); 62fe4ed1e7SDmitry Chagin static void sicode_to_lsicode(int si_code, int *lsi_code); 63fe4ed1e7SDmitry Chagin 649b44bfc5SAlexander Leidinger 65a1ebcbfbSPeter Wemm static void 665002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 67d66a5066SPeter Wemm { 68956d3333SMarcel Moolenaar 69956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 704af27623STim J. Robbins bsa->sa_handler = PTRIN(lsa->lsa_handler); 71d66a5066SPeter Wemm bsa->sa_flags = 0; 728f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 73d66a5066SPeter Wemm bsa->sa_flags |= SA_NOCLDSTOP; 7406ebbe77SMarcel Moolenaar if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 7506ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_NOCLDWAIT; 7606ebbe77SMarcel Moolenaar if (lsa->lsa_flags & LINUX_SA_SIGINFO) 7706ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_SIGINFO; 788f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_ONSTACK) 79d66a5066SPeter Wemm bsa->sa_flags |= SA_ONSTACK; 808f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_RESTART) 81d66a5066SPeter Wemm bsa->sa_flags |= SA_RESTART; 828f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_ONESHOT) 83d66a5066SPeter Wemm bsa->sa_flags |= SA_RESETHAND; 848f437f44SMartin Cracauer if (lsa->lsa_flags & LINUX_SA_NOMASK) 85d66a5066SPeter Wemm bsa->sa_flags |= SA_NODEFER; 86d66a5066SPeter Wemm } 87d66a5066SPeter Wemm 88a1ebcbfbSPeter Wemm static void 895002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 90d66a5066SPeter Wemm { 91956d3333SMarcel Moolenaar 92956d3333SMarcel Moolenaar bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 931997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 944af27623STim J. Robbins lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 954af27623STim J. Robbins #else 968f437f44SMartin Cracauer lsa->lsa_handler = bsa->sa_handler; 974af27623STim J. Robbins #endif 984af27623STim J. Robbins lsa->lsa_restorer = 0; /* unsupported */ 998f437f44SMartin Cracauer lsa->lsa_flags = 0; 100d66a5066SPeter Wemm if (bsa->sa_flags & SA_NOCLDSTOP) 1018f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 10206ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_NOCLDWAIT) 10306ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 10406ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_SIGINFO) 10506ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_SIGINFO; 106d66a5066SPeter Wemm if (bsa->sa_flags & SA_ONSTACK) 1078f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONSTACK; 108d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESTART) 1098f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_RESTART; 110d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESETHAND) 1118f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONESHOT; 112d66a5066SPeter Wemm if (bsa->sa_flags & SA_NODEFER) 1138f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOMASK; 114d66a5066SPeter Wemm } 115c21dee17SSøren Schmidt 116ba9ef45bSMarcel Moolenaar int 117b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 1185002a60fSMarcel Moolenaar l_sigaction_t *linux_osa) 11906ebbe77SMarcel Moolenaar { 120206a5d3aSIan Dowse struct sigaction act, oact, *nsa, *osa; 121206a5d3aSIan Dowse int error, sig; 12206ebbe77SMarcel Moolenaar 123687c23beSAlexander Leidinger if (!LINUX_SIG_VALID(linux_sig)) 124956d3333SMarcel Moolenaar return (EINVAL); 12506ebbe77SMarcel Moolenaar 126206a5d3aSIan Dowse osa = (linux_osa != NULL) ? &oact : NULL; 127956d3333SMarcel Moolenaar if (linux_nsa != NULL) { 128206a5d3aSIan Dowse nsa = &act; 129ec99e322SMarcel Moolenaar linux_to_bsd_sigaction(linux_nsa, nsa); 130206a5d3aSIan Dowse } else 13106ebbe77SMarcel Moolenaar nsa = NULL; 1324ab7403bSDmitry Chagin sig = linux_to_bsd_signal(linux_sig); 133956d3333SMarcel Moolenaar 134206a5d3aSIan Dowse error = kern_sigaction(td, sig, nsa, osa, 0); 13506ebbe77SMarcel Moolenaar if (error) 136956d3333SMarcel Moolenaar return (error); 13706ebbe77SMarcel Moolenaar 138ec99e322SMarcel Moolenaar if (linux_osa != NULL) 139ec99e322SMarcel Moolenaar bsd_to_linux_sigaction(osa, linux_osa); 14006ebbe77SMarcel Moolenaar 141956d3333SMarcel Moolenaar return (0); 14206ebbe77SMarcel Moolenaar } 14306ebbe77SMarcel Moolenaar 1447f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 145c21dee17SSøren Schmidt int 146b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args) 147d66a5066SPeter Wemm { 1485002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 149d66a5066SPeter Wemm int error; 150d66a5066SPeter Wemm 151d66a5066SPeter Wemm #ifdef DEBUG 15224593369SJonathan Lemon if (ldebug(signal)) 15324593369SJonathan Lemon printf(ARGS(signal, "%d, %p"), 154b61c60d4SDavid E. O'Brien args->sig, (void *)(uintptr_t)args->handler); 155d66a5066SPeter Wemm #endif 156d66a5066SPeter Wemm 15706ebbe77SMarcel Moolenaar nsa.lsa_handler = args->handler; 15806ebbe77SMarcel Moolenaar nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 159956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(nsa.lsa_mask); 160d66a5066SPeter Wemm 161b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, &nsa, &osa); 1624af27623STim J. Robbins td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 163d66a5066SPeter Wemm 164956d3333SMarcel Moolenaar return (error); 165d66a5066SPeter Wemm } 1667f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 167d66a5066SPeter Wemm 168c21dee17SSøren Schmidt int 169b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 170c21dee17SSøren Schmidt { 1715002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 17206ebbe77SMarcel Moolenaar int error; 173c21dee17SSøren Schmidt 174c21dee17SSøren Schmidt #ifdef DEBUG 17524593369SJonathan Lemon if (ldebug(rt_sigaction)) 17624593369SJonathan Lemon printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 17724593369SJonathan Lemon (long)args->sig, (void *)args->act, 1785231fb20SDavid E. O'Brien (void *)args->oact, (long)args->sigsetsize); 179c21dee17SSøren Schmidt #endif 180d66a5066SPeter Wemm 1815002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 182956d3333SMarcel Moolenaar return (EINVAL); 18306ebbe77SMarcel Moolenaar 184956d3333SMarcel Moolenaar if (args->act != NULL) { 1855002a60fSMarcel Moolenaar error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 18606ebbe77SMarcel Moolenaar if (error) 187956d3333SMarcel Moolenaar return (error); 18806ebbe77SMarcel Moolenaar } 18906ebbe77SMarcel Moolenaar 190b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, 19106ebbe77SMarcel Moolenaar args->act ? &nsa : NULL, 19206ebbe77SMarcel Moolenaar args->oact ? &osa : NULL); 19306ebbe77SMarcel Moolenaar 194956d3333SMarcel Moolenaar if (args->oact != NULL && !error) { 1955002a60fSMarcel Moolenaar error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 19606ebbe77SMarcel Moolenaar } 19706ebbe77SMarcel Moolenaar 198956d3333SMarcel Moolenaar return (error); 19906ebbe77SMarcel Moolenaar } 20006ebbe77SMarcel Moolenaar 20106ebbe77SMarcel Moolenaar static int 202b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 2035002a60fSMarcel Moolenaar l_sigset_t *old) 20406ebbe77SMarcel Moolenaar { 205fe8cdcaeSJohn Baldwin sigset_t omask, nmask; 206fe8cdcaeSJohn Baldwin sigset_t *nmaskp; 207216af822SJohn Baldwin int error; 20806ebbe77SMarcel Moolenaar 209b40ce416SJulian Elischer td->td_retval[0] = 0; 210d66a5066SPeter Wemm 21119dde5cdSJohn Baldwin switch (how) { 21219dde5cdSJohn Baldwin case LINUX_SIG_BLOCK: 21319dde5cdSJohn Baldwin how = SIG_BLOCK; 21419dde5cdSJohn Baldwin break; 21519dde5cdSJohn Baldwin case LINUX_SIG_UNBLOCK: 21619dde5cdSJohn Baldwin how = SIG_UNBLOCK; 21719dde5cdSJohn Baldwin break; 21819dde5cdSJohn Baldwin case LINUX_SIG_SETMASK: 21919dde5cdSJohn Baldwin how = SIG_SETMASK; 22019dde5cdSJohn Baldwin break; 22119dde5cdSJohn Baldwin default: 22219dde5cdSJohn Baldwin return (EINVAL); 22319dde5cdSJohn Baldwin } 22406ebbe77SMarcel Moolenaar if (new != NULL) { 225fe8cdcaeSJohn Baldwin linux_to_bsd_sigset(new, &nmask); 226fe8cdcaeSJohn Baldwin nmaskp = &nmask; 227fe8cdcaeSJohn Baldwin } else 228fe8cdcaeSJohn Baldwin nmaskp = NULL; 22919dde5cdSJohn Baldwin error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 2302f7ed219SJohn Baldwin if (error == 0 && old != NULL) 231fe8cdcaeSJohn Baldwin bsd_to_linux_sigset(&omask, old); 23206ebbe77SMarcel Moolenaar 233956d3333SMarcel Moolenaar return (error); 23406ebbe77SMarcel Moolenaar } 23506ebbe77SMarcel Moolenaar 2367f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 23706ebbe77SMarcel Moolenaar int 238b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 23906ebbe77SMarcel Moolenaar { 2405002a60fSMarcel Moolenaar l_osigset_t mask; 2415002a60fSMarcel Moolenaar l_sigset_t set, oset; 24206ebbe77SMarcel Moolenaar int error; 24306ebbe77SMarcel Moolenaar 24406ebbe77SMarcel Moolenaar #ifdef DEBUG 24524593369SJonathan Lemon if (ldebug(sigprocmask)) 24624593369SJonathan Lemon printf(ARGS(sigprocmask, "%d, *, *"), args->how); 24706ebbe77SMarcel Moolenaar #endif 24806ebbe77SMarcel Moolenaar 24906ebbe77SMarcel Moolenaar if (args->mask != NULL) { 2505002a60fSMarcel Moolenaar error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 25106ebbe77SMarcel Moolenaar if (error) 252956d3333SMarcel Moolenaar return (error); 253956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(set); 2544ab7403bSDmitry Chagin set.__mask = mask; 25506ebbe77SMarcel Moolenaar } 25606ebbe77SMarcel Moolenaar 257b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 258956d3333SMarcel Moolenaar args->mask ? &set : NULL, 259956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 26006ebbe77SMarcel Moolenaar 261956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 2624ab7403bSDmitry Chagin mask = oset.__mask; 2635002a60fSMarcel Moolenaar error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 26406ebbe77SMarcel Moolenaar } 26506ebbe77SMarcel Moolenaar 266956d3333SMarcel Moolenaar return (error); 26706ebbe77SMarcel Moolenaar } 2687f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 26906ebbe77SMarcel Moolenaar 27006ebbe77SMarcel Moolenaar int 271b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 27206ebbe77SMarcel Moolenaar { 2735002a60fSMarcel Moolenaar l_sigset_t set, oset; 27406ebbe77SMarcel Moolenaar int error; 27506ebbe77SMarcel Moolenaar 27606ebbe77SMarcel Moolenaar #ifdef DEBUG 27724593369SJonathan Lemon if (ldebug(rt_sigprocmask)) 27824593369SJonathan Lemon printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 27924593369SJonathan Lemon args->how, (void *)args->mask, 2805231fb20SDavid E. O'Brien (void *)args->omask, (long)args->sigsetsize); 28106ebbe77SMarcel Moolenaar #endif 28206ebbe77SMarcel Moolenaar 2835002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 28406ebbe77SMarcel Moolenaar return EINVAL; 28506ebbe77SMarcel Moolenaar 28606ebbe77SMarcel Moolenaar if (args->mask != NULL) { 2875002a60fSMarcel Moolenaar error = copyin(args->mask, &set, sizeof(l_sigset_t)); 28806ebbe77SMarcel Moolenaar if (error) 289956d3333SMarcel Moolenaar return (error); 29006ebbe77SMarcel Moolenaar } 29106ebbe77SMarcel Moolenaar 292b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 293956d3333SMarcel Moolenaar args->mask ? &set : NULL, 294956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 29506ebbe77SMarcel Moolenaar 296956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 2975002a60fSMarcel Moolenaar error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 29806ebbe77SMarcel Moolenaar } 29906ebbe77SMarcel Moolenaar 300956d3333SMarcel Moolenaar return (error); 301c21dee17SSøren Schmidt } 302c21dee17SSøren Schmidt 3037f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 304c21dee17SSøren Schmidt int 305b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 306c21dee17SSøren Schmidt { 307b40ce416SJulian Elischer struct proc *p = td->td_proc; 3085002a60fSMarcel Moolenaar l_sigset_t mask; 309956d3333SMarcel Moolenaar 310c21dee17SSøren Schmidt #ifdef DEBUG 3115002a60fSMarcel Moolenaar if (ldebug(sgetmask)) 3125002a60fSMarcel Moolenaar printf(ARGS(sgetmask, "")); 313c21dee17SSøren Schmidt #endif 314956d3333SMarcel Moolenaar 315216af822SJohn Baldwin PROC_LOCK(p); 3164093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &mask); 317216af822SJohn Baldwin PROC_UNLOCK(p); 3184ab7403bSDmitry Chagin td->td_retval[0] = mask.__mask; 319956d3333SMarcel Moolenaar return (0); 320c21dee17SSøren Schmidt } 321c21dee17SSøren Schmidt 322c21dee17SSøren Schmidt int 323b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 324c21dee17SSøren Schmidt { 325b40ce416SJulian Elischer struct proc *p = td->td_proc; 3265002a60fSMarcel Moolenaar l_sigset_t lset; 327956d3333SMarcel Moolenaar sigset_t bset; 328c21dee17SSøren Schmidt 329c21dee17SSøren Schmidt #ifdef DEBUG 3305002a60fSMarcel Moolenaar if (ldebug(ssetmask)) 3315002a60fSMarcel Moolenaar printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 332c21dee17SSøren Schmidt #endif 333d66a5066SPeter Wemm 334216af822SJohn Baldwin PROC_LOCK(p); 3354093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &lset); 3364ab7403bSDmitry Chagin td->td_retval[0] = lset.__mask; 337956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(lset); 3384ab7403bSDmitry Chagin lset.__mask = args->mask; 339956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lset, &bset); 3404093529dSJeff Roberson td->td_sigmask = bset; 3414093529dSJeff Roberson SIG_CANTMASK(td->td_sigmask); 3424093529dSJeff Roberson signotify(td); 343216af822SJohn Baldwin PROC_UNLOCK(p); 344956d3333SMarcel Moolenaar return (0); 345c21dee17SSøren Schmidt } 346c21dee17SSøren Schmidt 347c21dee17SSøren Schmidt int 348b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 349c21dee17SSøren Schmidt { 350b40ce416SJulian Elischer struct proc *p = td->td_proc; 351956d3333SMarcel Moolenaar sigset_t bset; 3525002a60fSMarcel Moolenaar l_sigset_t lset; 3535002a60fSMarcel Moolenaar l_osigset_t mask; 354c21dee17SSøren Schmidt 355c21dee17SSøren Schmidt #ifdef DEBUG 35624593369SJonathan Lemon if (ldebug(sigpending)) 35724593369SJonathan Lemon printf(ARGS(sigpending, "*")); 358c21dee17SSøren Schmidt #endif 359956d3333SMarcel Moolenaar 360216af822SJohn Baldwin PROC_LOCK(p); 3611d9c5696SJuli Mallett bset = p->p_siglist; 3624093529dSJeff Roberson SIGSETOR(bset, td->td_siglist); 3634093529dSJeff Roberson SIGSETAND(bset, td->td_sigmask); 364216af822SJohn Baldwin PROC_UNLOCK(p); 3659d8643ecSJohn Baldwin bsd_to_linux_sigset(&bset, &lset); 3664ab7403bSDmitry Chagin mask = lset.__mask; 367956d3333SMarcel Moolenaar return (copyout(&mask, args->mask, sizeof(mask))); 368c21dee17SSøren Schmidt } 3697f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 37017138b61SAlexander Leidinger 37117138b61SAlexander Leidinger /* 37217138b61SAlexander Leidinger * MPSAFE 37317138b61SAlexander Leidinger */ 37417138b61SAlexander Leidinger int 37517138b61SAlexander Leidinger linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 37617138b61SAlexander Leidinger { 37717138b61SAlexander Leidinger struct proc *p = td->td_proc; 37817138b61SAlexander Leidinger sigset_t bset; 37917138b61SAlexander Leidinger l_sigset_t lset; 38017138b61SAlexander Leidinger 38117138b61SAlexander Leidinger if (args->sigsetsize > sizeof(lset)) 38217138b61SAlexander Leidinger return EINVAL; 38317138b61SAlexander Leidinger /* NOT REACHED */ 38417138b61SAlexander Leidinger 38517138b61SAlexander Leidinger #ifdef DEBUG 38617138b61SAlexander Leidinger if (ldebug(rt_sigpending)) 38717138b61SAlexander Leidinger printf(ARGS(rt_sigpending, "*")); 38817138b61SAlexander Leidinger #endif 38917138b61SAlexander Leidinger 39017138b61SAlexander Leidinger PROC_LOCK(p); 39117138b61SAlexander Leidinger bset = p->p_siglist; 39217138b61SAlexander Leidinger SIGSETOR(bset, td->td_siglist); 39317138b61SAlexander Leidinger SIGSETAND(bset, td->td_sigmask); 39417138b61SAlexander Leidinger PROC_UNLOCK(p); 39517138b61SAlexander Leidinger bsd_to_linux_sigset(&bset, &lset); 39617138b61SAlexander Leidinger return (copyout(&lset, args->set, args->sigsetsize)); 39717138b61SAlexander Leidinger } 398c21dee17SSøren Schmidt 399c9447c75SAlexander Leidinger /* 400c9447c75SAlexander Leidinger * MPSAFE 401c9447c75SAlexander Leidinger */ 402c9447c75SAlexander Leidinger int 403c9447c75SAlexander Leidinger linux_rt_sigtimedwait(struct thread *td, 404c9447c75SAlexander Leidinger struct linux_rt_sigtimedwait_args *args) 405c9447c75SAlexander Leidinger { 406f3481dd9SDmitry Chagin int error, sig; 407c9447c75SAlexander Leidinger l_timeval ltv; 408c9447c75SAlexander Leidinger struct timeval tv; 409c9447c75SAlexander Leidinger struct timespec ts, *tsa; 410c9447c75SAlexander Leidinger l_sigset_t lset; 411c9447c75SAlexander Leidinger sigset_t bset; 412c9447c75SAlexander Leidinger l_siginfo_t linfo; 413c9447c75SAlexander Leidinger ksiginfo_t info; 414c9447c75SAlexander Leidinger 415c9447c75SAlexander Leidinger #ifdef DEBUG 416c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 417c9447c75SAlexander Leidinger printf(ARGS(rt_sigtimedwait, "*")); 418c9447c75SAlexander Leidinger #endif 419c9447c75SAlexander Leidinger if (args->sigsetsize != sizeof(l_sigset_t)) 420c9447c75SAlexander Leidinger return (EINVAL); 421c9447c75SAlexander Leidinger 422c9447c75SAlexander Leidinger if ((error = copyin(args->mask, &lset, sizeof(lset)))) 423c9447c75SAlexander Leidinger return (error); 424c9447c75SAlexander Leidinger linux_to_bsd_sigset(&lset, &bset); 425c9447c75SAlexander Leidinger 426c9447c75SAlexander Leidinger tsa = NULL; 427c9447c75SAlexander Leidinger if (args->timeout) { 428c9447c75SAlexander Leidinger if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 429c9447c75SAlexander Leidinger return (error); 430c9447c75SAlexander Leidinger #ifdef DEBUG 431c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 4328c50c562SDmitry Chagin printf(LMSG("linux_rt_sigtimedwait: " 4334ca75bedSDmitry Chagin "incoming timeout (%jd/%jd)\n"), 4344ca75bedSDmitry Chagin (intmax_t)ltv.tv_sec, (intmax_t)ltv.tv_usec); 435c9447c75SAlexander Leidinger #endif 436c9447c75SAlexander Leidinger tv.tv_sec = (long)ltv.tv_sec; 437c9447c75SAlexander Leidinger tv.tv_usec = (suseconds_t)ltv.tv_usec; 438c9447c75SAlexander Leidinger if (itimerfix(&tv)) { 439c9447c75SAlexander Leidinger /* 440c9447c75SAlexander Leidinger * The timeout was invalid. Convert it to something 441c9447c75SAlexander Leidinger * valid that will act as it does under Linux. 442c9447c75SAlexander Leidinger */ 443c9447c75SAlexander Leidinger tv.tv_sec += tv.tv_usec / 1000000; 444c9447c75SAlexander Leidinger tv.tv_usec %= 1000000; 445c9447c75SAlexander Leidinger if (tv.tv_usec < 0) { 446c9447c75SAlexander Leidinger tv.tv_sec -= 1; 447c9447c75SAlexander Leidinger tv.tv_usec += 1000000; 448c9447c75SAlexander Leidinger } 449c9447c75SAlexander Leidinger if (tv.tv_sec < 0) 450c9447c75SAlexander Leidinger timevalclear(&tv); 451c9447c75SAlexander Leidinger #ifdef DEBUG 452c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 4538c50c562SDmitry Chagin printf(LMSG("linux_rt_sigtimedwait: " 4548c50c562SDmitry Chagin "converted timeout (%jd/%ld)\n"), 45559038483SXin LI (intmax_t)tv.tv_sec, tv.tv_usec); 456c9447c75SAlexander Leidinger #endif 457c9447c75SAlexander Leidinger } 458c9447c75SAlexander Leidinger TIMEVAL_TO_TIMESPEC(&tv, &ts); 459c9447c75SAlexander Leidinger tsa = &ts; 460c9447c75SAlexander Leidinger } 461c9447c75SAlexander Leidinger error = kern_sigtimedwait(td, bset, &info, tsa); 462c9447c75SAlexander Leidinger #ifdef DEBUG 463c9447c75SAlexander Leidinger if (ldebug(rt_sigtimedwait)) 4648c50c562SDmitry Chagin printf(LMSG("linux_rt_sigtimedwait: " 4658c50c562SDmitry Chagin "sigtimedwait returning (%d)\n"), error); 466c9447c75SAlexander Leidinger #endif 467c9447c75SAlexander Leidinger if (error) 468c9447c75SAlexander Leidinger return (error); 469c9447c75SAlexander Leidinger 4704ab7403bSDmitry Chagin sig = bsd_to_linux_signal(info.ksi_signo); 471f3481dd9SDmitry Chagin 472c9447c75SAlexander Leidinger if (args->ptr) { 473c9447c75SAlexander Leidinger memset(&linfo, 0, sizeof(linfo)); 474f3481dd9SDmitry Chagin ksiginfo_to_lsiginfo(&info, &linfo, sig); 475c9447c75SAlexander Leidinger error = copyout(&linfo, args->ptr, sizeof(linfo)); 476c9447c75SAlexander Leidinger } 477f3481dd9SDmitry Chagin if (error == 0) 478f3481dd9SDmitry Chagin td->td_retval[0] = sig; 479c9447c75SAlexander Leidinger 480c9447c75SAlexander Leidinger return (error); 481c9447c75SAlexander Leidinger } 482c9447c75SAlexander Leidinger 483c21dee17SSøren Schmidt int 484b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args) 485c21dee17SSøren Schmidt { 486ef04503dSPeter Wemm struct kill_args /* { 487c21dee17SSøren Schmidt int pid; 488c21dee17SSøren Schmidt int signum; 489ef04503dSPeter Wemm } */ tmp; 490c21dee17SSøren Schmidt 491c21dee17SSøren Schmidt #ifdef DEBUG 49224593369SJonathan Lemon if (ldebug(kill)) 49324593369SJonathan Lemon printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 494c21dee17SSøren Schmidt #endif 495956d3333SMarcel Moolenaar 496956d3333SMarcel Moolenaar /* 497956d3333SMarcel Moolenaar * Allow signal 0 as a means to check for privileges 498956d3333SMarcel Moolenaar */ 49964742216SAlexander Leidinger if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 5009a6a64d3SDmitry Chagin return (EINVAL); 501956d3333SMarcel Moolenaar 5024ab7403bSDmitry Chagin if (args->signum > 0) 5034ab7403bSDmitry Chagin tmp.signum = linux_to_bsd_signal(args->signum); 504956d3333SMarcel Moolenaar else 5054ab7403bSDmitry Chagin tmp.signum = 0; 506956d3333SMarcel Moolenaar 507c21dee17SSøren Schmidt tmp.pid = args->pid; 5088451d0ddSKip Macy return (sys_kill(td, &tmp)); 509c21dee17SSøren Schmidt } 5109b44bfc5SAlexander Leidinger 511aa8b2011SKonstantin Belousov static int 51281338031SDmitry Chagin linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 513aa8b2011SKonstantin Belousov { 514aa8b2011SKonstantin Belousov struct proc *p; 515aa8b2011SKonstantin Belousov int error; 516aa8b2011SKonstantin Belousov 51781338031SDmitry Chagin p = tdt->td_proc; 51881338031SDmitry Chagin AUDIT_ARG_SIGNUM(ksi->ksi_signo); 51981338031SDmitry Chagin AUDIT_ARG_PID(p->p_pid); 52014961ba7SRobert Watson AUDIT_ARG_PROCESS(p); 52181338031SDmitry Chagin 52281338031SDmitry Chagin error = p_cansignal(td, p, ksi->ksi_signo); 52381338031SDmitry Chagin if (error != 0 || ksi->ksi_signo == 0) 524aa8b2011SKonstantin Belousov goto out; 525aa8b2011SKonstantin Belousov 52681338031SDmitry Chagin tdksignal(tdt, ksi->ksi_signo, ksi); 527aa8b2011SKonstantin Belousov 528aa8b2011SKonstantin Belousov out: 529aa8b2011SKonstantin Belousov PROC_UNLOCK(p); 530aa8b2011SKonstantin Belousov return (error); 531aa8b2011SKonstantin Belousov } 532aa8b2011SKonstantin Belousov 5339b44bfc5SAlexander Leidinger int 5349b44bfc5SAlexander Leidinger linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 5359b44bfc5SAlexander Leidinger { 53681338031SDmitry Chagin struct thread *tdt; 53781338031SDmitry Chagin ksiginfo_t ksi; 53881338031SDmitry Chagin int sig; 5399b44bfc5SAlexander Leidinger 5409b44bfc5SAlexander Leidinger #ifdef DEBUG 5419b44bfc5SAlexander Leidinger if (ldebug(tgkill)) 54281338031SDmitry Chagin printf(ARGS(tgkill, "%d, %d, %d"), 54381338031SDmitry Chagin args->tgid, args->pid, args->sig); 5449b44bfc5SAlexander Leidinger #endif 54581338031SDmitry Chagin 546aa8b2011SKonstantin Belousov if (args->pid <= 0 || args->tgid <=0) 547aa8b2011SKonstantin Belousov return (EINVAL); 5489b44bfc5SAlexander Leidinger 54981338031SDmitry Chagin /* 55081338031SDmitry Chagin * Allow signal 0 as a means to check for privileges 55181338031SDmitry Chagin */ 55281338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 55381338031SDmitry Chagin return (EINVAL); 55481338031SDmitry Chagin 5554ab7403bSDmitry Chagin if (args->sig > 0) 5564ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 55781338031SDmitry Chagin else 5584ab7403bSDmitry Chagin sig = 0; 55981338031SDmitry Chagin 56081338031SDmitry Chagin tdt = linux_tdfind(td, args->pid, args->tgid); 56181338031SDmitry Chagin if (tdt == NULL) 56281338031SDmitry Chagin return (ESRCH); 56381338031SDmitry Chagin 56481338031SDmitry Chagin ksiginfo_init(&ksi); 56581338031SDmitry Chagin ksi.ksi_signo = sig; 566fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 56781338031SDmitry Chagin ksi.ksi_errno = 0; 56881338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 56981338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 57081338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 5719b44bfc5SAlexander Leidinger } 5729b44bfc5SAlexander Leidinger 57381338031SDmitry Chagin /* 57481338031SDmitry Chagin * Deprecated since 2.5.75. Replaced by tgkill(). 57581338031SDmitry Chagin */ 5769b44bfc5SAlexander Leidinger int 5779b44bfc5SAlexander Leidinger linux_tkill(struct thread *td, struct linux_tkill_args *args) 5789b44bfc5SAlexander Leidinger { 57981338031SDmitry Chagin struct thread *tdt; 58081338031SDmitry Chagin ksiginfo_t ksi; 58181338031SDmitry Chagin int sig; 58281338031SDmitry Chagin 5839b44bfc5SAlexander Leidinger #ifdef DEBUG 5849b44bfc5SAlexander Leidinger if (ldebug(tkill)) 5859b44bfc5SAlexander Leidinger printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 5869b44bfc5SAlexander Leidinger #endif 587aa8b2011SKonstantin Belousov if (args->tid <= 0) 588aa8b2011SKonstantin Belousov return (EINVAL); 5899b44bfc5SAlexander Leidinger 59081338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 59181338031SDmitry Chagin return (EINVAL); 59281338031SDmitry Chagin 5934ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 59481338031SDmitry Chagin 59581338031SDmitry Chagin tdt = linux_tdfind(td, args->tid, -1); 59681338031SDmitry Chagin if (tdt == NULL) 59781338031SDmitry Chagin return (ESRCH); 59881338031SDmitry Chagin 59981338031SDmitry Chagin ksiginfo_init(&ksi); 60081338031SDmitry Chagin ksi.ksi_signo = sig; 601fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 60281338031SDmitry Chagin ksi.ksi_errno = 0; 60381338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 60481338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 60581338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 606aa8b2011SKonstantin Belousov } 607aa8b2011SKonstantin Belousov 608aa8b2011SKonstantin Belousov void 609fe4ed1e7SDmitry Chagin ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 610aa8b2011SKonstantin Belousov { 611aa8b2011SKonstantin Belousov 612fe4ed1e7SDmitry Chagin siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); 613fe4ed1e7SDmitry Chagin } 614aa8b2011SKonstantin Belousov 615fe4ed1e7SDmitry Chagin static void 616fe4ed1e7SDmitry Chagin sicode_to_lsicode(int si_code, int *lsi_code) 617fe4ed1e7SDmitry Chagin { 618fe4ed1e7SDmitry Chagin 619fe4ed1e7SDmitry Chagin switch (si_code) { 620fe4ed1e7SDmitry Chagin case SI_USER: 621fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_USER; 622fe4ed1e7SDmitry Chagin break; 623fe4ed1e7SDmitry Chagin case SI_KERNEL: 624fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_KERNEL; 625fe4ed1e7SDmitry Chagin break; 626fe4ed1e7SDmitry Chagin case SI_QUEUE: 627fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_QUEUE; 628fe4ed1e7SDmitry Chagin break; 629fe4ed1e7SDmitry Chagin case SI_TIMER: 630fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TIMER; 631fe4ed1e7SDmitry Chagin break; 632fe4ed1e7SDmitry Chagin case SI_MESGQ: 633fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_MESGQ; 634fe4ed1e7SDmitry Chagin break; 635fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 636fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_ASYNCIO; 637fe4ed1e7SDmitry Chagin break; 638fe4ed1e7SDmitry Chagin case SI_LWP: 639fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TKILL; 640fe4ed1e7SDmitry Chagin break; 641fe4ed1e7SDmitry Chagin default: 642fe4ed1e7SDmitry Chagin *lsi_code = si_code; 643fe4ed1e7SDmitry Chagin break; 644fe4ed1e7SDmitry Chagin } 645fe4ed1e7SDmitry Chagin } 646fe4ed1e7SDmitry Chagin 647fe4ed1e7SDmitry Chagin void 648fe4ed1e7SDmitry Chagin siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 649fe4ed1e7SDmitry Chagin { 650fe4ed1e7SDmitry Chagin 651fe4ed1e7SDmitry Chagin /* sig alredy converted */ 652fe4ed1e7SDmitry Chagin lsi->lsi_signo = sig; 653fe4ed1e7SDmitry Chagin sicode_to_lsicode(si->si_code, &lsi->lsi_code); 654fe4ed1e7SDmitry Chagin 655fe4ed1e7SDmitry Chagin switch (si->si_code) { 656fe4ed1e7SDmitry Chagin case SI_LWP: 657fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 658fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 659fe4ed1e7SDmitry Chagin break; 660fe4ed1e7SDmitry Chagin 661fe4ed1e7SDmitry Chagin case SI_TIMER: 662fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 663fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 664fe4ed1e7SDmitry Chagin lsi->lsi_tid = si->si_timerid; 665fe4ed1e7SDmitry Chagin break; 666fe4ed1e7SDmitry Chagin 667fe4ed1e7SDmitry Chagin case SI_QUEUE: 668fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 669fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 670fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 671fe4ed1e7SDmitry Chagin break; 672fe4ed1e7SDmitry Chagin 673fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 674fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 675fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 676fe4ed1e7SDmitry Chagin break; 677fe4ed1e7SDmitry Chagin 678fe4ed1e7SDmitry Chagin default: 679aa8b2011SKonstantin Belousov switch (sig) { 680aa8b2011SKonstantin Belousov case LINUX_SIGPOLL: 681aa8b2011SKonstantin Belousov /* XXX si_fd? */ 682fe4ed1e7SDmitry Chagin lsi->lsi_band = si->si_band; 683aa8b2011SKonstantin Belousov break; 684fe4ed1e7SDmitry Chagin 685aa8b2011SKonstantin Belousov case LINUX_SIGCHLD: 686fe4ed1e7SDmitry Chagin lsi->lsi_errno = 0; 687fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 688fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 689fe4ed1e7SDmitry Chagin 690fe4ed1e7SDmitry Chagin if (si->si_code == CLD_STOPPED) 6914ab7403bSDmitry Chagin lsi->lsi_status = bsd_to_linux_signal(si->si_status); 692fe4ed1e7SDmitry Chagin else if (si->si_code == CLD_CONTINUED) 6934ab7403bSDmitry Chagin lsi->lsi_status = bsd_to_linux_signal(SIGCONT); 694fe4ed1e7SDmitry Chagin else 695fe4ed1e7SDmitry Chagin lsi->lsi_status = si->si_status; 696aa8b2011SKonstantin Belousov break; 697fe4ed1e7SDmitry Chagin 698aa8b2011SKonstantin Belousov case LINUX_SIGBUS: 699aa8b2011SKonstantin Belousov case LINUX_SIGILL: 700aa8b2011SKonstantin Belousov case LINUX_SIGFPE: 701aa8b2011SKonstantin Belousov case LINUX_SIGSEGV: 702fe4ed1e7SDmitry Chagin lsi->lsi_addr = PTROUT(si->si_addr); 703aa8b2011SKonstantin Belousov break; 704fe4ed1e7SDmitry Chagin 705aa8b2011SKonstantin Belousov default: 706fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 707fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 708fe4ed1e7SDmitry Chagin if (sig >= LINUX_SIGRTMIN) { 709fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 710fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 711fe4ed1e7SDmitry Chagin } 712aa8b2011SKonstantin Belousov break; 713aa8b2011SKonstantin Belousov } 714fe4ed1e7SDmitry Chagin break; 71509d6cb0aSDmitry Chagin } 7169b44bfc5SAlexander Leidinger } 7177ac9766dSDmitry Chagin 7187ac9766dSDmitry Chagin void 7197ac9766dSDmitry Chagin lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig) 7207ac9766dSDmitry Chagin { 7217ac9766dSDmitry Chagin 7227ac9766dSDmitry Chagin ksi->ksi_signo = sig; 7237ac9766dSDmitry Chagin ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */ 7247ac9766dSDmitry Chagin ksi->ksi_pid = lsi->lsi_pid; 7257ac9766dSDmitry Chagin ksi->ksi_uid = lsi->lsi_uid; 7267ac9766dSDmitry Chagin ksi->ksi_status = lsi->lsi_status; 7277ac9766dSDmitry Chagin ksi->ksi_addr = PTRIN(lsi->lsi_addr); 7287ac9766dSDmitry Chagin ksi->ksi_info.si_value.sival_int = lsi->lsi_int; 7297ac9766dSDmitry Chagin } 7307ac9766dSDmitry Chagin 7317ac9766dSDmitry Chagin int 7327ac9766dSDmitry Chagin linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) 7337ac9766dSDmitry Chagin { 7347ac9766dSDmitry Chagin l_siginfo_t linfo; 7357ac9766dSDmitry Chagin struct proc *p; 7367ac9766dSDmitry Chagin ksiginfo_t ksi; 7377ac9766dSDmitry Chagin int error; 7387ac9766dSDmitry Chagin int sig; 7397ac9766dSDmitry Chagin 7407ac9766dSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 7417ac9766dSDmitry Chagin return (EINVAL); 7427ac9766dSDmitry Chagin 7437ac9766dSDmitry Chagin error = copyin(args->info, &linfo, sizeof(linfo)); 7447ac9766dSDmitry Chagin if (error != 0) 7457ac9766dSDmitry Chagin return (error); 7467ac9766dSDmitry Chagin 7477ac9766dSDmitry Chagin if (linfo.lsi_code >= 0) 7487ac9766dSDmitry Chagin return (EPERM); 7497ac9766dSDmitry Chagin 7504ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 7517ac9766dSDmitry Chagin 7527ac9766dSDmitry Chagin error = ESRCH; 753537d0fb1SMateusz Guzik if ((p = pfind_any(args->pid)) != NULL) { 7547ac9766dSDmitry Chagin error = p_cansignal(td, p, sig); 7557ac9766dSDmitry Chagin if (error != 0) { 7567ac9766dSDmitry Chagin PROC_UNLOCK(p); 7577ac9766dSDmitry Chagin return (error); 7587ac9766dSDmitry Chagin } 7597ac9766dSDmitry Chagin 7607ac9766dSDmitry Chagin ksiginfo_init(&ksi); 7617ac9766dSDmitry Chagin lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 7627ac9766dSDmitry Chagin error = tdsendsignal(p, NULL, sig, &ksi); 7637ac9766dSDmitry Chagin PROC_UNLOCK(p); 7647ac9766dSDmitry Chagin } 7657ac9766dSDmitry Chagin 7667ac9766dSDmitry Chagin return (error); 7677ac9766dSDmitry Chagin } 768486a06bdSDmitry Chagin 769486a06bdSDmitry Chagin int 770486a06bdSDmitry Chagin linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args) 771486a06bdSDmitry Chagin { 772486a06bdSDmitry Chagin l_siginfo_t linfo; 773486a06bdSDmitry Chagin struct thread *tds; 774486a06bdSDmitry Chagin ksiginfo_t ksi; 775486a06bdSDmitry Chagin int error; 776486a06bdSDmitry Chagin int sig; 777486a06bdSDmitry Chagin 778486a06bdSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 779486a06bdSDmitry Chagin return (EINVAL); 780486a06bdSDmitry Chagin 781486a06bdSDmitry Chagin error = copyin(args->uinfo, &linfo, sizeof(linfo)); 782486a06bdSDmitry Chagin if (error != 0) 783486a06bdSDmitry Chagin return (error); 784486a06bdSDmitry Chagin 785486a06bdSDmitry Chagin if (linfo.lsi_code >= 0) 786486a06bdSDmitry Chagin return (EPERM); 787486a06bdSDmitry Chagin 788486a06bdSDmitry Chagin tds = linux_tdfind(td, args->tid, args->tgid); 789486a06bdSDmitry Chagin if (tds == NULL) 790486a06bdSDmitry Chagin return (ESRCH); 791486a06bdSDmitry Chagin 792486a06bdSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 793486a06bdSDmitry Chagin ksiginfo_init(&ksi); 794486a06bdSDmitry Chagin lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 795486a06bdSDmitry Chagin return (linux_do_tkill(td, tds, &ksi)); 796486a06bdSDmitry Chagin } 797