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/emulation/linux/linux_signal.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
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  * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.23.2.3 2001/11/05 19:08:23 marcel Exp $
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/lock.h>
   34 #include <sys/proc.h>
   35 #include <sys/signalvar.h>
   36 #include <sys/sysproto.h>
   37 #include <sys/kern_syscall.h>
   38 #include <sys/thread.h>
   39 
   40 #include <sys/thread2.h>
   41 
   42 #include <arch_linux/linux.h>
   43 #include <arch_linux/linux_proto.h>
   44 #include "linux_emuldata.h"
   45 #include "linux_signal.h"
   46 #include "linux_util.h"
   47 
   48 void
   49 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
   50 {
   51         int b, l;
   52 
   53         SIGEMPTYSET(*bss);
   54         bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
   55         bss->__bits[1] = lss->__bits[1];
   56         for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
   57                 if (LINUX_SIGISMEMBER(*lss, l)) {
   58                         b = linux_to_bsd_signal[_SIG_IDX(l)];
   59                         if (b)
   60                                 SIGADDSET(*bss, b);
   61                 }
   62         }
   63 }
   64 
   65 void
   66 bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
   67 {
   68         int b, l;
   69 
   70         LINUX_SIGEMPTYSET(*lss);
   71         lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
   72         lss->__bits[1] = bss->__bits[1];
   73         for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
   74                 if (SIGISMEMBER(*bss, b)) {
   75                         l = bsd_to_linux_signal[_SIG_IDX(b)];
   76                         if (l)
   77                                 LINUX_SIGADDSET(*lss, l);
   78                 }
   79         }
   80 }
   81 
   82 void
   83 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
   84 {
   85 
   86         linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
   87         bsa->sa_handler = lsa->lsa_handler;
   88         bsa->sa_flags = 0;
   89         if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
   90                 bsa->sa_flags |= SA_NOCLDSTOP;
   91         if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
   92                 bsa->sa_flags |= SA_NOCLDWAIT;
   93         if (lsa->lsa_flags & LINUX_SA_SIGINFO)
   94                 bsa->sa_flags |= SA_SIGINFO;
   95         if (lsa->lsa_flags & LINUX_SA_ONSTACK)
   96                 bsa->sa_flags |= SA_ONSTACK;
   97         if (lsa->lsa_flags & LINUX_SA_RESTART)
   98                 bsa->sa_flags |= SA_RESTART;
   99         if (lsa->lsa_flags & LINUX_SA_ONESHOT)
  100                 bsa->sa_flags |= SA_RESETHAND;
  101         if (lsa->lsa_flags & LINUX_SA_NOMASK)
  102                 bsa->sa_flags |= SA_NODEFER;
  103 }
  104 
  105 void
  106 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
  107 {
  108 
  109         bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
  110         lsa->lsa_handler = bsa->sa_handler;
  111         lsa->lsa_restorer = NULL;       /* unsupported */
  112         lsa->lsa_flags = 0;
  113         if (bsa->sa_flags & SA_NOCLDSTOP)
  114                 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
  115         if (bsa->sa_flags & SA_NOCLDWAIT)
  116                 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
  117         if (bsa->sa_flags & SA_SIGINFO)
  118                 lsa->lsa_flags |= LINUX_SA_SIGINFO;
  119         if (bsa->sa_flags & SA_ONSTACK)
  120                 lsa->lsa_flags |= LINUX_SA_ONSTACK;
  121         if (bsa->sa_flags & SA_RESTART)
  122                 lsa->lsa_flags |= LINUX_SA_RESTART;
  123         if (bsa->sa_flags & SA_RESETHAND)
  124                 lsa->lsa_flags |= LINUX_SA_ONESHOT;
  125         if (bsa->sa_flags & SA_NODEFER)
  126                 lsa->lsa_flags |= LINUX_SA_NOMASK;
  127 }
  128 
  129 /*
  130  * MPALMOSTSAFE
  131  */
  132 int
  133 sys_linux_signal(struct linux_signal_args *args)
  134 {
  135         l_sigaction_t linux_nsa, linux_osa;
  136         struct sigaction nsa, osa;
  137         int error, sig;
  138 
  139 #ifdef DEBUG
  140         if (ldebug(signal))
  141                 kprintf(ARGS(signal, "%d, %p"),
  142                     args->sig, (void *)args->handler);
  143 #endif
  144         linux_nsa.lsa_handler = args->handler;
  145         linux_nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
  146         LINUX_SIGEMPTYSET(linux_nsa.lsa_mask);
  147         linux_to_bsd_sigaction(&linux_nsa, &nsa);
  148         if (args->sig <= LINUX_SIGTBLSZ) {
  149                 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)];
  150         } else {
  151                 sig = args->sig;
  152         }
  153 
  154         error = kern_sigaction(sig, &nsa, &osa);
  155 
  156         bsd_to_linux_sigaction(&osa, &linux_osa);
  157         args->sysmsg_result = (int) linux_osa.lsa_handler;
  158         return (error);
  159 }
  160 
  161 /*
  162  * MPALMOSTSAFE
  163  */
  164 int
  165 sys_linux_rt_sigaction(struct linux_rt_sigaction_args *args)
  166 {
  167         l_sigaction_t linux_nsa, linux_osa;
  168         struct sigaction nsa, osa;
  169         int error, sig;
  170 
  171 #ifdef DEBUG
  172         if (ldebug(rt_sigaction))
  173                 kprintf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
  174                     (long)args->sig, (void *)args->act,
  175                     (void *)args->oact, (long)args->sigsetsize);
  176 #endif
  177         if (args->sigsetsize != sizeof(l_sigset_t))
  178                 return (EINVAL);
  179 
  180         if (args->act) {
  181                 error = copyin(args->act, &linux_nsa, sizeof(linux_nsa));
  182                 if (error)
  183                         return (error);
  184                 linux_to_bsd_sigaction(&linux_nsa, &nsa);
  185         }
  186         if (args->sig <= LINUX_SIGTBLSZ) {
  187                 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)];
  188         } else {
  189                 sig = args->sig;
  190         }
  191 
  192         error = kern_sigaction(sig, args->act ? &nsa : NULL,
  193                                args->oact ? &osa : NULL);
  194 
  195         if (error == 0 && args->oact) {
  196                 bsd_to_linux_sigaction(&osa, &linux_osa);
  197                 error = copyout(&linux_osa, args->oact, sizeof(linux_osa));
  198         }
  199 
  200         return (error);
  201 }
  202 
  203 static int
  204 linux_to_bsd_sigprocmask(int how)
  205 {
  206         switch (how) {
  207         case LINUX_SIG_BLOCK:
  208                 return SIG_BLOCK;
  209         case LINUX_SIG_UNBLOCK:
  210                 return SIG_UNBLOCK;
  211         case LINUX_SIG_SETMASK:
  212                 return SIG_SETMASK;
  213         default:
  214                 return (-1);
  215         }
  216 }
  217 
  218 /*
  219  * MPALMOSTSAFE
  220  */
  221 int
  222 sys_linux_sigprocmask(struct linux_sigprocmask_args *args)
  223 {
  224         l_osigset_t mask;
  225         l_sigset_t linux_set, linux_oset;
  226         sigset_t set, oset;
  227         int error, how;
  228 
  229 #ifdef DEBUG
  230         if (ldebug(sigprocmask))
  231                 kprintf(ARGS(sigprocmask, "%d, *, *"), args->how);
  232 #endif
  233 
  234         if (args->mask) {
  235                 error = copyin(args->mask, &mask, sizeof(l_osigset_t));
  236                 if (error)
  237                         return (error);
  238                 LINUX_SIGEMPTYSET(linux_set);
  239                 linux_set.__bits[0] = mask;
  240                 linux_to_bsd_sigset(&linux_set, &set);
  241         }
  242         how = linux_to_bsd_sigprocmask(args->how);
  243 
  244         error = kern_sigprocmask(how, args->mask ? &set : NULL,
  245                                  args->omask ? &oset : NULL);
  246 
  247         if (error == 0 && args->omask) {
  248                 bsd_to_linux_sigset(&oset, &linux_oset);
  249                 mask = linux_oset.__bits[0];
  250                 error = copyout(&mask, args->omask, sizeof(l_osigset_t));
  251         }
  252         return (error);
  253 }
  254 
  255 /*
  256  * MPALMOSTSAFE
  257  */
  258 int
  259 sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args *args)
  260 {
  261         l_sigset_t linux_set, linux_oset;
  262         sigset_t set, oset;
  263         int error, how;
  264 
  265 #ifdef DEBUG
  266         if (ldebug(rt_sigprocmask))
  267                 kprintf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
  268                     args->how, (void *)args->mask,
  269                     (void *)args->omask, (long)args->sigsetsize);
  270 #endif
  271 
  272         if (args->sigsetsize != sizeof(l_sigset_t))
  273                 return EINVAL;
  274 
  275         if (args->mask) {
  276                 error = copyin(args->mask, &linux_set, sizeof(l_sigset_t));
  277                 if (error)
  278                         return (error);
  279                 linux_to_bsd_sigset(&linux_set, &set);
  280         }
  281         how = linux_to_bsd_sigprocmask(args->how);
  282 
  283         error = kern_sigprocmask(how, args->mask ? &set : NULL,
  284                                  args->omask ? &oset : NULL);
  285 
  286         if (error == 0 && args->omask) {
  287                 bsd_to_linux_sigset(&oset, &linux_oset);
  288                 error = copyout(&linux_oset, args->omask, sizeof(l_sigset_t));
  289         }
  290 
  291         return (error);
  292 }
  293 
  294 /*
  295  * MPSAFE
  296  */
  297 int
  298 sys_linux_sgetmask(struct linux_sgetmask_args *args)
  299 {
  300         struct lwp *lp = curthread->td_lwp;
  301         l_sigset_t mask;
  302 
  303 #ifdef DEBUG
  304         if (ldebug(sgetmask))
  305                 kprintf(ARGS(sgetmask, ""));
  306 #endif
  307 
  308         bsd_to_linux_sigset(&lp->lwp_sigmask, &mask);
  309         args->sysmsg_result = mask.__bits[0];
  310         return (0);
  311 }
  312 
  313 /*
  314  * MPSAFE
  315  */
  316 int
  317 sys_linux_ssetmask(struct linux_ssetmask_args *args)
  318 {
  319         struct lwp *lp = curthread->td_lwp;
  320         l_sigset_t lset;
  321         sigset_t bset;
  322 
  323 #ifdef DEBUG
  324         if (ldebug(ssetmask))
  325                 kprintf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
  326 #endif
  327 
  328         bsd_to_linux_sigset(&lp->lwp_sigmask, &lset);
  329         args->sysmsg_result = lset.__bits[0];
  330         LINUX_SIGEMPTYSET(lset);
  331         lset.__bits[0] = args->mask;
  332         linux_to_bsd_sigset(&lset, &bset);
  333         crit_enter();
  334         lp->lwp_sigmask = bset;
  335         SIG_CANTMASK(lp->lwp_sigmask);
  336         crit_exit();
  337         return (0);
  338 }
  339 
  340 /*
  341  * MPSAFE
  342  */
  343 int
  344 sys_linux_sigpending(struct linux_sigpending_args *args)
  345 {
  346         struct thread *td = curthread;
  347         struct lwp *lp = td->td_lwp;
  348         sigset_t set;
  349         l_sigset_t linux_set;
  350         l_osigset_t mask;
  351         int error;
  352 
  353 #ifdef DEBUG
  354         if (ldebug(sigpending))
  355                 kprintf(ARGS(sigpending, "*"));
  356 #endif
  357 
  358         error = kern_sigpending(&set);
  359 
  360         if (error == 0) {
  361                 SIGSETAND(set, lp->lwp_sigmask);
  362                 bsd_to_linux_sigset(&set, &linux_set);
  363                 mask = linux_set.__bits[0];
  364                 error = copyout(&mask, args->mask, sizeof(mask));
  365         }
  366         return (error);
  367 }
  368 
  369 int
  370 sys_linux_kill(struct linux_kill_args *args)
  371 {
  372         int error, sig;
  373 
  374 #ifdef DEBUG
  375         if (ldebug(kill))
  376                 kprintf(ARGS(kill, "%d, %d"), args->pid, args->signum);
  377 #endif
  378         /*
  379          * Allow signal 0 as a means to check for privileges
  380          */
  381         if (args->signum < 0 || args->signum > LINUX_NSIG)
  382                 return EINVAL;
  383 
  384         if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
  385                 sig = linux_to_bsd_signal[_SIG_IDX(args->signum)];
  386         else
  387                 sig = args->signum;
  388 
  389         error = kern_kill(sig, args->pid, -1);
  390 
  391         return(error);
  392 }
  393 
  394 
  395 static int
  396 linux_do_tkill(l_int tgid, l_int pid, l_int sig)
  397 {
  398         struct linux_emuldata *em;
  399         struct proc *p;
  400         int error = 0;
  401 
  402         /*
  403          * Allow signal 0 as a means to check for privileges
  404          */
  405         if (sig < 0 || sig > LINUX_NSIG)
  406                 return (EINVAL);
  407 
  408         if (sig > 0 && sig <= LINUX_SIGTBLSZ)
  409                 sig = linux_to_bsd_signal[_SIG_IDX(sig)];
  410 
  411         if ((p = pfind(pid)) == NULL) {
  412                 if ((p = zpfind(pid)) == NULL) {
  413                         error = ESRCH;
  414                         goto done2;
  415                 }
  416         }
  417 
  418         EMUL_LOCK();
  419         em = emuldata_get(p);
  420 
  421         if (em == NULL) {
  422                 EMUL_UNLOCK();
  423                 error = ESRCH;
  424                 goto done1;
  425         }
  426 
  427         if (tgid > 0 && em->s->group_pid != tgid) {
  428                 EMUL_UNLOCK();
  429                 error = ESRCH;
  430                 goto done1;
  431         }
  432         EMUL_UNLOCK();
  433 
  434         error = kern_kill(sig, pid, -1);
  435 
  436 done1:
  437         PRELE(p);
  438 done2:
  439         return (error);
  440 }
  441 
  442 int
  443 sys_linux_tgkill(struct linux_tgkill_args *args)
  444 {
  445 
  446 #ifdef DEBUG
  447         if (ldebug(tgkill))
  448                 kprintf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig);
  449 #endif
  450         if (args->pid <= 0 || args->tgid <= 0)
  451                 return (EINVAL);
  452 
  453         return (linux_do_tkill(args->tgid, args->pid, args->sig));
  454 }
  455 
  456 int
  457 sys_linux_tkill(struct linux_tkill_args *args)
  458 {
  459 #ifdef DEBUG
  460         if (ldebug(tkill))
  461                 kprintf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
  462 #endif
  463         if (args->tid <= 0)
  464                 return (EINVAL);
  465 
  466         return (linux_do_tkill(0, args->tid, args->sig));
  467 }
  468 

Cache object: fb1e8801189868ef64ef334746eef2f4


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