The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/linux/linux_signal.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1994-1995 Søren Schmidt
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer 
   10  *    in this position and unchanged.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD: releng/10.2/sys/compat/linux/linux_signal.c 230132 2012-01-15 13:23:18Z uqs $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/lock.h>
   35 #include <sys/mutex.h>
   36 #include <sys/sx.h>
   37 #include <sys/proc.h>
   38 #include <sys/signalvar.h>
   39 #include <sys/syscallsubr.h>
   40 #include <sys/sysproto.h>
   41 
   42 #include <security/audit/audit.h>
   43 
   44 #include "opt_compat.h"
   45 
   46 #ifdef COMPAT_LINUX32
   47 #include <machine/../linux32/linux.h>
   48 #include <machine/../linux32/linux32_proto.h>
   49 #else
   50 #include <machine/../linux/linux.h>
   51 #include <machine/../linux/linux_proto.h>
   52 #endif
   53 #include <compat/linux/linux_signal.h>
   54 #include <compat/linux/linux_util.h>
   55 #include <compat/linux/linux_emul.h>
   56 
   57 void
   58 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
   59 {
   60         int b, l;
   61 
   62         SIGEMPTYSET(*bss);
   63         bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
   64         bss->__bits[1] = lss->__bits[1];
   65         for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
   66                 if (LINUX_SIGISMEMBER(*lss, l)) {
   67                         b = linux_to_bsd_signal[_SIG_IDX(l)];
   68                         if (b)
   69                                 SIGADDSET(*bss, b);
   70                 }
   71         }
   72 }
   73 
   74 void
   75 bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
   76 {
   77         int b, l;
   78 
   79         LINUX_SIGEMPTYSET(*lss);
   80         lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
   81         lss->__bits[1] = bss->__bits[1];
   82         for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
   83                 if (SIGISMEMBER(*bss, b)) {
   84                         l = bsd_to_linux_signal[_SIG_IDX(b)];
   85                         if (l)
   86                                 LINUX_SIGADDSET(*lss, l);
   87                 }
   88         }
   89 }
   90 
   91 static void
   92 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
   93 {
   94 
   95         linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
   96         bsa->sa_handler = PTRIN(lsa->lsa_handler);
   97         bsa->sa_flags = 0;
   98         if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
   99                 bsa->sa_flags |= SA_NOCLDSTOP;
  100         if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
  101                 bsa->sa_flags |= SA_NOCLDWAIT;
  102         if (lsa->lsa_flags & LINUX_SA_SIGINFO)
  103                 bsa->sa_flags |= SA_SIGINFO;
  104         if (lsa->lsa_flags & LINUX_SA_ONSTACK)
  105                 bsa->sa_flags |= SA_ONSTACK;
  106         if (lsa->lsa_flags & LINUX_SA_RESTART)
  107                 bsa->sa_flags |= SA_RESTART;
  108         if (lsa->lsa_flags & LINUX_SA_ONESHOT)
  109                 bsa->sa_flags |= SA_RESETHAND;
  110         if (lsa->lsa_flags & LINUX_SA_NOMASK)
  111                 bsa->sa_flags |= SA_NODEFER;
  112 }
  113 
  114 static void
  115 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
  116 {
  117 
  118         bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
  119 #ifdef COMPAT_LINUX32
  120         lsa->lsa_handler = (uintptr_t)bsa->sa_handler;
  121 #else
  122         lsa->lsa_handler = bsa->sa_handler;
  123 #endif
  124         lsa->lsa_restorer = 0;          /* unsupported */
  125         lsa->lsa_flags = 0;
  126         if (bsa->sa_flags & SA_NOCLDSTOP)
  127                 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
  128         if (bsa->sa_flags & SA_NOCLDWAIT)
  129                 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
  130         if (bsa->sa_flags & SA_SIGINFO)
  131                 lsa->lsa_flags |= LINUX_SA_SIGINFO;
  132         if (bsa->sa_flags & SA_ONSTACK)
  133                 lsa->lsa_flags |= LINUX_SA_ONSTACK;
  134         if (bsa->sa_flags & SA_RESTART)
  135                 lsa->lsa_flags |= LINUX_SA_RESTART;
  136         if (bsa->sa_flags & SA_RESETHAND)
  137                 lsa->lsa_flags |= LINUX_SA_ONESHOT;
  138         if (bsa->sa_flags & SA_NODEFER)
  139                 lsa->lsa_flags |= LINUX_SA_NOMASK;
  140 }
  141 
  142 int
  143 linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
  144                    l_sigaction_t *linux_osa)
  145 {
  146         struct sigaction act, oact, *nsa, *osa;
  147         int error, sig;
  148 
  149         if (!LINUX_SIG_VALID(linux_sig))
  150                 return (EINVAL);
  151 
  152         osa = (linux_osa != NULL) ? &oact : NULL;
  153         if (linux_nsa != NULL) {
  154                 nsa = &act;
  155                 linux_to_bsd_sigaction(linux_nsa, nsa);
  156         } else
  157                 nsa = NULL;
  158 
  159         if (linux_sig <= LINUX_SIGTBLSZ)
  160                 sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
  161         else
  162                 sig = linux_sig;
  163 
  164         error = kern_sigaction(td, sig, nsa, osa, 0);
  165         if (error)
  166                 return (error);
  167 
  168         if (linux_osa != NULL)
  169                 bsd_to_linux_sigaction(osa, linux_osa);
  170 
  171         return (0);
  172 }
  173 
  174 
  175 int
  176 linux_signal(struct thread *td, struct linux_signal_args *args)
  177 {
  178         l_sigaction_t nsa, osa;
  179         int error;
  180 
  181 #ifdef DEBUG
  182         if (ldebug(signal))
  183                 printf(ARGS(signal, "%d, %p"),
  184                     args->sig, (void *)(uintptr_t)args->handler);
  185 #endif
  186 
  187         nsa.lsa_handler = args->handler;
  188         nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
  189         LINUX_SIGEMPTYSET(nsa.lsa_mask);
  190 
  191         error = linux_do_sigaction(td, args->sig, &nsa, &osa);
  192         td->td_retval[0] = (int)(intptr_t)osa.lsa_handler;
  193 
  194         return (error);
  195 }
  196 
  197 int
  198 linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
  199 {
  200         l_sigaction_t nsa, osa;
  201         int error;
  202 
  203 #ifdef DEBUG
  204         if (ldebug(rt_sigaction))
  205                 printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
  206                     (long)args->sig, (void *)args->act,
  207                     (void *)args->oact, (long)args->sigsetsize);
  208 #endif
  209 
  210         if (args->sigsetsize != sizeof(l_sigset_t))
  211                 return (EINVAL);
  212 
  213         if (args->act != NULL) {
  214                 error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
  215                 if (error)
  216                         return (error);
  217         }
  218 
  219         error = linux_do_sigaction(td, args->sig,
  220                                    args->act ? &nsa : NULL,
  221                                    args->oact ? &osa : NULL);
  222 
  223         if (args->oact != NULL && !error) {
  224                 error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
  225         }
  226 
  227         return (error);
  228 }
  229 
  230 static int
  231 linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
  232                      l_sigset_t *old)
  233 {
  234         sigset_t omask, nmask;
  235         sigset_t *nmaskp;
  236         int error;
  237 
  238         td->td_retval[0] = 0;
  239 
  240         switch (how) {
  241         case LINUX_SIG_BLOCK:
  242                 how = SIG_BLOCK;
  243                 break;
  244         case LINUX_SIG_UNBLOCK:
  245                 how = SIG_UNBLOCK;
  246                 break;
  247         case LINUX_SIG_SETMASK:
  248                 how = SIG_SETMASK;
  249                 break;
  250         default:
  251                 return (EINVAL);
  252         }
  253         if (new != NULL) {
  254                 linux_to_bsd_sigset(new, &nmask);
  255                 nmaskp = &nmask;
  256         } else
  257                 nmaskp = NULL;
  258         error = kern_sigprocmask(td, how, nmaskp, &omask, 0);
  259         if (error == 0 && old != NULL)
  260                 bsd_to_linux_sigset(&omask, old);
  261 
  262         return (error);
  263 }
  264 
  265 int
  266 linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
  267 {
  268         l_osigset_t mask;
  269         l_sigset_t set, oset;
  270         int error;
  271 
  272 #ifdef DEBUG
  273         if (ldebug(sigprocmask))
  274                 printf(ARGS(sigprocmask, "%d, *, *"), args->how);
  275 #endif
  276 
  277         if (args->mask != NULL) {
  278                 error = copyin(args->mask, &mask, sizeof(l_osigset_t));
  279                 if (error)
  280                         return (error);
  281                 LINUX_SIGEMPTYSET(set);
  282                 set.__bits[0] = mask;
  283         }
  284 
  285         error = linux_do_sigprocmask(td, args->how,
  286                                      args->mask ? &set : NULL,
  287                                      args->omask ? &oset : NULL);
  288 
  289         if (args->omask != NULL && !error) {
  290                 mask = oset.__bits[0];
  291                 error = copyout(&mask, args->omask, sizeof(l_osigset_t));
  292         }
  293 
  294         return (error);
  295 }
  296 
  297 int
  298 linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
  299 {
  300         l_sigset_t set, oset;
  301         int error;
  302 
  303 #ifdef DEBUG
  304         if (ldebug(rt_sigprocmask))
  305                 printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
  306                     args->how, (void *)args->mask,
  307                     (void *)args->omask, (long)args->sigsetsize);
  308 #endif
  309 
  310         if (args->sigsetsize != sizeof(l_sigset_t))
  311                 return EINVAL;
  312 
  313         if (args->mask != NULL) {
  314                 error = copyin(args->mask, &set, sizeof(l_sigset_t));
  315                 if (error)
  316                         return (error);
  317         }
  318 
  319         error = linux_do_sigprocmask(td, args->how,
  320                                      args->mask ? &set : NULL,
  321                                      args->omask ? &oset : NULL);
  322 
  323         if (args->omask != NULL && !error) {
  324                 error = copyout(&oset, args->omask, sizeof(l_sigset_t));
  325         }
  326 
  327         return (error);
  328 }
  329 
  330 int
  331 linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
  332 {
  333         struct proc *p = td->td_proc;
  334         l_sigset_t mask;
  335 
  336 #ifdef DEBUG
  337         if (ldebug(sgetmask))
  338                 printf(ARGS(sgetmask, ""));
  339 #endif
  340 
  341         PROC_LOCK(p);
  342         bsd_to_linux_sigset(&td->td_sigmask, &mask);
  343         PROC_UNLOCK(p);
  344         td->td_retval[0] = mask.__bits[0];
  345         return (0);
  346 }
  347 
  348 int
  349 linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
  350 {
  351         struct proc *p = td->td_proc;
  352         l_sigset_t lset;
  353         sigset_t bset;
  354 
  355 #ifdef DEBUG
  356         if (ldebug(ssetmask))
  357                 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
  358 #endif
  359 
  360         PROC_LOCK(p);
  361         bsd_to_linux_sigset(&td->td_sigmask, &lset);
  362         td->td_retval[0] = lset.__bits[0];
  363         LINUX_SIGEMPTYSET(lset);
  364         lset.__bits[0] = args->mask;
  365         linux_to_bsd_sigset(&lset, &bset);
  366         td->td_sigmask = bset;
  367         SIG_CANTMASK(td->td_sigmask);
  368         signotify(td);
  369         PROC_UNLOCK(p);
  370         return (0);
  371 }
  372 
  373 /*
  374  * MPSAFE
  375  */
  376 int
  377 linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
  378 {
  379         struct proc *p = td->td_proc;
  380         sigset_t bset;
  381         l_sigset_t lset;
  382         l_osigset_t mask;
  383 
  384 #ifdef DEBUG
  385         if (ldebug(sigpending))
  386                 printf(ARGS(sigpending, "*"));
  387 #endif
  388 
  389         PROC_LOCK(p);
  390         bset = p->p_siglist;
  391         SIGSETOR(bset, td->td_siglist);
  392         SIGSETAND(bset, td->td_sigmask);
  393         PROC_UNLOCK(p);
  394         bsd_to_linux_sigset(&bset, &lset);
  395         mask = lset.__bits[0];
  396         return (copyout(&mask, args->mask, sizeof(mask)));
  397 }
  398 
  399 /*
  400  * MPSAFE
  401  */
  402 int
  403 linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
  404 {
  405         struct proc *p = td->td_proc;
  406         sigset_t bset;
  407         l_sigset_t lset;
  408 
  409         if (args->sigsetsize > sizeof(lset))
  410                 return EINVAL;
  411                 /* NOT REACHED */
  412 
  413 #ifdef DEBUG
  414         if (ldebug(rt_sigpending))
  415                 printf(ARGS(rt_sigpending, "*"));
  416 #endif
  417 
  418         PROC_LOCK(p);
  419         bset = p->p_siglist;
  420         SIGSETOR(bset, td->td_siglist);
  421         SIGSETAND(bset, td->td_sigmask);
  422         PROC_UNLOCK(p);
  423         bsd_to_linux_sigset(&bset, &lset);
  424         return (copyout(&lset, args->set, args->sigsetsize));
  425 }
  426 
  427 /*
  428  * MPSAFE
  429  */
  430 int
  431 linux_rt_sigtimedwait(struct thread *td,
  432         struct linux_rt_sigtimedwait_args *args)
  433 {
  434         int error, sig;
  435         l_timeval ltv;
  436         struct timeval tv;
  437         struct timespec ts, *tsa;
  438         l_sigset_t lset;
  439         sigset_t bset;
  440         l_siginfo_t linfo;
  441         ksiginfo_t info;
  442 
  443 #ifdef DEBUG
  444         if (ldebug(rt_sigtimedwait))
  445                 printf(ARGS(rt_sigtimedwait, "*"));
  446 #endif
  447         if (args->sigsetsize != sizeof(l_sigset_t))
  448                 return (EINVAL);
  449 
  450         if ((error = copyin(args->mask, &lset, sizeof(lset))))
  451                 return (error);
  452         linux_to_bsd_sigset(&lset, &bset);
  453 
  454         tsa = NULL;
  455         if (args->timeout) {
  456                 if ((error = copyin(args->timeout, &ltv, sizeof(ltv))))
  457                         return (error);
  458 #ifdef DEBUG
  459                 if (ldebug(rt_sigtimedwait))
  460                         printf(LMSG("linux_rt_sigtimedwait: "
  461                             "incoming timeout (%d/%d)\n"),
  462                             ltv.tv_sec, ltv.tv_usec);
  463 #endif
  464                 tv.tv_sec = (long)ltv.tv_sec;
  465                 tv.tv_usec = (suseconds_t)ltv.tv_usec;
  466                 if (itimerfix(&tv)) {
  467                         /* 
  468                          * The timeout was invalid. Convert it to something
  469                          * valid that will act as it does under Linux.
  470                          */
  471                         tv.tv_sec += tv.tv_usec / 1000000;
  472                         tv.tv_usec %= 1000000;
  473                         if (tv.tv_usec < 0) {
  474                                 tv.tv_sec -= 1;
  475                                 tv.tv_usec += 1000000;
  476                         }
  477                         if (tv.tv_sec < 0)
  478                                 timevalclear(&tv);
  479 #ifdef DEBUG
  480                         if (ldebug(rt_sigtimedwait))
  481                                 printf(LMSG("linux_rt_sigtimedwait: "
  482                                     "converted timeout (%jd/%ld)\n"),
  483                                     (intmax_t)tv.tv_sec, tv.tv_usec);
  484 #endif
  485                 }
  486                 TIMEVAL_TO_TIMESPEC(&tv, &ts);
  487                 tsa = &ts;
  488         }
  489         error = kern_sigtimedwait(td, bset, &info, tsa);
  490 #ifdef DEBUG
  491         if (ldebug(rt_sigtimedwait))
  492                 printf(LMSG("linux_rt_sigtimedwait: "
  493                     "sigtimedwait returning (%d)\n"), error);
  494 #endif
  495         if (error)
  496                 return (error);
  497 
  498         sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo);
  499 
  500         if (args->ptr) {
  501                 memset(&linfo, 0, sizeof(linfo));
  502                 ksiginfo_to_lsiginfo(&info, &linfo, sig);
  503                 error = copyout(&linfo, args->ptr, sizeof(linfo));
  504         }
  505         if (error == 0)
  506                 td->td_retval[0] = sig; 
  507 
  508         return (error);
  509 }
  510 
  511 int
  512 linux_kill(struct thread *td, struct linux_kill_args *args)
  513 {
  514         struct kill_args /* {
  515             int pid;
  516             int signum;
  517         } */ tmp;
  518 
  519 #ifdef DEBUG
  520         if (ldebug(kill))
  521                 printf(ARGS(kill, "%d, %d"), args->pid, args->signum);
  522 #endif
  523 
  524         /*
  525          * Allow signal 0 as a means to check for privileges
  526          */
  527         if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
  528                 return (EINVAL);
  529 
  530         if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
  531                 tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
  532         else
  533                 tmp.signum = args->signum;
  534 
  535         tmp.pid = args->pid;
  536         return (sys_kill(td, &tmp));
  537 }
  538 
  539 static int
  540 linux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum)
  541 {
  542         struct proc *proc = td->td_proc;
  543         struct linux_emuldata *em;
  544         struct proc *p;
  545         ksiginfo_t ksi;
  546         int error;
  547 
  548         AUDIT_ARG_SIGNUM(signum);
  549         AUDIT_ARG_PID(pid);
  550 
  551         /*
  552          * Allow signal 0 as a means to check for privileges
  553          */
  554         if (!LINUX_SIG_VALID(signum) && signum != 0)
  555                 return (EINVAL);
  556 
  557         if (signum > 0 && signum <= LINUX_SIGTBLSZ)
  558                 signum = linux_to_bsd_signal[_SIG_IDX(signum)];
  559 
  560         if ((p = pfind(pid)) == NULL) {
  561                 if ((p = zpfind(pid)) == NULL)
  562                         return (ESRCH);
  563         }
  564 
  565         AUDIT_ARG_PROCESS(p);
  566         error = p_cansignal(td, p, signum);
  567         if (error != 0 || signum == 0)
  568                 goto out;
  569 
  570         error = ESRCH;
  571         em = em_find(p, EMUL_DONTLOCK);
  572 
  573         if (em == NULL) {
  574 #ifdef DEBUG
  575                 printf("emuldata not found in do_tkill.\n");
  576 #endif
  577                 goto out;
  578         }
  579         if (tgid > 0 && em->shared->group_pid != tgid)
  580                 goto out;
  581 
  582         ksiginfo_init(&ksi);
  583         ksi.ksi_signo = signum;
  584         ksi.ksi_code = LINUX_SI_TKILL;
  585         ksi.ksi_errno = 0;
  586         ksi.ksi_pid = proc->p_pid;
  587         ksi.ksi_uid = proc->p_ucred->cr_ruid;
  588 
  589         error = pksignal(p, ksi.ksi_signo, &ksi);
  590 
  591 out:
  592         PROC_UNLOCK(p);
  593         return (error);
  594 }
  595 
  596 int
  597 linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
  598 {
  599 
  600 #ifdef DEBUG
  601         if (ldebug(tgkill))
  602                 printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig);
  603 #endif
  604         if (args->pid <= 0 || args->tgid <=0)
  605                 return (EINVAL);
  606 
  607         return (linux_do_tkill(td, args->tgid, args->pid, args->sig));
  608 }
  609 
  610 int
  611 linux_tkill(struct thread *td, struct linux_tkill_args *args)
  612 {
  613 #ifdef DEBUG
  614         if (ldebug(tkill))
  615                 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
  616 #endif
  617         if (args->tid <= 0)
  618                 return (EINVAL);
  619 
  620         return (linux_do_tkill(td, 0, args->tid, args->sig));
  621 }
  622 
  623 void
  624 ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig)
  625 {
  626 
  627         lsi->lsi_signo = sig;
  628         lsi->lsi_code = ksi->ksi_code;
  629 
  630         switch (sig) {
  631         case LINUX_SIGPOLL:
  632                 /* XXX si_fd? */
  633                 lsi->lsi_band = ksi->ksi_band;
  634                 break;
  635         case LINUX_SIGCHLD:
  636                 lsi->lsi_pid = ksi->ksi_pid;
  637                 lsi->lsi_uid = ksi->ksi_uid;
  638                 lsi->lsi_status = ksi->ksi_status;
  639                 break;
  640         case LINUX_SIGBUS:
  641         case LINUX_SIGILL:
  642         case LINUX_SIGFPE:
  643         case LINUX_SIGSEGV:
  644                 lsi->lsi_addr = PTROUT(ksi->ksi_addr);
  645                 break;
  646         default:
  647                 /* XXX SI_TIMER etc... */
  648                 lsi->lsi_pid = ksi->ksi_pid;
  649                 lsi->lsi_uid = ksi->ksi_uid;
  650                 break;
  651         }
  652         if (sig >= LINUX_SIGRTMIN) {
  653                 lsi->lsi_int = ksi->ksi_info.si_value.sival_int;
  654                 lsi->lsi_ptr = PTROUT(ksi->ksi_info.si_value.sival_ptr);
  655         }
  656 }

Cache object: 2472db89f6353b7ad028002c1873723a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.