root/compat/linux/linux_signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. linux_old_to_bsd_sigset
  2. bsd_to_linux_old_sigset
  3. linux_old_extra_to_bsd_sigset
  4. bsd_to_linux_old_extra_sigset
  5. linux_to_bsd_sigset
  6. bsd_to_linux_sigset
  7. linux_old_to_bsd_sigaction
  8. bsd_to_linux_old_sigaction
  9. linux_to_bsd_sigaction
  10. bsd_to_linux_sigaction
  11. linux_to_bsd_signal
  12. bsd_to_linux_signal
  13. linux_sys_sigaction
  14. linux_sys_rt_sigaction
  15. linux_sys_signal
  16. linux_sys_sigprocmask
  17. linux_sys_rt_sigprocmask
  18. linux_sys_siggetmask
  19. linux_sys_sigsetmask
  20. linux_sys_sigpending
  21. linux_sys_rt_sigpending
  22. linux_sys_sigsuspend
  23. linux_sys_rt_sigsuspend
  24. linux_sys_sigaltstack
  25. linux_sys_pause
  26. linux_sys_kill

    1 /*      $OpenBSD: linux_signal.c,v 1.12 2003/02/25 09:10:27 tedu Exp $  */
    2 /*      $NetBSD: linux_signal.c,v 1.10 1996/04/04 23:51:36 christos Exp $       */
    3 
    4 /*
    5  * Copyright (c) 1995 Frank van der Linden
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed for the NetBSD Project
   19  *      by Frank van der Linden
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/namei.h>
   40 #include <sys/proc.h>
   41 #include <sys/filedesc.h>
   42 #include <sys/ioctl.h>
   43 #include <sys/mount.h>
   44 #include <sys/kernel.h>
   45 #include <sys/signal.h>
   46 #include <sys/signalvar.h>
   47 #include <sys/malloc.h>
   48 
   49 #include <sys/syscallargs.h>
   50 
   51 #include <compat/linux/linux_types.h>
   52 #include <compat/linux/linux_signal.h>
   53 #include <compat/linux/linux_syscallargs.h>
   54 #include <compat/linux/linux_util.h>
   55 
   56 #define sigemptyset(s)          bzero((s), sizeof(*(s)))
   57 #define sigismember(s, n)       (*(s) & sigmask(n))
   58 #define sigaddset(s, n)         (*(s) |= sigmask(n))
   59  
   60 /* Locally used defines (in bsd<->linux conversion functions): */
   61 #define linux_sigmask(n)        (1 << ((n) - 1))
   62 #define linux_sigemptyset(s)    bzero((s), sizeof(*(s)))
   63 #define linux_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
   64                                         & (1 << ((n) - 1) % LINUX__NSIG_BPW))
   65 #define linux_sigaddset(s, n)   ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
   66                                         |= (1 << ((n) - 1) % LINUX__NSIG_BPW))
   67 
   68 int bsd_to_linux_sig[NSIG] = {
   69         0,
   70         LINUX_SIGHUP,
   71         LINUX_SIGINT,
   72         LINUX_SIGQUIT,
   73         LINUX_SIGILL,
   74         LINUX_SIGTRAP,
   75         LINUX_SIGABRT,
   76         LINUX_NSIG,             /* XXX Kludge to get RT signal #32 to work */
   77         LINUX_SIGFPE,
   78         LINUX_SIGKILL,
   79         LINUX_SIGBUS,
   80         LINUX_SIGSEGV,
   81         LINUX_NSIG + 1,                 /* XXX Kludge to get RT signal #32 to work */
   82         LINUX_SIGPIPE,
   83         LINUX_SIGALRM,
   84         LINUX_SIGTERM,
   85         LINUX_SIGURG,
   86         LINUX_SIGSTOP,
   87         LINUX_SIGTSTP,
   88         LINUX_SIGCONT,
   89         LINUX_SIGCHLD,
   90         LINUX_SIGTTIN,
   91         LINUX_SIGTTOU,
   92         LINUX_SIGIO,
   93         LINUX_SIGXCPU,
   94         LINUX_SIGXFSZ,
   95         LINUX_SIGVTALRM,
   96         LINUX_SIGPROF,
   97         LINUX_SIGWINCH,
   98         0,                      /* SIGINFO */
   99         LINUX_SIGUSR1,
  100         LINUX_SIGUSR2,
  101 };
  102 
  103 int linux_to_bsd_sig[LINUX__NSIG] = {
  104         0,
  105         SIGHUP,
  106         SIGINT,
  107         SIGQUIT,
  108         SIGILL,
  109         SIGTRAP,
  110         SIGABRT,
  111         SIGBUS,
  112         SIGFPE,
  113         SIGKILL,
  114         SIGUSR1,
  115         SIGSEGV,
  116         SIGUSR2,
  117         SIGPIPE,
  118         SIGALRM,
  119         SIGTERM,
  120         0,                      /* SIGSTKFLT */
  121         SIGCHLD,
  122         SIGCONT,
  123         SIGSTOP,
  124         SIGTSTP,
  125         SIGTTIN,
  126         SIGTTOU,
  127         SIGURG,
  128         SIGXCPU,
  129         SIGXFSZ,
  130         SIGVTALRM,
  131         SIGPROF,
  132         SIGWINCH,
  133         SIGIO,
  134         0,                      /* SIGUNUSED */
  135         0,
  136         SIGEMT,                 /* XXX Gruesome hack for linuxthreads:       */
  137         SIGSYS,                 /* Map 1st 2 RT signals onto ones we handle. */
  138         0,
  139         0,
  140         0,
  141         0,
  142         0,
  143         0,
  144         0,
  145         0,
  146         0,
  147         0,
  148         0,
  149         0,
  150         0,
  151         0,
  152         0,
  153         0,
  154         0,
  155         0,
  156         0,
  157         0,
  158         0,
  159         0,
  160         0,
  161         0,
  162         0,
  163         0,
  164         0,
  165         0,
  166         0,
  167         0,
  168 };
  169 
  170 /*
  171  * Convert between Linux and BSD signal sets.
  172  */
  173 void
  174 linux_old_to_bsd_sigset(lss, bss)
  175         const linux_old_sigset_t *lss;
  176         sigset_t *bss;
  177 {
  178         linux_old_extra_to_bsd_sigset(lss, (const unsigned long *) 0, bss);    
  179 }
  180 
  181 void
  182 bsd_to_linux_old_sigset(bss, lss)
  183         const sigset_t *bss;
  184         linux_old_sigset_t *lss;
  185 {
  186         bsd_to_linux_old_extra_sigset(bss, lss, (unsigned long *) 0); 
  187 }
  188 
  189 void
  190 linux_old_extra_to_bsd_sigset(lss, extra, bss)
  191         const linux_old_sigset_t *lss;
  192         const unsigned long *extra;
  193         sigset_t *bss;
  194 {
  195         linux_sigset_t lsnew;
  196 
  197         /* convert old sigset to new sigset */
  198         linux_sigemptyset(&lsnew);
  199         lsnew.sig[0] = *lss;
  200         if (extra)
  201                 bcopy(extra, &lsnew.sig[1],
  202                         sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
  203 
  204         linux_to_bsd_sigset(&lsnew, bss);
  205 }
  206 
  207 void
  208 bsd_to_linux_old_extra_sigset(bss, lss, extra)
  209         const sigset_t *bss;
  210         linux_old_sigset_t *lss;
  211         unsigned long *extra;
  212 {
  213         linux_sigset_t lsnew;
  214 
  215         bsd_to_linux_sigset(bss, &lsnew);
  216 
  217         /* convert new sigset to old sigset */
  218         *lss = lsnew.sig[0];
  219         if (extra)
  220                 bcopy(&lsnew.sig[1], extra,
  221                         sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
  222 }
  223 
  224 void
  225 linux_to_bsd_sigset(lss, bss)
  226         const linux_sigset_t *lss;
  227         sigset_t *bss;
  228 {
  229         int i, newsig;
  230 
  231         sigemptyset(bss);
  232         for (i = 1; i < LINUX__NSIG; i++) {
  233                 if (linux_sigismember(lss, i)) {
  234                         newsig = linux_to_bsd_sig[i];
  235                         if (newsig)
  236                                 sigaddset(bss, newsig);
  237                 }
  238         }
  239 }
  240 
  241 void
  242 bsd_to_linux_sigset(bss, lss)
  243         const sigset_t *bss;
  244         linux_sigset_t *lss;
  245 {
  246         int i, newsig;
  247 
  248         linux_sigemptyset(lss);
  249         for (i = 1; i < NSIG; i++) {
  250                 if (sigismember(bss, i)) {
  251                         newsig = bsd_to_linux_sig[i];
  252                         if (newsig)
  253                                 linux_sigaddset(lss, newsig);
  254                 }
  255         }
  256 }
  257 
  258 /*
  259  * Convert between Linux and BSD sigaction structures. Linux has
  260  * one extra field (sa_restorer) which we don't support.
  261  */
  262 void
  263 linux_old_to_bsd_sigaction(lsa, bsa)
  264         struct linux_old_sigaction *lsa;
  265         struct sigaction *bsa;
  266 {
  267 
  268         bsa->sa_handler = lsa->sa__handler;
  269         linux_old_to_bsd_sigset(&lsa->sa_mask, &bsa->sa_mask);
  270         bsa->sa_flags = 0;
  271         if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
  272                 bsa->sa_flags |= SA_ONSTACK;
  273         if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
  274                 bsa->sa_flags |= SA_RESTART;
  275         if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
  276                 bsa->sa_flags |= SA_RESETHAND;
  277         if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
  278                 bsa->sa_flags |= SA_NOCLDSTOP;
  279         if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
  280                 bsa->sa_flags |= SA_NODEFER;
  281 }
  282 
  283 void
  284 bsd_to_linux_old_sigaction(bsa, lsa)
  285         struct sigaction *bsa;
  286         struct linux_old_sigaction *lsa;
  287 {
  288 
  289         lsa->sa__handler = bsa->sa_handler;
  290         bsd_to_linux_old_sigset(&bsa->sa_mask, &lsa->sa_mask);
  291         lsa->sa_flags = 0;
  292         if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
  293                 lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
  294         if ((bsa->sa_flags & SA_ONSTACK) != 0)
  295                 lsa->sa_flags |= LINUX_SA_ONSTACK;
  296         if ((bsa->sa_flags & SA_RESTART) != 0)
  297                 lsa->sa_flags |= LINUX_SA_RESTART;
  298         if ((bsa->sa_flags & SA_NODEFER) != 0)
  299                 lsa->sa_flags |= LINUX_SA_NOMASK;
  300         if ((bsa->sa_flags & SA_RESETHAND) != 0)
  301                 lsa->sa_flags |= LINUX_SA_ONESHOT;
  302         lsa->sa_restorer = NULL;
  303 }
  304 
  305 void
  306 linux_to_bsd_sigaction(lsa, bsa)
  307         struct linux_sigaction *lsa;
  308         struct sigaction *bsa;
  309 {
  310 
  311         bsa->sa_handler = lsa->sa__handler;
  312         linux_to_bsd_sigset(&lsa->sa_mask, &bsa->sa_mask);
  313         bsa->sa_flags = 0;
  314         if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
  315                 bsa->sa_flags |= SA_NOCLDSTOP;
  316         if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
  317                 bsa->sa_flags |= SA_ONSTACK;
  318         if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
  319                 bsa->sa_flags |= SA_RESTART;
  320         if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
  321                 bsa->sa_flags |= SA_RESETHAND;
  322         if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
  323                 bsa->sa_flags |= SA_NODEFER;
  324         if ((lsa->sa_flags & LINUX_SA_SIGINFO) != 0)
  325                 bsa->sa_flags |= SA_SIGINFO;
  326 }
  327 
  328 void
  329 bsd_to_linux_sigaction(bsa, lsa)
  330         struct sigaction *bsa;
  331         struct linux_sigaction *lsa;
  332 {
  333 
  334         /* Clear sa_flags and sa_restorer (if it exists) */
  335         bzero(lsa, sizeof(struct linux_sigaction));
  336 
  337         /* ...and fill in the mask and flags */
  338         bsd_to_linux_sigset(&bsa->sa_mask, &lsa->sa_mask);
  339         if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
  340                 lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
  341         if ((bsa->sa_flags & SA_ONSTACK) != 0)
  342                 lsa->sa_flags |= LINUX_SA_ONSTACK;
  343         if ((bsa->sa_flags & SA_RESTART) != 0)
  344                 lsa->sa_flags |= LINUX_SA_RESTART;
  345         if ((bsa->sa_flags & SA_NODEFER) != 0)
  346                 lsa->sa_flags |= LINUX_SA_NOMASK;
  347         if ((bsa->sa_flags & SA_RESETHAND) != 0)
  348                 lsa->sa_flags |= LINUX_SA_ONESHOT;
  349         if ((bsa->sa_flags & SA_SIGINFO) != 0)
  350                 lsa->sa_flags |= LINUX_SA_SIGINFO;
  351         lsa->sa__handler = bsa->sa_handler;
  352 }
  353 
  354 int
  355 linux_to_bsd_signal(int linuxsig, int *bsdsig)
  356 {
  357         if (linuxsig < 0 || linuxsig >= LINUX__NSIG)
  358                 return (EINVAL);
  359 
  360         *bsdsig = linux_to_bsd_sig[linuxsig];
  361         return (0);
  362 }
  363 
  364 int
  365 bsd_to_linux_signal(int bsdsig, int *linuxsig)
  366 {
  367         if (bsdsig < 0 || bsdsig >= NSIG)
  368                 return (EINVAL);
  369 
  370         *linuxsig = bsd_to_linux_sig[bsdsig];
  371         return (0);
  372 }
  373 
  374 /*
  375  * The Linux sigaction() system call. Do the usual conversions,
  376  * and just call sigaction(). Some flags and values are silently
  377  * ignored (see above).
  378  */
  379 int
  380 linux_sys_sigaction(p, v, retval)
  381         register struct proc *p;
  382         void *v;
  383         register_t *retval;
  384 {
  385         struct linux_sys_sigaction_args /* {
  386                 syscallarg(int) signum;
  387                 syscallarg(struct linux_old_sigaction *) nsa;
  388                 syscallarg(struct linux_old_sigaction *) osa;
  389         } */ *uap = v;
  390         struct linux_old_sigaction *nlsa, *olsa, tmplsa;
  391         struct sigaction *nbsa, *obsa, tmpbsa;
  392         struct sys_sigaction_args sa;
  393         caddr_t sg;
  394         int error;
  395 
  396         if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
  397                 return (EINVAL);
  398 
  399         sg = stackgap_init(p->p_emul);
  400         nlsa = SCARG(uap, nsa);
  401         olsa = SCARG(uap, osa);
  402 
  403         if (olsa != NULL)
  404                 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  405         else
  406                 obsa = NULL;
  407 
  408         if (nlsa != NULL) {
  409                 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  410                 if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
  411                         return (error);
  412                 linux_old_to_bsd_sigaction(&tmplsa, &tmpbsa);
  413                 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
  414                         return (error);
  415         } else
  416                 nbsa = NULL;
  417 
  418         SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
  419         SCARG(&sa, nsa) = nbsa;
  420         SCARG(&sa, osa) = obsa;
  421 
  422         /* Silently ignore unknown signals */
  423         if (SCARG(&sa, signum) == 0) {
  424                 if (obsa != NULL) {
  425                         obsa->sa_handler = SIG_IGN;
  426                         sigemptyset(&obsa->sa_mask);
  427                         obsa->sa_flags = 0;
  428                 }
  429         }
  430         else {
  431                 if ((error = sys_sigaction(p, &sa, retval)) != 0)
  432                         return (error);
  433         }
  434 
  435         if (olsa != NULL) {
  436                 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
  437                         return (error);
  438                 bsd_to_linux_old_sigaction(&tmpbsa, &tmplsa);
  439                 if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
  440                         return (error);
  441         }
  442 
  443         return (0);
  444 }
  445 
  446 int
  447 linux_sys_rt_sigaction(p, v, retval)
  448         register struct proc *p;
  449         void *v;
  450         register_t *retval;
  451 {
  452         struct linux_sys_rt_sigaction_args /* {
  453                 syscallarg(int) signum;
  454                 syscallarg(struct linux_sigaction *) nsa;
  455                 syscallarg(struct linux_sigaction *) osa;
  456                 syscallarg(size_t) sigsetsize;
  457         } */ *uap = v;
  458         struct linux_sigaction *nlsa, *olsa, tmplsa;
  459         struct sigaction *nbsa, *obsa, tmpbsa;
  460         struct sys_sigaction_args sa;
  461         caddr_t sg;
  462         int error;
  463 
  464         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  465                 return (EINVAL);
  466 
  467         if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
  468                 return (EINVAL);
  469 
  470         sg = stackgap_init(p->p_emul);
  471         nlsa = SCARG(uap, nsa);
  472         olsa = SCARG(uap, osa);
  473 
  474         if (olsa != NULL) 
  475                 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  476         else
  477                 obsa = NULL;
  478 
  479         if (nlsa != NULL) {
  480                 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  481                 if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
  482                         return (error);
  483                 linux_to_bsd_sigaction(&tmplsa, &tmpbsa);
  484                 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
  485                         return (error);
  486         }
  487         else
  488                 nbsa = NULL;
  489 
  490         SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
  491         SCARG(&sa, nsa) = nbsa;
  492         SCARG(&sa, osa) = obsa;
  493 
  494         /* Silently ignore unknown signals */
  495         if (SCARG(&sa, signum) == 0) {
  496                 if (obsa != NULL) {
  497                         obsa->sa_handler = SIG_IGN;
  498                         sigemptyset(&obsa->sa_mask);
  499                         obsa->sa_flags = 0;
  500                 }
  501         }
  502         else {
  503                 if ((error = sys_sigaction(p, &sa, retval)) != 0)
  504                         return (error);
  505         }
  506 
  507         if (olsa != NULL) {
  508                 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
  509                         return (error);
  510                 bsd_to_linux_sigaction(&tmpbsa, &tmplsa);
  511                 if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
  512                         return (error);
  513         }
  514 
  515         return (0);
  516 }
  517 
  518 /*
  519  * The Linux signal() system call. I think that the signal() in the C
  520  * library actually calls sigaction, so I doubt this one is ever used.
  521  * But hey, it can't hurt having it here. The same restrictions as for
  522  * sigaction() apply.
  523  */
  524 int
  525 linux_sys_signal(p, v, retval)
  526         register struct proc *p;
  527         void *v;
  528         register_t *retval;
  529 {
  530         struct linux_sys_signal_args /* {
  531                 syscallarg(int) sig;
  532                 syscallarg(linux_handler_t) handler;
  533         } */ *uap = v;
  534         caddr_t sg;
  535         struct sys_sigaction_args sa_args;
  536         struct sigaction *osa, *nsa, tmpsa;
  537         int error;
  538 
  539         if (SCARG(uap, sig) < 0 || SCARG(uap, sig) >= LINUX__NSIG)
  540                 return (EINVAL);
  541 
  542         sg = stackgap_init(p->p_emul);
  543         nsa = stackgap_alloc(&sg, sizeof *nsa);
  544         osa = stackgap_alloc(&sg, sizeof *osa);
  545 
  546         tmpsa.sa_handler = SCARG(uap, handler);
  547         tmpsa.sa_mask = (sigset_t) 0;
  548         tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
  549         if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
  550                 return (error);
  551 
  552         SCARG(&sa_args, signum) = linux_to_bsd_sig[SCARG(uap, sig)];
  553         SCARG(&sa_args, osa) = osa;
  554         SCARG(&sa_args, nsa) = nsa;
  555 
  556         /* Silently ignore unknown signals */
  557         if (SCARG(&sa_args, signum) != 0) {
  558                 if ((error = sys_sigaction(p, &sa_args, retval)))
  559                         return (error);
  560         }
  561 
  562         if ((error = copyin(osa, &tmpsa, sizeof *osa)))
  563                 return (error);
  564         retval[0] = (register_t) tmpsa.sa_handler;
  565 
  566         return (0);
  567 }
  568 
  569 /*
  570  * This is just a copy of the svr4 compat one. I feel so creative now.
  571  */
  572 int
  573 linux_sys_sigprocmask(p, v, retval)
  574         register struct proc *p;
  575         void *v;
  576         register_t *retval;
  577 {
  578         struct linux_sys_sigprocmask_args /* {
  579                 syscallarg(int) how;
  580                 syscallarg(linux_old_sigset_t *) set;
  581                 syscallarg(linux_old_sigset_t *) oset;
  582         } */ *uap = v;
  583         linux_old_sigset_t ss;
  584         sigset_t bs;
  585         int error = 0;
  586 
  587         *retval = 0;
  588 
  589         if (SCARG(uap, oset) != NULL) {
  590                 /* Fix the return value first if needed */
  591                 bsd_to_linux_old_sigset(&p->p_sigmask, &ss);
  592                 if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
  593                         return (error);
  594         }
  595 
  596         if (SCARG(uap, set) == NULL)
  597                 /* Just examine */
  598                 return (0);
  599 
  600         if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
  601                 return (error);
  602 
  603         linux_old_to_bsd_sigset(&ss, &bs);
  604 
  605         (void) splhigh();
  606 
  607         switch (SCARG(uap, how)) {
  608         case LINUX_SIG_BLOCK:
  609                 p->p_sigmask |= bs & ~sigcantmask;
  610                 break;
  611 
  612         case LINUX_SIG_UNBLOCK:
  613                 p->p_sigmask &= ~bs;
  614                 break;
  615 
  616         case LINUX_SIG_SETMASK:
  617                 p->p_sigmask = bs & ~sigcantmask;
  618                 break;
  619 
  620         default:
  621                 error = EINVAL;
  622                 break;
  623         }
  624 
  625         (void) spl0();
  626 
  627         return (error);
  628 }
  629 
  630 int
  631 linux_sys_rt_sigprocmask(p, v, retval)
  632         register struct proc *p;
  633         void *v;
  634         register_t *retval;
  635 {
  636         struct linux_sys_rt_sigprocmask_args /* {
  637                 syscallarg(int) how;
  638                 syscallarg(const linux_sigset_t *) set;
  639                 syscallarg(linux_sigset_t *) oset;
  640                 syscallarg(size_t) sigsetsize;
  641         } */ *uap = v;
  642         linux_sigset_t ls;
  643         sigset_t bs;
  644         int error = 0;
  645 
  646         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  647                 return (EINVAL);
  648 
  649         *retval = 0;
  650 
  651         if (SCARG(uap, oset) != NULL) {
  652                 /* Fix the return value first if needed */
  653                 bsd_to_linux_sigset(&p->p_sigmask, &ls);
  654                 if ((error = copyout(&ls, SCARG(uap, oset), sizeof(ls))) != 0)
  655                         return (error);
  656         }
  657 
  658         if (SCARG(uap, set) == NULL)
  659                 /* Just examine */
  660                 return (0);
  661 
  662         if ((error = copyin(SCARG(uap, set), &ls, sizeof(ls))) != 0)
  663                 return (error);
  664 
  665         linux_to_bsd_sigset(&ls, &bs);
  666 
  667         (void) splhigh();
  668 
  669         switch (SCARG(uap, how)) {
  670         case LINUX_SIG_BLOCK:
  671                 p->p_sigmask |= bs & ~sigcantmask;
  672                 break;
  673 
  674         case LINUX_SIG_UNBLOCK:
  675                 p->p_sigmask &= ~bs;
  676                 break;
  677 
  678         case LINUX_SIG_SETMASK:
  679                 p->p_sigmask = bs & ~sigcantmask;
  680                 break;
  681 
  682         default:
  683                 error = EINVAL;
  684                 break;
  685         }
  686 
  687         (void) spl0();
  688 
  689         return (error);
  690 }
  691 
  692 /*
  693  * The functions below really make no distinction between an int
  694  * and [linux_]sigset_t. This is ok for now, but it might break
  695  * sometime. Then again, sigset_t is trusted to be an int everywhere
  696  * else in the kernel too.
  697  */
  698 /* ARGSUSED */
  699 int
  700 linux_sys_siggetmask(p, v, retval)
  701         register struct proc *p;
  702         void *v;
  703         register_t *retval;
  704 {
  705 
  706         bsd_to_linux_old_sigset(&p->p_sigmask, (linux_old_sigset_t *)retval);
  707         return (0);
  708 }
  709 
  710 /*
  711  * The following three functions fiddle with a process' signal mask.
  712  * Convert the signal masks because of the different signal
  713  * values for Linux. The need for this is the reason why
  714  * they are here, and have not been mapped directly.
  715  */
  716 int
  717 linux_sys_sigsetmask(p, v, retval)
  718         register struct proc *p;
  719         void *v;
  720         register_t *retval;
  721 {
  722         struct linux_sys_sigsetmask_args /* {
  723                 syscallarg(linux_old_sigset_t) mask;
  724         } */ *uap = v;
  725         linux_old_sigset_t mask;
  726         sigset_t bsdsig;
  727 
  728         bsd_to_linux_old_sigset(&p->p_sigmask, (linux_old_sigset_t *)retval);
  729 
  730         mask = SCARG(uap, mask);
  731         bsd_to_linux_old_sigset(&bsdsig, &mask);
  732 
  733         splhigh();
  734         p->p_sigmask = bsdsig & ~sigcantmask;
  735         spl0();
  736 
  737         return (0);
  738 }
  739 
  740 int
  741 linux_sys_sigpending(p, v, retval)
  742         register struct proc *p;
  743         void *v;
  744         register_t *retval;
  745 {
  746         struct linux_sys_sigpending_args /* {
  747                 syscallarg(linux_old_sigset_t *) mask;
  748         } */ *uap = v;
  749         sigset_t bs;
  750         linux_old_sigset_t ls;
  751 
  752         bs = p->p_siglist & p->p_sigmask;
  753         bsd_to_linux_old_sigset(&bs, &ls);
  754 
  755         return (copyout(&ls, SCARG(uap, mask), sizeof ls));
  756 }
  757 
  758 int
  759 linux_sys_rt_sigpending(p, v, retval)
  760         register struct proc *p;
  761         void *v;
  762         register_t *retval;
  763 {
  764         struct linux_sys_rt_sigpending_args /* {
  765                 syscallarg(linux_sigset_t *) set;
  766                 syscallarg(size_t) sigsetsize;
  767         } */ *uap = v;
  768         sigset_t bs;
  769         linux_sigset_t ls;
  770 
  771         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  772                 return (EINVAL);
  773 
  774         bs = p->p_siglist & p->p_sigmask;
  775         bsd_to_linux_sigset(&bs, &ls);
  776 
  777         return (copyout(&ls, SCARG(uap, set), sizeof ls));
  778 }
  779 
  780 int
  781 linux_sys_sigsuspend(p, v, retval)
  782         register struct proc *p;
  783         void *v;
  784         register_t *retval;
  785 {
  786         struct linux_sys_sigsuspend_args /* {
  787                 syscallarg(caddr_t) restart;
  788                 syscallarg(int) oldmask;
  789                 syscallarg(int) mask;
  790         } */ *uap = v;
  791         struct sys_sigsuspend_args sa;
  792         linux_old_sigset_t mask = SCARG(uap, mask);
  793 
  794         linux_old_to_bsd_sigset(&mask, &SCARG(&sa, mask));
  795         return (sys_sigsuspend(p, &sa, retval));
  796 }
  797 
  798 int
  799 linux_sys_rt_sigsuspend(p, v, retval)
  800         register struct proc *p;
  801         void *v;
  802         register_t *retval;
  803 {
  804         struct linux_sys_rt_sigsuspend_args /* {
  805                 syscallarg(sigset_t *) unewset;
  806                 syscallarg(size_t) sigsetsize;
  807         } */ *uap = v;
  808         struct sys_sigsuspend_args sa;
  809         linux_sigset_t mask;
  810         int error;
  811 
  812         if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
  813                 return (EINVAL);
  814         
  815         error = copyin(SCARG(uap, unewset), &mask, sizeof mask);
  816         if (error)
  817                 return (error);
  818         
  819         linux_to_bsd_sigset(&mask, &SCARG(&sa, mask));
  820         return (sys_sigsuspend(p, &sa, retval));
  821 }
  822 
  823 /*
  824  * Linux' sigaltstack structure is just of a different order than BSD's
  825  * so just shuffle the fields around and call our version.
  826  */
  827 int
  828 linux_sys_sigaltstack(p, v, retval)
  829         register struct proc *p;
  830         void *v;        
  831         register_t *retval;
  832 {       
  833         struct linux_sys_sigaltstack_args /* {
  834                 syscallarg(const struct linux_sigaltstack *) nss;
  835                 syscallarg(struct linux_sigaltstack *) oss;
  836         } */ *uap = v;
  837         struct linux_sigaltstack linux_ss;
  838         struct sigaltstack *bsd_nss, *bsd_oss;
  839         struct sys_sigaltstack_args sa;
  840         int error;
  841         caddr_t sg;
  842 
  843         sg = stackgap_init(p->p_emul);
  844 
  845         if (SCARG(uap, nss) != NULL) {
  846                 bsd_nss = stackgap_alloc(&sg, sizeof *bsd_nss);
  847 
  848                 error = copyin(SCARG(uap, nss), &linux_ss, sizeof linux_ss);
  849                 if (error)
  850                         return (error);
  851 
  852                 bsd_nss->ss_sp = linux_ss.ss_sp;
  853                 bsd_nss->ss_size = linux_ss.ss_size;
  854                 bsd_nss->ss_flags = (linux_ss.ss_flags & LINUX_SS_DISABLE) ?
  855                     SS_DISABLE : 0;
  856 
  857                 SCARG(&sa, nss) = bsd_nss;
  858         } else
  859                 SCARG(&sa, nss) = NULL;
  860 
  861         if (SCARG(uap, oss) == NULL) {
  862                 SCARG(&sa, oss) = NULL;
  863                 return (sys_sigaltstack(p, &sa, retval));
  864         }
  865         SCARG(&sa, oss) = bsd_oss = stackgap_alloc(&sg, sizeof *bsd_oss);
  866 
  867         error = sys_sigaltstack(p, &sa, retval);
  868         if (error)
  869                 return (error);
  870 
  871         linux_ss.ss_sp = bsd_oss->ss_sp;
  872         linux_ss.ss_size = bsd_oss->ss_size;
  873         linux_ss.ss_flags = 0;
  874         if (bsd_oss->ss_flags & SS_ONSTACK)
  875                 linux_ss.ss_flags |= LINUX_SS_ONSTACK;
  876         if (bsd_oss->ss_flags & SS_DISABLE)
  877                 linux_ss.ss_flags |= LINUX_SS_DISABLE;
  878         return (copyout(&linux_ss, SCARG(uap, oss), sizeof linux_ss));
  879 }
  880 
  881 /*
  882  * The deprecated pause(2), which is really just an instance
  883  * of sigsuspend(2).
  884  */
  885 int
  886 linux_sys_pause(p, v, retval)
  887         register struct proc *p;
  888         void *v;        
  889         register_t *retval;
  890 {       
  891         struct sys_sigsuspend_args bsa;
  892 
  893         SCARG(&bsa, mask) = p->p_sigmask;
  894         return (sys_sigsuspend(p, &bsa, retval));
  895 }
  896 
  897 /*
  898  * Once more: only a signal conversion is needed.
  899  */
  900 int
  901 linux_sys_kill(p, v, retval)
  902         register struct proc *p;
  903         void *v;
  904         register_t *retval;
  905 {
  906         struct linux_sys_kill_args /* {
  907                 syscallarg(int) pid;
  908                 syscallarg(int) signum;
  909         } */ *uap = v;
  910         struct sys_kill_args ka;
  911 
  912         SCARG(&ka, pid) = SCARG(uap, pid);
  913         if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
  914                 return (EINVAL);
  915         SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
  916         return (sys_kill(p, &ka, retval));
  917 }

/* [<][>][^][v][top][bottom][index][help] */