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_ipc.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_ipc.c,v 1.37 2006/09/13 19:55:49 manu Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Frank van der Linden and Eric Haszlakiewicz.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: linux_ipc.c,v 1.37 2006/09/13 19:55:49 manu Exp $");
   41 
   42 #if defined(_KERNEL_OPT)
   43 #include "opt_sysv.h"
   44 #endif
   45 
   46 #include <sys/param.h>
   47 #include <sys/shm.h>
   48 #include <sys/sem.h>
   49 #include <sys/msg.h>
   50 #include <sys/proc.h>
   51 #include <sys/systm.h>
   52 
   53 #include <sys/mount.h>
   54 #include <sys/sa.h>
   55 #include <sys/syscallargs.h>
   56 
   57 #include <compat/linux/common/linux_types.h>
   58 #include <compat/linux/common/linux_signal.h>
   59 #include <compat/linux/common/linux_util.h>
   60 #include <compat/linux/common/linux_ipc.h>
   61 #include <compat/linux/common/linux_msg.h>
   62 #include <compat/linux/common/linux_shm.h>
   63 #include <compat/linux/common/linux_sem.h>
   64 
   65 #include <compat/linux/linux_syscallargs.h>
   66 #include <compat/linux/linux_syscall.h>
   67 
   68 #include <compat/linux/common/linux_ipccall.h>
   69 
   70 /*
   71  * Note: Not all linux architechtures have explicit versions
   72  *      of the SYSV* syscalls.  On the ones that don't
   73  *      we pretend that they are defined anyway.  *_args and
   74  *      prototypes are defined in individual headers;
   75  *      syscalls.master lists those syscalls as NOARGS.
   76  *
   77  *      The functions in multiarch are the ones that just need
   78  *      the arguments shuffled around and then use the
   79  *      normal NetBSD syscall.
   80  *
   81  * Function in multiarch:
   82  *      linux_sys_ipc           : linux_ipccall.c
   83  *      liunx_semop             : linux_ipccall.c
   84  *      linux_semget            : linux_ipccall.c
   85  *      linux_msgsnd            : linux_ipccall.c
   86  *      linux_msgrcv            : linux_ipccall.c
   87  *      linux_msgget            : linux_ipccall.c
   88  *      linux_shmdt             : linux_ipccall.c
   89  *      linux_shmget            : linux_ipccall.c
   90  */
   91 
   92 #if defined (SYSVSEM) || defined(SYSVSHM) || defined(SYSVMSG)
   93 /*
   94  * Convert between Linux and NetBSD ipc_perm structures. Only the
   95  * order of the fields is different.
   96  */
   97 void
   98 linux_to_bsd_ipc_perm(lpp, bpp)
   99         struct linux_ipc_perm *lpp;
  100         struct ipc_perm *bpp;
  101 {
  102 
  103         bpp->_key = lpp->l_key;
  104         bpp->uid = lpp->l_uid;
  105         bpp->gid = lpp->l_gid;
  106         bpp->cuid = lpp->l_cuid;
  107         bpp->cgid = lpp->l_cgid;
  108         bpp->mode = lpp->l_mode;
  109         bpp->_seq = lpp->l_seq;
  110 }
  111 
  112 void
  113 linux_to_bsd_ipc64_perm(lpp, bpp)
  114         struct linux_ipc64_perm *lpp;
  115         struct ipc_perm *bpp;
  116 {
  117         bpp->_key = lpp->l_key;
  118         bpp->uid = lpp->l_uid;
  119         bpp->gid = lpp->l_gid;
  120         bpp->cuid = lpp->l_cuid;
  121         bpp->cgid = lpp->l_cgid;
  122         bpp->mode = lpp->l_mode;
  123         bpp->_seq = lpp->l_seq;
  124 }
  125 
  126 void
  127 bsd_to_linux_ipc_perm(bpp, lpp)
  128         struct ipc_perm *bpp;
  129         struct linux_ipc_perm *lpp;
  130 {
  131 
  132         lpp->l_key = bpp->_key;
  133         lpp->l_uid = bpp->uid;
  134         lpp->l_gid = bpp->gid;
  135         lpp->l_cuid = bpp->cuid;
  136         lpp->l_cgid = bpp->cgid;
  137         lpp->l_mode = bpp->mode;
  138         lpp->l_seq = bpp->_seq;
  139 }
  140 
  141 void
  142 bsd_to_linux_ipc64_perm(bpp, lpp)
  143         struct ipc_perm *bpp;
  144         struct linux_ipc64_perm *lpp;
  145 {
  146         lpp->l_key = bpp->_key;
  147         lpp->l_uid = bpp->uid;
  148         lpp->l_gid = bpp->gid;
  149         lpp->l_cuid = bpp->cuid;
  150         lpp->l_cgid = bpp->cgid;
  151         lpp->l_mode = bpp->mode;
  152         lpp->l_seq = bpp->_seq;
  153 }
  154 
  155 #endif
  156 
  157 #ifdef SYSVSEM
  158 /*
  159  * Semaphore operations. Most constants and structures are the same on
  160  * both systems. Only semctl() needs some extra work.
  161  */
  162 
  163 /*
  164  * Convert between Linux and NetBSD semid_ds structures.
  165  */
  166 void
  167 bsd_to_linux_semid_ds(bs, ls)
  168         struct semid_ds *bs;
  169         struct linux_semid_ds *ls;
  170 {
  171 
  172         bsd_to_linux_ipc_perm(&bs->sem_perm, &ls->l_sem_perm);
  173         ls->l_sem_otime = bs->sem_otime;
  174         ls->l_sem_ctime = bs->sem_ctime;
  175         ls->l_sem_nsems = bs->sem_nsems;
  176         ls->l_sem_base = bs->_sem_base;
  177 }
  178 
  179 void
  180 linux_to_bsd_semid_ds(ls, bs)
  181         struct linux_semid_ds *ls;
  182         struct semid_ds *bs;
  183 {
  184 
  185         linux_to_bsd_ipc_perm(&ls->l_sem_perm, &bs->sem_perm);
  186         bs->sem_otime = ls->l_sem_otime;
  187         bs->sem_ctime = ls->l_sem_ctime;
  188         bs->sem_nsems = ls->l_sem_nsems;
  189         bs->_sem_base = ls->l_sem_base;
  190 }
  191 
  192 /*
  193  * Most of this can be handled by directly passing the arguments on; we
  194  * just need to frob the `cmd' and convert the semid_ds and semun.
  195  */
  196 int
  197 linux_sys_semctl(l, v, retval)
  198         struct lwp *l;
  199         void *v;
  200         register_t *retval;
  201 {
  202         struct linux_sys_semctl_args /* {
  203                 syscallarg(int) semid;
  204                 syscallarg(int) semnum;
  205                 syscallarg(int) cmd;
  206                 syscallarg(union linux_semun) arg;
  207         } */ *uap = v;
  208         struct semid_ds sembuf;
  209         struct linux_semid_ds lsembuf;
  210         union __semun semun;
  211         int cmd, error;
  212         void *pass_arg = NULL;
  213 
  214         cmd = SCARG(uap, cmd);
  215 
  216         switch (cmd) {
  217         case LINUX_IPC_SET:
  218                 pass_arg = &sembuf;
  219                 cmd = IPC_SET;
  220                 break;
  221 
  222         case LINUX_IPC_STAT:
  223                 pass_arg = &sembuf;
  224                 cmd = IPC_STAT;
  225                 break;
  226 
  227         case LINUX_IPC_RMID:
  228                 cmd = IPC_RMID;
  229                 break;
  230 
  231         case LINUX_GETVAL:
  232                 cmd = GETVAL;
  233                 break;
  234 
  235         case LINUX_GETPID:
  236                 cmd = GETPID;
  237                 break;
  238 
  239         case LINUX_GETNCNT:
  240                 cmd = GETNCNT;
  241                 break;
  242 
  243         case LINUX_GETZCNT:
  244                 cmd = GETZCNT;
  245                 break;
  246 
  247         case LINUX_GETALL:
  248                 pass_arg = &semun;
  249                 semun.array = SCARG(uap, arg).l_array;
  250                 cmd = GETALL;
  251                 break;
  252 
  253         case LINUX_SETVAL:
  254                 pass_arg = &semun;
  255                 semun.val = SCARG(uap, arg).l_val;
  256                 cmd = SETVAL;
  257                 break;
  258 
  259         case LINUX_SETALL:
  260                 pass_arg = &semun;
  261                 semun.array = SCARG(uap, arg).l_array;
  262                 cmd = SETALL;
  263                 break;
  264 
  265         default:
  266                 return (EINVAL);
  267         }
  268 
  269         if (cmd == IPC_SET) {
  270                 error = copyin(SCARG(uap, arg).l_buf, &lsembuf,
  271                     sizeof(lsembuf));
  272                 if (error)
  273                         return (error);
  274                 linux_to_bsd_semid_ds(&lsembuf, &sembuf);
  275         }
  276 
  277         error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
  278             pass_arg, retval);
  279 
  280         if (error == 0 && cmd == IPC_STAT) {
  281                 bsd_to_linux_semid_ds(&sembuf, &lsembuf);
  282                 error = copyout(&lsembuf, SCARG(uap, arg).l_buf,
  283                     sizeof(lsembuf));
  284         }
  285 
  286         return (error);
  287 }
  288 #endif /* SYSVSEM */
  289 
  290 #ifdef SYSVMSG
  291 
  292 void
  293 linux_to_bsd_msqid_ds(lmp, bmp)
  294         struct linux_msqid_ds *lmp;
  295         struct msqid_ds *bmp;
  296 {
  297 
  298         linux_to_bsd_ipc_perm(&lmp->l_msg_perm, &bmp->msg_perm);
  299         bmp->_msg_first = lmp->l_msg_first;
  300         bmp->_msg_last = lmp->l_msg_last;
  301         bmp->_msg_cbytes = lmp->l_msg_cbytes;
  302         bmp->msg_qnum = lmp->l_msg_qnum;
  303         bmp->msg_qbytes = lmp->l_msg_qbytes;
  304         bmp->msg_lspid = lmp->l_msg_lspid;
  305         bmp->msg_lrpid = lmp->l_msg_lrpid;
  306         bmp->msg_stime = lmp->l_msg_stime;
  307         bmp->msg_rtime = lmp->l_msg_rtime;
  308         bmp->msg_ctime = lmp->l_msg_ctime;
  309 }
  310 
  311 void
  312 bsd_to_linux_msqid_ds(bmp, lmp)
  313         struct msqid_ds *bmp;
  314         struct linux_msqid_ds *lmp;
  315 {
  316 
  317         bsd_to_linux_ipc_perm(&bmp->msg_perm, &lmp->l_msg_perm);
  318         lmp->l_msg_first = bmp->_msg_first;
  319         lmp->l_msg_last = bmp->_msg_last;
  320         lmp->l_msg_cbytes = bmp->_msg_cbytes;
  321         lmp->l_msg_qnum = bmp->msg_qnum;
  322         lmp->l_msg_qbytes = bmp->msg_qbytes;
  323         lmp->l_msg_lspid = bmp->msg_lspid;
  324         lmp->l_msg_lrpid = bmp->msg_lrpid;
  325         lmp->l_msg_stime = bmp->msg_stime;
  326         lmp->l_msg_rtime = bmp->msg_rtime;
  327         lmp->l_msg_ctime = bmp->msg_ctime;
  328 }
  329 
  330 int
  331 linux_sys_msgctl(l, v, retval)
  332         struct lwp *l;
  333         void *v;
  334         register_t *retval;
  335 {
  336         struct linux_sys_msgctl_args /* {
  337                 syscallarg(int) msqid;
  338                 syscallarg(int) cmd;
  339                 syscallarg(struct linux_msqid_ds *) buf;
  340         } */ *uap = v;
  341         struct proc *p = l->l_proc;
  342         caddr_t sg;
  343         struct sys___msgctl13_args nua;
  344         struct msqid_ds *bmp, bm;
  345         struct linux_msqid_ds lm;
  346         int error;
  347 
  348         SCARG(&nua, msqid) = SCARG(uap, msqid);
  349         switch (SCARG(uap, cmd)) {
  350         case LINUX_IPC_STAT:
  351                 sg = stackgap_init(p, 0);
  352                 bmp = stackgap_alloc(p, &sg, sizeof (struct msqid_ds));
  353                 SCARG(&nua, cmd) = IPC_STAT;
  354                 SCARG(&nua, buf) = bmp;
  355                 if ((error = sys___msgctl13(l, &nua, retval)))
  356                         return error;
  357                 if ((error = copyin(bmp, &bm, sizeof bm)))
  358                         return error;
  359                 bsd_to_linux_msqid_ds(&bm, &lm);
  360                 return copyout(&lm, SCARG(uap, buf), sizeof lm);
  361         case LINUX_IPC_SET:
  362                 if ((error = copyin(SCARG(uap, buf), &lm, sizeof lm)))
  363                         return error;
  364                 linux_to_bsd_msqid_ds(&lm, &bm);
  365                 sg = stackgap_init(p, 0);
  366                 bmp = stackgap_alloc(p, &sg, sizeof bm);
  367                 if ((error = copyout(&bm, bmp, sizeof bm)))
  368                         return error;
  369                 SCARG(&nua, cmd) = IPC_SET;
  370                 SCARG(&nua, buf) = bmp;
  371                 break;
  372         case LINUX_IPC_RMID:
  373                 SCARG(&nua, cmd) = IPC_RMID;
  374                 SCARG(&nua, buf) = NULL;
  375                 break;
  376         default:
  377                 return EINVAL;
  378         }
  379         return sys___msgctl13(l, &nua, retval);
  380 }
  381 #endif /* SYSVMSG */
  382 
  383 #ifdef SYSVSHM
  384 /*
  385  * shmget(2). Just make sure the Linux-compatible shmat() semantics
  386  * is enabled for the segment, so that shmat() succeeds even when
  387  * the segment would be removed.
  388  */
  389 int
  390 linux_sys_shmget(l, v, retval)
  391         struct lwp *l;
  392         void *v;
  393         register_t *retval;
  394 {
  395         struct sys_shmget_args /* {
  396                 syscallarg(key_t) key;
  397                 syscallarg(size_t) size;
  398                 syscallarg(int) shmflg;
  399         } */ *uap = v;
  400 
  401         SCARG(uap, shmflg) |= _SHM_RMLINGER;
  402         return sys_shmget(l, uap, retval);
  403 }
  404 
  405 /*
  406  * shmat(2). Very straightforward, except that Linux passes a pointer
  407  * in which the return value is to be passed. This is subsequently
  408  * handled by libc, apparently.
  409  */
  410 #ifndef __amd64__
  411 int
  412 linux_sys_shmat(l, v, retval)
  413         struct lwp *l;
  414         void *v;
  415         register_t *retval;
  416 {
  417         struct linux_sys_shmat_args /* {
  418                 syscallarg(int) shmid;
  419                 syscallarg(void *) shmaddr;
  420                 syscallarg(int) shmflg;
  421                 syscallarg(u_long *) raddr;
  422         } */ *uap = v;
  423         int error;
  424 
  425         if ((error = sys_shmat(l, uap, retval)))
  426                 return error;
  427 
  428 #ifndef __amd64__
  429         if ((error = copyout(&retval[0], (caddr_t) SCARG(uap, raddr),
  430              sizeof retval[0])))
  431                 return error;
  432 
  433         retval[0] = 0;
  434 #endif
  435         return 0;
  436 }
  437 #endif /* __amd64__ */
  438 
  439 /*
  440  * Convert between Linux and NetBSD shmid_ds structures.
  441  * The order of the fields is once again the difference, and
  442  * we also need a place to store the internal data pointer
  443  * in, which is unfortunately stored in this structure.
  444  *
  445  * We abuse a Linux internal field for that.
  446  */
  447 void
  448 linux_to_bsd_shmid_ds(lsp, bsp)
  449         struct linux_shmid_ds *lsp;
  450         struct shmid_ds *bsp;
  451 {
  452 
  453         linux_to_bsd_ipc_perm(&lsp->l_shm_perm, &bsp->shm_perm);
  454         bsp->shm_segsz = lsp->l_shm_segsz;
  455         bsp->shm_lpid = lsp->l_shm_lpid;
  456         bsp->shm_cpid = lsp->l_shm_cpid;
  457         bsp->shm_nattch = lsp->l_shm_nattch;
  458         bsp->shm_atime = lsp->l_shm_atime;
  459         bsp->shm_dtime = lsp->l_shm_dtime;
  460         bsp->shm_ctime = lsp->l_shm_ctime;
  461         bsp->_shm_internal = lsp->l_private2;   /* XXX Oh well. */
  462 }
  463 
  464 void
  465 linux_to_bsd_shmid64_ds(lsp, bsp)
  466         struct linux_shmid64_ds *lsp;
  467         struct shmid_ds *bsp;
  468 {
  469 
  470         linux_to_bsd_ipc64_perm(&lsp->l_shm_perm, &bsp->shm_perm);
  471         bsp->shm_segsz = lsp->l_shm_segsz;
  472         bsp->shm_lpid = lsp->l_shm_lpid;
  473         bsp->shm_cpid = lsp->l_shm_cpid;
  474         bsp->shm_nattch = lsp->l_shm_nattch;
  475         bsp->shm_atime = lsp->l_shm_atime;
  476         bsp->shm_dtime = lsp->l_shm_dtime;
  477         bsp->shm_ctime = lsp->l_shm_ctime;
  478         bsp->_shm_internal = (void*)lsp->l___unused5;   /* XXX Oh well. */
  479 }
  480 
  481 void
  482 bsd_to_linux_shmid_ds(bsp, lsp)
  483         struct shmid_ds *bsp;
  484         struct linux_shmid_ds *lsp;
  485 {
  486 
  487         bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->l_shm_perm);
  488         lsp->l_shm_segsz = bsp->shm_segsz;
  489         lsp->l_shm_lpid = bsp->shm_lpid;
  490         lsp->l_shm_cpid = bsp->shm_cpid;
  491         lsp->l_shm_nattch = bsp->shm_nattch;
  492         lsp->l_shm_atime = bsp->shm_atime;
  493         lsp->l_shm_dtime = bsp->shm_dtime;
  494         lsp->l_shm_ctime = bsp->shm_ctime;
  495         lsp->l_private2 = bsp->_shm_internal;   /* XXX */
  496 }
  497 
  498 void
  499 bsd_to_linux_shmid64_ds(bsp, lsp)
  500         struct shmid_ds *bsp;
  501         struct linux_shmid64_ds *lsp;
  502 {
  503         bsd_to_linux_ipc64_perm(&bsp->shm_perm, &lsp->l_shm_perm);
  504         lsp->l_shm_segsz = bsp->shm_segsz;
  505         lsp->l_shm_lpid = bsp->shm_lpid;
  506         lsp->l_shm_cpid = bsp->shm_cpid;
  507         lsp->l_shm_nattch = bsp->shm_nattch;
  508         lsp->l_shm_atime = bsp->shm_atime;
  509         lsp->l_shm_dtime = bsp->shm_dtime;
  510         lsp->l_shm_ctime = bsp->shm_ctime;
  511         lsp->l___unused5 = (u_long)bsp->_shm_internal;  /* XXX */
  512 }
  513 
  514 /*
  515  * shmctl.SHM_LOCK and SHM_UNLOCK are passed on, but currently not implemented
  516  * by NetBSD itself.
  517  *
  518  * The usual structure conversion and massaging is done.
  519  */
  520 int
  521 linux_sys_shmctl(l, v, retval)
  522         struct lwp *l;
  523         void *v;
  524         register_t *retval;
  525 {
  526         struct linux_sys_shmctl_args /* {
  527                 syscallarg(int) shmid;
  528                 syscallarg(int) cmd;
  529                 syscallarg(struct linux_shmid_ds *) buf;
  530         } */ *uap = v;
  531         struct proc *p = l->l_proc;
  532         caddr_t sg;
  533         struct sys___shmctl13_args nua;
  534         struct shmid_ds *bsp, bs;
  535         struct linux_shmid_ds ls;
  536         struct linux_shmid64_ds ls64;
  537         struct linux_shminfo64 lsi64;
  538         struct linux_shm_info lsi;
  539         int error, i, cmd;
  540 
  541         SCARG(&nua, shmid) = SCARG(uap, shmid);
  542         cmd = SCARG(uap, cmd);
  543         switch (cmd) {
  544         case LINUX_IPC_STAT:
  545         case LINUX_SHM_STAT:
  546                 sg = stackgap_init(p, 0);
  547                 bsp = stackgap_alloc(p, &sg, sizeof(struct shmid_ds));
  548                 SCARG(&nua, cmd) = IPC_STAT;
  549                 SCARG(&nua, buf) = bsp;
  550                 if ((error = sys___shmctl13(l, &nua, retval)))
  551                         return error;
  552                 if ((error = copyin(SCARG(&nua, buf), &bs, sizeof bs)))
  553                         return error;
  554                 bsd_to_linux_shmid_ds(&bs, &ls);
  555                 if (cmd == LINUX_SHM_STAT)
  556                         retval[0] = IXSEQ_TO_IPCID(bs.shm_perm._key,
  557                             bs.shm_perm);
  558                 return copyout(&ls, SCARG(uap, buf), sizeof ls);
  559 
  560         case LINUX_IPC_STAT|LINUX_IPC_64:
  561         case LINUX_SHM_STAT|LINUX_IPC_64:
  562                 sg = stackgap_init(p,0);
  563                 bsp = stackgap_alloc(p, &sg, sizeof(struct linux_shmid64_ds));
  564                 SCARG(&nua, cmd) = IPC_STAT;
  565                 SCARG(&nua, buf) = bsp;
  566                 if ((error = sys___shmctl13(l, &nua, retval)))
  567                         return error;
  568                 if ((error = copyin(SCARG(&nua, buf), &bs, sizeof bs)))
  569                         return error;
  570                 bsd_to_linux_shmid64_ds(&bs, &ls64);
  571                 if (cmd == (LINUX_SHM_STAT|LINUX_IPC_64)) {
  572                         retval[0] = IXSEQ_TO_IPCID(bs.shm_perm._key,
  573                                                    bs.shm_perm);
  574                 }
  575                 return copyout(&ls64, SCARG(uap, buf), sizeof ls64);
  576 
  577         case LINUX_IPC_SET:
  578                 if ((error = copyin(SCARG(uap, buf), &ls, sizeof ls)))
  579                         return error;
  580                 linux_to_bsd_shmid_ds(&ls, &bs);
  581                 sg = stackgap_init(p, 0);
  582                 bsp = stackgap_alloc(p, &sg, sizeof bs);
  583                 if ((error = copyout(&bs, bsp, sizeof bs)))
  584                         return error;
  585                 SCARG(&nua, cmd) = IPC_SET;
  586                 SCARG(&nua, buf) = bsp;
  587                 break;
  588 
  589         case LINUX_IPC_RMID:
  590                 SCARG(&nua, cmd) = IPC_RMID;
  591                 SCARG(&nua, buf) = NULL;
  592                 break;
  593 
  594         case LINUX_SHM_LOCK:
  595                 SCARG(&nua, cmd) = SHM_LOCK;
  596                 SCARG(&nua, buf) = NULL;
  597                 break;
  598 
  599         case LINUX_SHM_UNLOCK:
  600                 SCARG(&nua, cmd) = SHM_UNLOCK;
  601                 SCARG(&nua, buf) = NULL;
  602                 break;
  603 
  604         case LINUX_IPC_INFO:
  605                 memset(&lsi64, 0, sizeof lsi64);
  606                 lsi64.l_shmmax = shminfo.shmmax;
  607                 lsi64.l_shmmin = shminfo.shmmin;
  608                 lsi64.l_shmmni = shminfo.shmmni;
  609                 lsi64.l_shmseg = shminfo.shmseg;
  610                 lsi64.l_shmall = shminfo.shmall;
  611                 return copyout(&lsi64, SCARG(uap, buf), sizeof lsi64);
  612 
  613         case LINUX_SHM_INFO:
  614                 (void)memset(&lsi, 0, sizeof lsi);
  615                 lsi.l_used_ids = shm_nused;
  616                 for (i = 0; i < shminfo.shmmni; i++)
  617                         if (shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED)
  618                                 lsi.l_shm_tot += shmsegs[i].shm_segsz;
  619                 lsi.l_shm_rss = 0;
  620                 lsi.l_shm_swp = 0;
  621                 lsi.l_swap_attempts = 0;
  622                 lsi.l_swap_successes = 0;
  623                 return copyout(&lsi, SCARG(uap, buf), sizeof lsi);
  624 
  625         default:
  626 #ifdef DEBUG
  627                 printf("linux_sys_shmctl cmd %d\n", SCARG(uap, cmd));
  628 #endif
  629                 return EINVAL;
  630         }
  631         return sys___shmctl13(l, &nua, retval);
  632 }
  633 #endif /* SYSVSHM */

Cache object: c5824db76ddaba3c06a8c53c8a40e17c


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