19313Ssos/*- 29313Ssos * Copyright (c) 1994-1995 S�ren Schmidt 39313Ssos * All rights reserved. 49313Ssos * 59313Ssos * Redistribution and use in source and binary forms, with or without 69313Ssos * modification, are permitted provided that the following conditions 79313Ssos * are met: 89313Ssos * 1. Redistributions of source code must retain the above copyright 99313Ssos * notice, this list of conditions and the following disclaimer 109313Ssos * in this position and unchanged. 119313Ssos * 2. Redistributions in binary form must reproduce the above copyright 129313Ssos * notice, this list of conditions and the following disclaimer in the 139313Ssos * documentation and/or other materials provided with the distribution. 149313Ssos * 3. The name of the author may not be used to endorse or promote products 1597748Sschweikh * derived from this software without specific prior written permission 169313Ssos * 179313Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 189313Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 199313Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 209313Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 219313Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229313Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239313Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249313Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259313Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 269313Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279313Ssos */ 289313Ssos 29116173Sobrien#include <sys/cdefs.h> 30141829Snjl__FBSDID("$FreeBSD$"); 31116173Sobrien 329313Ssos#include <sys/param.h> 339313Ssos#include <sys/systm.h> 3476166Smarkm#include <sys/lock.h> 3576166Smarkm#include <sys/mutex.h> 36161461Snetchild#include <sys/sx.h> 379313Ssos#include <sys/proc.h> 389313Ssos#include <sys/signalvar.h> 39102814Siedowse#include <sys/syscallsubr.h> 4076166Smarkm#include <sys/sysproto.h> 419313Ssos 42184058Skib#include <security/audit/audit.h> 43184058Skib 44156874Sru#include "opt_compat.h" 45156874Sru 46140214Sobrien#ifdef COMPAT_LINUX32 47140214Sobrien#include <machine/../linux32/linux.h> 48140214Sobrien#include <machine/../linux32/linux32_proto.h> 49140214Sobrien#else 5064911Smarcel#include <machine/../linux/linux.h> 5168583Smarcel#include <machine/../linux/linux_proto.h> 52133816Stjr#endif 5364911Smarcel#include <compat/linux/linux_signal.h> 5464911Smarcel#include <compat/linux/linux_util.h> 55161310Snetchild#include <compat/linux/linux_emul.h> 569313Ssos 5764911Smarcelvoid 5883221Smarcellinux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 5951793Smarcel{ 6051793Smarcel int b, l; 619313Ssos 6251793Smarcel SIGEMPTYSET(*bss); 6351793Smarcel bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 6451793Smarcel bss->__bits[1] = lss->__bits[1]; 6551793Smarcel for (l = 1; l <= LINUX_SIGTBLSZ; l++) { 6651793Smarcel if (LINUX_SIGISMEMBER(*lss, l)) { 6751793Smarcel b = linux_to_bsd_signal[_SIG_IDX(l)]; 6851793Smarcel if (b) 6951793Smarcel SIGADDSET(*bss, b); 7051793Smarcel } 7114331Speter } 729313Ssos} 739313Ssos 7467234Sgallatinvoid 7583221Smarcelbsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 7651793Smarcel{ 7751793Smarcel int b, l; 789313Ssos 7951793Smarcel LINUX_SIGEMPTYSET(*lss); 8051793Smarcel lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 8151793Smarcel lss->__bits[1] = bss->__bits[1]; 8251793Smarcel for (b = 1; b <= LINUX_SIGTBLSZ; b++) { 8351793Smarcel if (SIGISMEMBER(*bss, b)) { 8451793Smarcel l = bsd_to_linux_signal[_SIG_IDX(b)]; 8551793Smarcel if (l) 8651793Smarcel LINUX_SIGADDSET(*lss, l); 8751793Smarcel } 8814331Speter } 899313Ssos} 909313Ssos 9114342Speterstatic void 9283221Smarcellinux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 9314331Speter{ 9451793Smarcel 9551793Smarcel linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 96133816Stjr bsa->sa_handler = PTRIN(lsa->lsa_handler); 9751793Smarcel bsa->sa_flags = 0; 9851793Smarcel if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 9951793Smarcel bsa->sa_flags |= SA_NOCLDSTOP; 10051793Smarcel if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 10151793Smarcel bsa->sa_flags |= SA_NOCLDWAIT; 10251793Smarcel if (lsa->lsa_flags & LINUX_SA_SIGINFO) 10351793Smarcel bsa->sa_flags |= SA_SIGINFO; 10451793Smarcel if (lsa->lsa_flags & LINUX_SA_ONSTACK) 10551793Smarcel bsa->sa_flags |= SA_ONSTACK; 10651793Smarcel if (lsa->lsa_flags & LINUX_SA_RESTART) 10751793Smarcel bsa->sa_flags |= SA_RESTART; 10851793Smarcel if (lsa->lsa_flags & LINUX_SA_ONESHOT) 10951793Smarcel bsa->sa_flags |= SA_RESETHAND; 11051793Smarcel if (lsa->lsa_flags & LINUX_SA_NOMASK) 11151793Smarcel bsa->sa_flags |= SA_NODEFER; 11214331Speter} 1139313Ssos 11414342Speterstatic void 11583221Smarcelbsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 11614331Speter{ 11751793Smarcel 11851793Smarcel bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 119140214Sobrien#ifdef COMPAT_LINUX32 120133816Stjr lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 121133816Stjr#else 12251793Smarcel lsa->lsa_handler = bsa->sa_handler; 123133816Stjr#endif 124133816Stjr lsa->lsa_restorer = 0; /* unsupported */ 12551793Smarcel lsa->lsa_flags = 0; 12651793Smarcel if (bsa->sa_flags & SA_NOCLDSTOP) 12751793Smarcel lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 12851793Smarcel if (bsa->sa_flags & SA_NOCLDWAIT) 12951793Smarcel lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 13051793Smarcel if (bsa->sa_flags & SA_SIGINFO) 13151793Smarcel lsa->lsa_flags |= LINUX_SA_SIGINFO; 13251793Smarcel if (bsa->sa_flags & SA_ONSTACK) 13351793Smarcel lsa->lsa_flags |= LINUX_SA_ONSTACK; 13451793Smarcel if (bsa->sa_flags & SA_RESTART) 13551793Smarcel lsa->lsa_flags |= LINUX_SA_RESTART; 13651793Smarcel if (bsa->sa_flags & SA_RESETHAND) 13751793Smarcel lsa->lsa_flags |= LINUX_SA_ONESHOT; 13851793Smarcel if (bsa->sa_flags & SA_NODEFER) 13951793Smarcel lsa->lsa_flags |= LINUX_SA_NOMASK; 14014331Speter} 14114331Speter 14264911Smarcelint 14383366Sjulianlinux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 14483221Smarcel l_sigaction_t *linux_osa) 14549786Smarcel{ 146102814Siedowse struct sigaction act, oact, *nsa, *osa; 147102814Siedowse int error, sig; 14849786Smarcel 149163369Snetchild if (!LINUX_SIG_VALID(linux_sig)) 15051793Smarcel return (EINVAL); 15149786Smarcel 152102814Siedowse osa = (linux_osa != NULL) ? &oact : NULL; 15351793Smarcel if (linux_nsa != NULL) { 154102814Siedowse nsa = &act; 15553954Smarcel linux_to_bsd_sigaction(linux_nsa, nsa); 156102814Siedowse } else 15751793Smarcel nsa = NULL; 15849786Smarcel 15951793Smarcel if (linux_sig <= LINUX_SIGTBLSZ) 160102814Siedowse sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; 16151793Smarcel else 162102814Siedowse sig = linux_sig; 16349786Smarcel 164102814Siedowse error = kern_sigaction(td, sig, nsa, osa, 0); 16549786Smarcel if (error) 16651793Smarcel return (error); 16749786Smarcel 16853954Smarcel if (linux_osa != NULL) 16953954Smarcel bsd_to_linux_sigaction(osa, linux_osa); 17051793Smarcel 17151793Smarcel return (0); 17249786Smarcel} 17349786Smarcel 17468201Sobrien 1759313Ssosint 17683366Sjulianlinux_signal(struct thread *td, struct linux_signal_args *args) 17714331Speter{ 17883221Smarcel l_sigaction_t nsa, osa; 17951793Smarcel int error; 1809313Ssos 18114331Speter#ifdef DEBUG 18272543Sjlemon if (ldebug(signal)) 18372543Sjlemon printf(ARGS(signal, "%d, %p"), 184133850Sobrien args->sig, (void *)(uintptr_t)args->handler); 18514331Speter#endif 18649786Smarcel 18751793Smarcel nsa.lsa_handler = args->handler; 18851793Smarcel nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 18951793Smarcel LINUX_SIGEMPTYSET(nsa.lsa_mask); 19049786Smarcel 19183366Sjulian error = linux_do_sigaction(td, args->sig, &nsa, &osa); 192133816Stjr td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 19349786Smarcel 19451793Smarcel return (error); 19549786Smarcel} 19649786Smarcel 19749786Smarcelint 19883366Sjulianlinux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 19949786Smarcel{ 20083221Smarcel l_sigaction_t nsa, osa; 20151793Smarcel int error; 20249786Smarcel 20349786Smarcel#ifdef DEBUG 20472543Sjlemon if (ldebug(rt_sigaction)) 20572543Sjlemon printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 20672543Sjlemon (long)args->sig, (void *)args->act, 20772543Sjlemon (void *)args->oact, (long)args->sigsetsize); 20849786Smarcel#endif 20949786Smarcel 21083221Smarcel if (args->sigsetsize != sizeof(l_sigset_t)) 21151793Smarcel return (EINVAL); 21214331Speter 21351793Smarcel if (args->act != NULL) { 21483221Smarcel error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 21551793Smarcel if (error) 21651793Smarcel return (error); 21751793Smarcel } 21814331Speter 21983366Sjulian error = linux_do_sigaction(td, args->sig, 22051793Smarcel args->act ? &nsa : NULL, 22151793Smarcel args->oact ? &osa : NULL); 22214331Speter 22351793Smarcel if (args->oact != NULL && !error) { 22483221Smarcel error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 22551793Smarcel } 22649786Smarcel 22751793Smarcel return (error); 22814331Speter} 22914331Speter 23049786Smarcelstatic int 23183366Sjulianlinux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 23283221Smarcel l_sigset_t *old) 23349786Smarcel{ 234113859Sjhb sigset_t omask, nmask; 235113859Sjhb sigset_t *nmaskp; 23670061Sjhb int error; 23714331Speter 23883366Sjulian td->td_retval[0] = 0; 23949786Smarcel 240114023Sjhb switch (how) { 241114023Sjhb case LINUX_SIG_BLOCK: 242114023Sjhb how = SIG_BLOCK; 243114023Sjhb break; 244114023Sjhb case LINUX_SIG_UNBLOCK: 245114023Sjhb how = SIG_UNBLOCK; 246114023Sjhb break; 247114023Sjhb case LINUX_SIG_SETMASK: 248114023Sjhb how = SIG_SETMASK; 249114023Sjhb break; 250114023Sjhb default: 251114023Sjhb return (EINVAL); 252114023Sjhb } 25351793Smarcel if (new != NULL) { 254113859Sjhb linux_to_bsd_sigset(new, &nmask); 255113859Sjhb nmaskp = &nmask; 256113859Sjhb } else 257113859Sjhb nmaskp = NULL; 258114023Sjhb error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 259114174Sjhb if (error == 0 && old != NULL) 260113859Sjhb bsd_to_linux_sigset(&omask, old); 26149786Smarcel 26251793Smarcel return (error); 26349786Smarcel} 26449786Smarcel 2659313Ssosint 26683366Sjulianlinux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 2679313Ssos{ 26883221Smarcel l_osigset_t mask; 26983221Smarcel l_sigset_t set, oset; 27051793Smarcel int error; 2719313Ssos 2729313Ssos#ifdef DEBUG 27372543Sjlemon if (ldebug(sigprocmask)) 27472543Sjlemon printf(ARGS(sigprocmask, "%d, *, *"), args->how); 2759313Ssos#endif 27614331Speter 27751793Smarcel if (args->mask != NULL) { 27883221Smarcel error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 27951793Smarcel if (error) 28051793Smarcel return (error); 28151793Smarcel LINUX_SIGEMPTYSET(set); 28251793Smarcel set.__bits[0] = mask; 28351793Smarcel } 28414331Speter 28583366Sjulian error = linux_do_sigprocmask(td, args->how, 28651793Smarcel args->mask ? &set : NULL, 28751793Smarcel args->omask ? &oset : NULL); 28849786Smarcel 28951793Smarcel if (args->omask != NULL && !error) { 29051793Smarcel mask = oset.__bits[0]; 29183221Smarcel error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 29251793Smarcel } 29349786Smarcel 29451793Smarcel return (error); 29549786Smarcel} 29649786Smarcel 29749786Smarcelint 29883366Sjulianlinux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 29949786Smarcel{ 30083221Smarcel l_sigset_t set, oset; 30151793Smarcel int error; 30249786Smarcel 30349786Smarcel#ifdef DEBUG 30472543Sjlemon if (ldebug(rt_sigprocmask)) 30572543Sjlemon printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 30672543Sjlemon args->how, (void *)args->mask, 30772543Sjlemon (void *)args->omask, (long)args->sigsetsize); 30849786Smarcel#endif 30949786Smarcel 31083221Smarcel if (args->sigsetsize != sizeof(l_sigset_t)) 31151793Smarcel return EINVAL; 31249786Smarcel 31351793Smarcel if (args->mask != NULL) { 31483221Smarcel error = copyin(args->mask, &set, sizeof(l_sigset_t)); 31551793Smarcel if (error) 31651793Smarcel return (error); 31751793Smarcel } 31849786Smarcel 31983366Sjulian error = linux_do_sigprocmask(td, args->how, 32051793Smarcel args->mask ? &set : NULL, 32151793Smarcel args->omask ? &oset : NULL); 3229313Ssos 32351793Smarcel if (args->omask != NULL && !error) { 32483221Smarcel error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 32551793Smarcel } 32649786Smarcel 32751793Smarcel return (error); 3289313Ssos} 3299313Ssos 3309313Ssosint 33183366Sjulianlinux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 3329313Ssos{ 33383366Sjulian struct proc *p = td->td_proc; 33483221Smarcel l_sigset_t mask; 33551793Smarcel 3369313Ssos#ifdef DEBUG 33783221Smarcel if (ldebug(sgetmask)) 33883221Smarcel printf(ARGS(sgetmask, "")); 3399313Ssos#endif 34051793Smarcel 34170061Sjhb PROC_LOCK(p); 342112888Sjeff bsd_to_linux_sigset(&td->td_sigmask, &mask); 34370061Sjhb PROC_UNLOCK(p); 34483366Sjulian td->td_retval[0] = mask.__bits[0]; 34551793Smarcel return (0); 3469313Ssos} 3479313Ssos 3489313Ssosint 34983366Sjulianlinux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 3509313Ssos{ 35183366Sjulian struct proc *p = td->td_proc; 35283221Smarcel l_sigset_t lset; 35351793Smarcel sigset_t bset; 3549313Ssos 3559313Ssos#ifdef DEBUG 35683221Smarcel if (ldebug(ssetmask)) 35783221Smarcel printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 3589313Ssos#endif 35914331Speter 36070061Sjhb PROC_LOCK(p); 361112888Sjeff bsd_to_linux_sigset(&td->td_sigmask, &lset); 36283366Sjulian td->td_retval[0] = lset.__bits[0]; 36351793Smarcel LINUX_SIGEMPTYSET(lset); 36451793Smarcel lset.__bits[0] = args->mask; 36551793Smarcel linux_to_bsd_sigset(&lset, &bset); 366112888Sjeff td->td_sigmask = bset; 367112888Sjeff SIG_CANTMASK(td->td_sigmask); 368112888Sjeff signotify(td); 36970061Sjhb PROC_UNLOCK(p); 37051793Smarcel return (0); 3719313Ssos} 3729313Ssos 373110980Stjr/* 374110980Stjr * MPSAFE 375110980Stjr */ 3769313Ssosint 37783366Sjulianlinux_sigpending(struct thread *td, struct linux_sigpending_args *args) 3789313Ssos{ 37983366Sjulian struct proc *p = td->td_proc; 38051793Smarcel sigset_t bset; 38183221Smarcel l_sigset_t lset; 38283221Smarcel l_osigset_t mask; 3839313Ssos 3849313Ssos#ifdef DEBUG 38572543Sjlemon if (ldebug(sigpending)) 38672543Sjlemon printf(ARGS(sigpending, "*")); 3879313Ssos#endif 38851793Smarcel 38970061Sjhb PROC_LOCK(p); 390104306Sjmallett bset = p->p_siglist; 391112888Sjeff SIGSETOR(bset, td->td_siglist); 392112888Sjeff SIGSETAND(bset, td->td_sigmask); 393113615Sjhb PROC_UNLOCK(p); 39451793Smarcel bsd_to_linux_sigset(&bset, &lset); 39551793Smarcel mask = lset.__bits[0]; 39651793Smarcel return (copyout(&mask, args->mask, sizeof(mask))); 3979313Ssos} 398158406Snetchild 399158406Snetchild/* 400158406Snetchild * MPSAFE 401158406Snetchild */ 402158406Snetchildint 403158406Snetchildlinux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 404158406Snetchild{ 405158406Snetchild struct proc *p = td->td_proc; 406158406Snetchild sigset_t bset; 407158406Snetchild l_sigset_t lset; 408158406Snetchild 409158406Snetchild if (args->sigsetsize > sizeof(lset)) 410158406Snetchild return EINVAL; 411158406Snetchild /* NOT REACHED */ 412158406Snetchild 413158406Snetchild#ifdef DEBUG 414158406Snetchild if (ldebug(rt_sigpending)) 415158406Snetchild printf(ARGS(rt_sigpending, "*")); 416158406Snetchild#endif 417158406Snetchild 418158406Snetchild PROC_LOCK(p); 419158406Snetchild bset = p->p_siglist; 420158406Snetchild SIGSETOR(bset, td->td_siglist); 421158406Snetchild SIGSETAND(bset, td->td_sigmask); 422158406Snetchild PROC_UNLOCK(p); 423158406Snetchild bsd_to_linux_sigset(&bset, &lset); 424158406Snetchild return (copyout(&lset, args->set, args->sigsetsize)); 425158406Snetchild} 4269313Ssos 427165689Snetchild/* 428165689Snetchild * MPSAFE 429165689Snetchild */ 4309313Ssosint 431165689Snetchildlinux_rt_sigtimedwait(struct thread *td, 432165689Snetchild struct linux_rt_sigtimedwait_args *args) 433165689Snetchild{ 434218719Sdchagin int error, sig; 435165689Snetchild l_timeval ltv; 436165689Snetchild struct timeval tv; 437165689Snetchild struct timespec ts, *tsa; 438165689Snetchild l_sigset_t lset; 439165689Snetchild sigset_t bset; 440165689Snetchild l_siginfo_t linfo; 441165689Snetchild ksiginfo_t info; 442165689Snetchild 443165689Snetchild#ifdef DEBUG 444165689Snetchild if (ldebug(rt_sigtimedwait)) 445165689Snetchild printf(ARGS(rt_sigtimedwait, "*")); 446165689Snetchild#endif 447165689Snetchild if (args->sigsetsize != sizeof(l_sigset_t)) 448165689Snetchild return (EINVAL); 449165689Snetchild 450165689Snetchild if ((error = copyin(args->mask, &lset, sizeof(lset)))) 451165689Snetchild return (error); 452165689Snetchild linux_to_bsd_sigset(&lset, &bset); 453165689Snetchild 454165689Snetchild tsa = NULL; 455165689Snetchild if (args->timeout) { 456165689Snetchild if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 457165689Snetchild return (error); 458165689Snetchild#ifdef DEBUG 459165689Snetchild if (ldebug(rt_sigtimedwait)) 460218718Sdchagin printf(LMSG("linux_rt_sigtimedwait: " 461218718Sdchagin "incoming timeout (%d/%d)\n"), 462218718Sdchagin ltv.tv_sec, ltv.tv_usec); 463165689Snetchild#endif 464165689Snetchild tv.tv_sec = (long)ltv.tv_sec; 465165689Snetchild tv.tv_usec = (suseconds_t)ltv.tv_usec; 466165689Snetchild if (itimerfix(&tv)) { 467165689Snetchild /* 468165689Snetchild * The timeout was invalid. Convert it to something 469165689Snetchild * valid that will act as it does under Linux. 470165689Snetchild */ 471165689Snetchild tv.tv_sec += tv.tv_usec / 1000000; 472165689Snetchild tv.tv_usec %= 1000000; 473165689Snetchild if (tv.tv_usec < 0) { 474165689Snetchild tv.tv_sec -= 1; 475165689Snetchild tv.tv_usec += 1000000; 476165689Snetchild } 477165689Snetchild if (tv.tv_sec < 0) 478165689Snetchild timevalclear(&tv); 479165689Snetchild#ifdef DEBUG 480165689Snetchild if (ldebug(rt_sigtimedwait)) 481218718Sdchagin printf(LMSG("linux_rt_sigtimedwait: " 482218718Sdchagin "converted timeout (%jd/%ld)\n"), 483218718Sdchagin (intmax_t)tv.tv_sec, tv.tv_usec); 484165689Snetchild#endif 485165689Snetchild } 486165689Snetchild TIMEVAL_TO_TIMESPEC(&tv, &ts); 487165689Snetchild tsa = &ts; 488165689Snetchild } 489165689Snetchild error = kern_sigtimedwait(td, bset, &info, tsa); 490165689Snetchild#ifdef DEBUG 491165689Snetchild if (ldebug(rt_sigtimedwait)) 492218718Sdchagin printf(LMSG("linux_rt_sigtimedwait: " 493218718Sdchagin "sigtimedwait returning (%d)\n"), error); 494165689Snetchild#endif 495165689Snetchild if (error) 496165689Snetchild return (error); 497165689Snetchild 498218719Sdchagin sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo); 499218719Sdchagin 500165689Snetchild if (args->ptr) { 501165689Snetchild memset(&linfo, 0, sizeof(linfo)); 502218719Sdchagin ksiginfo_to_lsiginfo(&info, &linfo, sig); 503165689Snetchild error = copyout(&linfo, args->ptr, sizeof(linfo)); 504165689Snetchild } 505218719Sdchagin if (error == 0) 506218719Sdchagin td->td_retval[0] = sig; 507165689Snetchild 508165689Snetchild return (error); 509165689Snetchild} 510165689Snetchild 511165689Snetchildint 51283366Sjulianlinux_kill(struct thread *td, struct linux_kill_args *args) 5139313Ssos{ 51451793Smarcel struct kill_args /* { 51551793Smarcel int pid; 51651793Smarcel int signum; 51751793Smarcel } */ tmp; 5189313Ssos 5199313Ssos#ifdef DEBUG 52072543Sjlemon if (ldebug(kill)) 52172543Sjlemon printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 5229313Ssos#endif 52351793Smarcel 52451793Smarcel /* 52551793Smarcel * Allow signal 0 as a means to check for privileges 52651793Smarcel */ 527163381Snetchild if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 528217743Sdchagin return (EINVAL); 52951793Smarcel 53051793Smarcel if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) 53151793Smarcel tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; 53251793Smarcel else 53351793Smarcel tmp.signum = args->signum; 53451793Smarcel 53551793Smarcel tmp.pid = args->pid; 536225617Skmacy return (sys_kill(td, &tmp)); 5379313Ssos} 538161310Snetchild 539184058Skibstatic int 540184058Skiblinux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum) 541161310Snetchild{ 542184058Skib struct proc *proc = td->td_proc; 543184058Skib struct linux_emuldata *em; 544161310Snetchild struct proc *p; 545184058Skib ksiginfo_t ksi; 546184058Skib int error; 547161310Snetchild 548195104Srwatson AUDIT_ARG_SIGNUM(signum); 549195104Srwatson AUDIT_ARG_PID(pid); 550161310Snetchild 551184058Skib /* 552184058Skib * Allow signal 0 as a means to check for privileges 553184058Skib */ 554184058Skib if (!LINUX_SIG_VALID(signum) && signum != 0) 555184058Skib return (EINVAL); 556161310Snetchild 557184058Skib if (signum > 0 && signum <= LINUX_SIGTBLSZ) 558184058Skib signum = linux_to_bsd_signal[_SIG_IDX(signum)]; 559161310Snetchild 560184058Skib if ((p = pfind(pid)) == NULL) { 561184058Skib if ((p = zpfind(pid)) == NULL) 562184058Skib return (ESRCH); 563184058Skib } 564161310Snetchild 565195104Srwatson AUDIT_ARG_PROCESS(p); 566184058Skib error = p_cansignal(td, p, signum); 567200667Skib if (error != 0 || signum == 0) 568184058Skib goto out; 569161310Snetchild 570184058Skib error = ESRCH; 571165869Snetchild em = em_find(p, EMUL_DONTLOCK); 572161310Snetchild 573161310Snetchild if (em == NULL) { 574161310Snetchild#ifdef DEBUG 575184058Skib printf("emuldata not found in do_tkill.\n"); 576161310Snetchild#endif 577184058Skib goto out; 578161310Snetchild } 579184058Skib if (tgid > 0 && em->shared->group_pid != tgid) 580184058Skib goto out; 581161310Snetchild 582184058Skib ksiginfo_init(&ksi); 583184058Skib ksi.ksi_signo = signum; 584184058Skib ksi.ksi_code = LINUX_SI_TKILL; 585184058Skib ksi.ksi_errno = 0; 586184058Skib ksi.ksi_pid = proc->p_pid; 587184058Skib ksi.ksi_uid = proc->p_ucred->cr_ruid; 588161310Snetchild 589209592Sjhb error = pksignal(p, ksi.ksi_signo, &ksi); 590184058Skib 591184058Skibout: 592184058Skib PROC_UNLOCK(p); 593184058Skib return (error); 594161310Snetchild} 595161310Snetchild 596161310Snetchildint 597184058Skiblinux_tgkill(struct thread *td, struct linux_tgkill_args *args) 598184058Skib{ 599184058Skib 600184058Skib#ifdef DEBUG 601184058Skib if (ldebug(tgkill)) 602184058Skib printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig); 603184058Skib#endif 604184058Skib if (args->pid <= 0 || args->tgid <=0) 605184058Skib return (EINVAL); 606184058Skib 607184058Skib return (linux_do_tkill(td, args->tgid, args->pid, args->sig)); 608184058Skib} 609184058Skib 610184058Skibint 611161310Snetchildlinux_tkill(struct thread *td, struct linux_tkill_args *args) 612161310Snetchild{ 613161310Snetchild#ifdef DEBUG 614161310Snetchild if (ldebug(tkill)) 615161310Snetchild printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 616161310Snetchild#endif 617184058Skib if (args->tid <= 0) 618184058Skib return (EINVAL); 619161310Snetchild 620184058Skib return (linux_do_tkill(td, 0, args->tid, args->sig)); 621161310Snetchild} 622184058Skib 623184058Skibvoid 624184058Skibksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 625184058Skib{ 626184058Skib 627184058Skib lsi->lsi_signo = sig; 628184058Skib lsi->lsi_code = ksi->ksi_code; 629184058Skib 630184058Skib switch (sig) { 631184058Skib case LINUX_SIGPOLL: 632184058Skib /* XXX si_fd? */ 633184058Skib lsi->lsi_band = ksi->ksi_band; 634184058Skib break; 635184058Skib case LINUX_SIGCHLD: 636184058Skib lsi->lsi_pid = ksi->ksi_pid; 637184058Skib lsi->lsi_uid = ksi->ksi_uid; 638184058Skib lsi->lsi_status = ksi->ksi_status; 639184058Skib break; 640184058Skib case LINUX_SIGBUS: 641184058Skib case LINUX_SIGILL: 642184058Skib case LINUX_SIGFPE: 643184058Skib case LINUX_SIGSEGV: 644184058Skib lsi->lsi_addr = PTROUT(ksi->ksi_addr); 645184058Skib break; 646184058Skib default: 647184058Skib /* XXX SI_TIMER etc... */ 648184058Skib lsi->lsi_pid = ksi->ksi_pid; 649184058Skib lsi->lsi_uid = ksi->ksi_uid; 650184058Skib break; 651184058Skib } 652218720Sdchagin if (sig >= LINUX_SIGRTMIN) { 653218720Sdchagin lsi->lsi_int = ksi->ksi_info.si_value.sival_int; 654218720Sdchagin lsi->lsi_ptr = PTROUT(ksi->ksi_info.si_value.sival_ptr); 655218720Sdchagin } 656184058Skib} 657