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/common/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 /*      $NetBSD: linux_signal.c,v 1.41 2003/07/03 21:22:32 christos Exp $       */
    2 /*-
    3  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
    4  * All rights reserved.
    5  *
    6  * This code is derived from software contributed to The NetBSD Foundation
    7  * by Frank van der Linden and Eric Haszlakiewicz.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by the NetBSD
   20  *      Foundation, Inc. and its contributors.
   21  * 4. Neither the name of The NetBSD Foundation nor the names of its
   22  *    contributors may be used to endorse or promote products derived
   23  *    from this software without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35  * POSSIBILITY OF SUCH DAMAGE.
   36  */
   37 /*
   38  * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
   39  */
   40 
   41 /*
   42  *   Functions in multiarch:
   43  *      linux_sys_signal        : linux_sig_notalpha.c
   44  *      linux_sys_siggetmask    : linux_sig_notalpha.c
   45  *      linux_sys_sigsetmask    : linux_sig_notalpha.c
   46  *      linux_sys_pause         : linux_sig_notalpha.c
   47  *      linux_sys_sigaction     : linux_sigaction.c
   48  *
   49  */
   50 
   51 /*
   52  *   Unimplemented:
   53  *      linux_sys_rt_sigtimedwait       : sigsuspend w/timeout.
   54  */
   55 
   56 #include <sys/cdefs.h>
   57 __KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.41 2003/07/03 21:22:32 christos Exp $");
   58 
   59 #define COMPAT_LINUX 1
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/namei.h>
   64 #include <sys/proc.h>
   65 #include <sys/filedesc.h>
   66 #include <sys/ioctl.h>
   67 #include <sys/mount.h>
   68 #include <sys/kernel.h>
   69 #include <sys/signal.h>
   70 #include <sys/signalvar.h>
   71 #include <sys/malloc.h>
   72 
   73 #include <sys/sa.h>
   74 #include <sys/syscallargs.h>
   75 
   76 #include <compat/linux/common/linux_types.h>
   77 #include <compat/linux/common/linux_signal.h>
   78 #include <compat/linux/common/linux_siginfo.h>
   79 #include <compat/linux/common/linux_util.h>
   80 
   81 #include <compat/linux/linux_syscallargs.h>
   82 
   83 /* Locally used defines (in bsd<->linux conversion functions): */
   84 #define linux_sigemptyset(s)    memset((s), 0, sizeof(*(s)))
   85 #define linux_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
   86                                         & (1 << ((n) - 1) % LINUX__NSIG_BPW))
   87 #define linux_sigaddset(s, n)   ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
   88                                         |= (1 << ((n) - 1) % LINUX__NSIG_BPW))
   89 
   90 #ifdef DEBUG_LINUX
   91 #define DPRINTF(a)      uprintf a
   92 #else
   93 #define DPRINTF(a)
   94 #endif
   95 
   96 extern const int native_to_linux_signo[];
   97 extern const int linux_to_native_signo[];
   98 
   99 /*
  100  * Convert between Linux and BSD signal sets.
  101  */
  102 #if LINUX__NSIG_WORDS > 1
  103 void
  104 linux_old_extra_to_native_sigset(bss, lss, extra)
  105         sigset_t *bss;
  106         const linux_old_sigset_t *lss;
  107         const unsigned long *extra;
  108 {
  109         linux_sigset_t lsnew;
  110 
  111         /* convert old sigset to new sigset */
  112         linux_sigemptyset(&lsnew);
  113         lsnew.sig[0] = *lss;
  114         if (extra)
  115                 memcpy(&lsnew.sig[1], extra,
  116                     sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
  117 
  118         linux_to_native_sigset(bss, &lsnew);
  119 }
  120 
  121 void
  122 native_to_linux_old_extra_sigset(lss, extra, bss)
  123         linux_old_sigset_t *lss;
  124         unsigned long *extra;
  125         const sigset_t *bss;
  126 {
  127         linux_sigset_t lsnew;
  128 
  129         native_to_linux_sigset(&lsnew, bss);
  130 
  131         /* convert new sigset to old sigset */
  132         *lss = lsnew.sig[0];
  133         if (extra)
  134                 memcpy(extra, &lsnew.sig[1],
  135                     sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
  136 }
  137 #endif
  138 
  139 void
  140 linux_to_native_sigset(bss, lss)
  141         sigset_t *bss;
  142         const linux_sigset_t *lss;
  143 {
  144         int i, newsig;
  145 
  146         sigemptyset(bss);
  147         for (i = 1; i < LINUX__NSIG; i++) {
  148                 if (linux_sigismember(lss, i)) {
  149                         newsig = linux_to_native_signo[i];
  150                         if (newsig)
  151                                 sigaddset(bss, newsig);
  152                 }
  153         }
  154 }
  155 
  156 void
  157 native_to_linux_sigset(lss, bss)
  158         linux_sigset_t *lss;
  159         const sigset_t *bss;
  160 {
  161         int i, newsig;
  162 
  163         linux_sigemptyset(lss);
  164         for (i = 1; i < NSIG; i++) {
  165                 if (sigismember(bss, i)) {
  166                         newsig = native_to_linux_signo[i];
  167                         if (newsig)
  168                                 linux_sigaddset(lss, newsig);
  169                 }
  170         }
  171 }
  172 
  173 unsigned int
  174 native_to_linux_sigflags(bsf)
  175         const int bsf;
  176 {
  177         unsigned int lsf = 0;
  178         if ((bsf & SA_NOCLDSTOP) != 0)
  179                 lsf |= LINUX_SA_NOCLDSTOP;
  180         if ((bsf & SA_NOCLDWAIT) != 0)
  181                 lsf |= LINUX_SA_NOCLDWAIT;
  182         if ((bsf & SA_ONSTACK) != 0)
  183                 lsf |= LINUX_SA_ONSTACK;
  184         if ((bsf & SA_RESTART) != 0)
  185                 lsf |= LINUX_SA_RESTART;
  186         if ((bsf & SA_NODEFER) != 0)
  187                 lsf |= LINUX_SA_NOMASK;
  188         if ((bsf & SA_RESETHAND) != 0)
  189                 lsf |= LINUX_SA_ONESHOT;
  190         if ((bsf & SA_SIGINFO) != 0)
  191                 lsf |= LINUX_SA_SIGINFO;
  192         return lsf;
  193 }
  194 
  195 int
  196 linux_to_native_sigflags(lsf)
  197         const unsigned long lsf;
  198 {
  199         int bsf = 0;
  200         if ((lsf & LINUX_SA_NOCLDSTOP) != 0)
  201                 bsf |= SA_NOCLDSTOP;
  202         if ((lsf & LINUX_SA_NOCLDWAIT) != 0)
  203                 bsf |= SA_NOCLDWAIT;
  204         if ((lsf & LINUX_SA_ONSTACK) != 0)
  205                 bsf |= SA_ONSTACK;
  206         if ((lsf & LINUX_SA_RESTART) != 0)
  207                 bsf |= SA_RESTART;
  208         if ((lsf & LINUX_SA_ONESHOT) != 0)
  209                 bsf |= SA_RESETHAND;
  210         if ((lsf & LINUX_SA_NOMASK) != 0)
  211                 bsf |= SA_NODEFER;
  212         if ((lsf & LINUX_SA_SIGINFO) != 0)
  213                 bsf |= SA_SIGINFO;
  214         if ((lsf & ~LINUX_SA_ALLBITS) != 0)
  215                 DPRINTF(("linux_old_to_native_sigflags: "
  216                     "%lx extra bits ignored\n", lsf));
  217         return bsf;
  218 }
  219 
  220 /*
  221  * Convert between Linux and BSD sigaction structures. Linux sometimes
  222  * has one extra field (sa_restorer) which we don't support.
  223  */
  224 void
  225 linux_old_to_native_sigaction(bsa, lsa)
  226         struct sigaction *bsa;
  227         const struct linux_old_sigaction *lsa;
  228 {
  229         bsa->sa_handler = lsa->linux_sa_handler;
  230         linux_old_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
  231         bsa->sa_flags = linux_to_native_sigflags(lsa->linux_sa_flags);
  232 #ifndef __alpha__
  233 /*
  234  * XXX: On the alpha sa_restorer is elsewhere.
  235  */
  236         if (lsa->linux_sa_restorer != NULL)
  237                 DPRINTF(("linux_old_to_native_sigaction: "
  238                     "sa_restorer ignored\n"));
  239 #endif
  240 }
  241 
  242 void
  243 native_to_linux_old_sigaction(lsa, bsa)
  244         struct linux_old_sigaction *lsa;
  245         const struct sigaction *bsa;
  246 {
  247         lsa->linux_sa_handler = bsa->sa_handler;
  248         native_to_linux_old_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
  249         lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
  250 #ifndef __alpha__
  251         lsa->linux_sa_restorer = NULL;
  252 #endif
  253 }
  254 
  255 /* ...and the new sigaction conversion funcs. */
  256 void
  257 linux_to_native_sigaction(bsa, lsa)
  258         struct sigaction *bsa;
  259         const struct linux_sigaction *lsa;
  260 {
  261         bsa->sa_handler = lsa->linux_sa_handler;
  262         linux_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
  263         bsa->sa_flags = linux_to_native_sigflags(lsa->linux_sa_flags);
  264 #ifndef __alpha__
  265         if (lsa->linux_sa_restorer != 0)
  266                 DPRINTF(("linux_to_native_sigaction: sa_restorer ignored\n"));
  267 #endif
  268 }
  269 
  270 void
  271 native_to_linux_sigaction(lsa, bsa)
  272         struct linux_sigaction *lsa;
  273         const struct sigaction *bsa;
  274 {
  275         lsa->linux_sa_handler = bsa->sa_handler;
  276         native_to_linux_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
  277         lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
  278 #ifndef __alpha__
  279         lsa->linux_sa_restorer = NULL;
  280 #endif
  281 }
  282 
  283 /* ----------------------------------------------------------------------- */
  284 
  285 /*
  286  * The Linux sigaction() system call. Do the usual conversions,
  287  * and just call sigaction(). Some flags and values are silently
  288  * ignored (see above).
  289  */
  290 int
  291 linux_sys_rt_sigaction(l, v, retval)
  292         struct lwp *l;
  293         void *v;
  294         register_t *retval;
  295 {
  296         struct linux_sys_rt_sigaction_args /* {
  297                 syscallarg(int) signum;
  298                 syscallarg(const struct linux_sigaction *) nsa;
  299                 syscallarg(struct linux_sigaction *) osa;
  300                 syscallarg(size_t) sigsetsize;
  301         } */ *uap = v;
  302         struct proc *p = l->l_proc;
  303         struct linux_sigaction nlsa, olsa;
  304         struct sigaction nbsa, obsa;
  305         int error, sig;
  306 
  307         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  308                 return (EINVAL);
  309 
  310         if (SCARG(uap, nsa)) {
  311                 error = copyin(SCARG(uap, nsa), &nlsa, sizeof(nlsa));
  312                 if (error)
  313                         return (error);
  314                 linux_to_native_sigaction(&nbsa, &nlsa);
  315         }
  316         sig = SCARG(uap, signum);
  317         if (sig < 0 || sig >= LINUX__NSIG)
  318                 return (EINVAL);
  319         if (sig > 0 && !linux_to_native_signo[sig]) {
  320                 /* Pretend that we did something useful for unknown signals. */
  321                 obsa.sa_handler = SIG_IGN;
  322                 sigemptyset(&obsa.sa_mask);
  323                 obsa.sa_flags = 0;
  324         } else {
  325                 error = sigaction1(p, linux_to_native_signo[sig],
  326                     SCARG(uap, nsa) ? &nbsa : NULL,
  327                     SCARG(uap, osa) ? &obsa : NULL,
  328                     NULL, 0);
  329                 if (error)
  330                         return (error);
  331         }
  332         if (SCARG(uap, osa)) {
  333                 native_to_linux_sigaction(&olsa, &obsa);
  334                 error = copyout(&olsa, SCARG(uap, osa), sizeof(olsa));
  335                 if (error)
  336                         return (error);
  337         }
  338         return (0);
  339 }
  340 
  341 int
  342 linux_sigprocmask1(p, how, set, oset)
  343         struct proc *p;
  344         int how;
  345         const linux_old_sigset_t *set;
  346         linux_old_sigset_t *oset;
  347 {
  348         linux_old_sigset_t nlss, olss;
  349         sigset_t nbss, obss;
  350         int error;
  351 
  352         switch (how) {
  353         case LINUX_SIG_BLOCK:
  354                 how = SIG_BLOCK;
  355                 break;
  356         case LINUX_SIG_UNBLOCK:
  357                 how = SIG_UNBLOCK;
  358                 break;
  359         case LINUX_SIG_SETMASK:
  360                 how = SIG_SETMASK;
  361                 break;
  362         default:
  363                 return (EINVAL);
  364         }
  365 
  366         if (set) {
  367                 error = copyin(set, &nlss, sizeof(nlss));
  368                 if (error)
  369                         return (error);
  370                 linux_old_to_native_sigset(&nbss, &nlss);
  371         }
  372         error = sigprocmask1(p, how,
  373             set ? &nbss : NULL, oset ? &obss : NULL);
  374         if (error)
  375                 return (error); 
  376         if (oset) {
  377                 native_to_linux_old_sigset(&olss, &obss);
  378                 error = copyout(&olss, oset, sizeof(olss));
  379                 if (error)
  380                         return (error);
  381         }       
  382         return (error);
  383 }
  384 
  385 int
  386 linux_sys_rt_sigprocmask(l, v, retval)
  387         struct lwp *l;
  388         void *v;
  389         register_t *retval;
  390 {
  391         struct linux_sys_rt_sigprocmask_args /* {
  392                 syscallarg(int) how;
  393                 syscallarg(const linux_sigset_t *) set;
  394                 syscallarg(linux_sigset_t *) oset;
  395                 syscallarg(size_t) sigsetsize;
  396         } */ *uap = v;
  397         struct proc *p = l->l_proc;
  398         linux_sigset_t nlss, olss, *oset;
  399         const linux_sigset_t *set;
  400         sigset_t nbss, obss;
  401         int error, how;
  402 
  403         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  404                 return (EINVAL);
  405 
  406         switch (SCARG(uap, how)) {
  407         case LINUX_SIG_BLOCK:
  408                 how = SIG_BLOCK;
  409                 break;
  410         case LINUX_SIG_UNBLOCK:
  411                 how = SIG_UNBLOCK;
  412                 break;
  413         case LINUX_SIG_SETMASK:
  414                 how = SIG_SETMASK;
  415                 break;
  416         default:
  417                 return (EINVAL);
  418         }
  419 
  420         set = SCARG(uap, set);
  421         oset = SCARG(uap, oset);
  422 
  423         if (set) {
  424                 error = copyin(set, &nlss, sizeof(nlss));
  425                 if (error)
  426                         return (error);
  427                 linux_to_native_sigset(&nbss, &nlss);
  428         }
  429         error = sigprocmask1(p, how,
  430             set ? &nbss : NULL, oset ? &obss : NULL);
  431         if (!error && oset) {
  432                 native_to_linux_sigset(&olss, &obss);
  433                 error = copyout(&olss, oset, sizeof(olss));
  434         }       
  435         return (error);
  436 }
  437 
  438 int
  439 linux_sys_rt_sigpending(l, v, retval)
  440         struct lwp *l;
  441         void *v;
  442         register_t *retval;
  443 {
  444         struct linux_sys_rt_sigpending_args /* {
  445                 syscallarg(linux_sigset_t *) set;
  446                 syscallarg(size_t) sigsetsize;
  447         } */ *uap = v;
  448         struct proc *p = l->l_proc;
  449         sigset_t bss;
  450         linux_sigset_t lss;
  451 
  452         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  453                 return (EINVAL);
  454 
  455         sigpending1(p, &bss);
  456         native_to_linux_sigset(&lss, &bss);
  457         return copyout(&lss, SCARG(uap, set), sizeof(lss));
  458 }
  459 
  460 int
  461 linux_sys_sigpending(l, v, retval)
  462         struct lwp *l;
  463         void *v;
  464         register_t *retval;
  465 {
  466         struct linux_sys_sigpending_args /* {
  467                 syscallarg(linux_old_sigset_t *) mask;
  468         } */ *uap = v;
  469         struct proc *p = l->l_proc;
  470         sigset_t bss;
  471         linux_old_sigset_t lss;
  472 
  473         sigpending1(p, &bss);
  474         native_to_linux_old_sigset(&lss, &bss);
  475         return copyout(&lss, SCARG(uap, set), sizeof(lss));
  476 }
  477 
  478 int
  479 linux_sys_sigsuspend(l, v, retval)
  480         struct lwp *l;
  481         void *v;
  482         register_t *retval;
  483 {
  484         struct linux_sys_sigsuspend_args /* {
  485                 syscallarg(caddr_t) restart;
  486                 syscallarg(int) oldmask;
  487                 syscallarg(int) mask;
  488         } */ *uap = v;
  489         struct proc *p = l->l_proc;
  490         linux_old_sigset_t lss;
  491         sigset_t bss;
  492 
  493         lss = SCARG(uap, mask);
  494         linux_old_to_native_sigset(&bss, &lss);
  495         return (sigsuspend1(p, &bss));
  496 }
  497 int
  498 linux_sys_rt_sigsuspend(l, v, retval)
  499         struct lwp *l;
  500         void *v;
  501         register_t *retval;
  502 {
  503         struct linux_sys_rt_sigsuspend_args /* {
  504                 syscallarg(linux_sigset_t *) unewset;
  505                 syscallarg(size_t) sigsetsize;
  506         } */ *uap = v;
  507         struct proc *p = l->l_proc;
  508         linux_sigset_t lss;
  509         sigset_t bss;
  510         int error;
  511 
  512         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  513                 return (EINVAL);
  514 
  515         error = copyin(SCARG(uap, unewset), &lss, sizeof(linux_sigset_t));
  516         if (error)
  517                 return (error);
  518 
  519         linux_to_native_sigset(&bss, &lss);
  520 
  521         return (sigsuspend1(p, &bss));
  522 }
  523 
  524 /*
  525  * Once more: only a signal conversion is needed.
  526  * Note: also used as sys_rt_queueinfo.  The info field is ignored.
  527  */
  528 int
  529 linux_sys_rt_queueinfo(l, v, retval)
  530         struct lwp *l;
  531         void *v;
  532         register_t *retval;
  533 {
  534         /* XXX XAX This isn't this really int, int, siginfo_t *, is it? */
  535 #if 0
  536         struct linux_sys_rt_queueinfo_args /* {
  537                 syscallarg(int) pid;
  538                 syscallarg(int) signum;
  539                 syscallarg(siginfo_t *) uinfo;
  540         } */ *uap = v;
  541 #endif
  542 
  543         /* XXX To really implement this we need to      */
  544         /* XXX keep a list of queued signals somewhere. */
  545         return (linux_sys_kill(l, v, retval));
  546 }
  547 
  548 int
  549 linux_sys_kill(l, v, retval)
  550         struct lwp *l;
  551         void *v;
  552         register_t *retval;
  553 {
  554         struct linux_sys_kill_args /* {
  555                 syscallarg(int) pid;
  556                 syscallarg(int) signum;
  557         } */ *uap = v;
  558 
  559         struct sys_kill_args ka;
  560         int sig;
  561 
  562         SCARG(&ka, pid) = SCARG(uap, pid);
  563         sig = SCARG(uap, signum);
  564         if (sig < 0 || sig >= LINUX__NSIG)
  565                 return (EINVAL);
  566         SCARG(&ka, signum) = linux_to_native_signo[sig];
  567         return sys_kill(l, &ka, retval);
  568 }
  569 
  570 #ifdef LINUX_SS_ONSTACK
  571 static void linux_to_native_sigaltstack __P((struct sigaltstack *,
  572     const struct linux_sigaltstack *));
  573 
  574 static void
  575 linux_to_native_sigaltstack(bss, lss)
  576         struct sigaltstack *bss;
  577         const struct linux_sigaltstack *lss;
  578 {
  579         bss->ss_sp = lss->ss_sp;
  580         bss->ss_size = lss->ss_size;
  581         if (lss->ss_flags & LINUX_SS_ONSTACK)
  582             bss->ss_flags = SS_ONSTACK;
  583         else if (lss->ss_flags & LINUX_SS_DISABLE)
  584             bss->ss_flags = SS_DISABLE;
  585         else
  586             bss->ss_flags = 0;
  587 }
  588 
  589 void
  590 native_to_linux_sigaltstack(lss, bss)
  591         struct linux_sigaltstack *lss;
  592         const struct sigaltstack *bss;
  593 {
  594         lss->ss_sp = bss->ss_sp;
  595         lss->ss_size = bss->ss_size;
  596         if (bss->ss_flags & SS_ONSTACK)
  597             lss->ss_flags = LINUX_SS_ONSTACK;
  598         else if (bss->ss_flags & SS_DISABLE)
  599             lss->ss_flags = LINUX_SS_DISABLE;
  600         else
  601             lss->ss_flags = 0;
  602 }
  603 
  604 int
  605 linux_sys_sigaltstack(l, v, retval)
  606         struct lwp *l;
  607         void *v;
  608         register_t *retval;
  609 {
  610         struct linux_sys_sigaltstack_args /* {
  611                 syscallarg(const struct linux_sigaltstack *) ss;
  612                 syscallarg(struct linux_sigaltstack *) oss;
  613         } */ *uap = v;
  614         struct proc *p = l->l_proc;
  615         struct linux_sigaltstack ss;
  616         struct sigaltstack nss, oss;
  617         int error;
  618 
  619         if (SCARG(uap, ss) != NULL) {
  620                 if ((error = copyin(SCARG(uap, ss), &ss, sizeof(ss))) != 0)
  621                         return error;
  622                 linux_to_native_sigaltstack(&nss, &ss);
  623         }
  624 
  625         error = sigaltstack1(p,
  626             SCARG(uap, ss) ? &nss : NULL, SCARG(uap, oss) ? &oss : NULL);
  627         if (error)
  628                 return error;
  629 
  630         if (SCARG(uap, oss) != NULL) {
  631                 native_to_linux_sigaltstack(&ss, &oss);
  632                 if ((error = copyout(&ss, SCARG(uap, oss), sizeof(ss))) != 0)
  633                         return error;
  634         }
  635         return 0;
  636 }
  637 #endif

Cache object: c454a1a3a2579e113a83c4cc15790147


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