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_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 /*-
    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_ipc.c,v 1.17.2.3 2001/11/05 19:08:22 marcel Exp $
   29  * $DragonFly: src/sys/emulation/linux/linux_ipc.c,v 1.8 2006/06/05 07:26:09 dillon Exp $
   30  */
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/sysproto.h>
   35 #include <sys/proc.h>
   36 #include <sys/msg.h>
   37 #include <sys/sem.h>
   38 #include <sys/shm.h>
   39 
   40 #include <arch_linux/linux.h>
   41 #include <machine/limits.h>
   42 #include <arch_linux/linux_proto.h>
   43 #include "linux_ipc.h"
   44 #include "linux_util.h"
   45 
   46 
   47 static void
   48 bsd_to_linux_shminfo( struct shminfo *bpp, struct l_shminfo *lpp)
   49 {
   50         lpp->shmmax = bpp->shmmax;
   51         lpp->shmmin = bpp->shmmin;
   52         lpp->shmmni = bpp->shmmni;
   53         lpp->shmseg = bpp->shmseg;
   54         lpp->shmall = bpp->shmall;
   55 }
   56 
   57 #if 0
   58 static void
   59 bsd_to_linux_shm_info( struct shm_info *bpp, struct l_shm_info *lpp)
   60 {
   61         lpp->used_ids = bpp->used_ids ;
   62         lpp->shm_tot = bpp->shm_tot ;
   63         lpp->shm_rss = bpp->shm_rss ;
   64         lpp->shm_swp = bpp->shm_swp ;
   65         lpp->swap_attempts = bpp->swap_attempts ;
   66         lpp->swap_successes = bpp->swap_successes ;
   67 }
   68 #endif
   69 
   70 /*
   71  * MPSAFE
   72  */
   73 static void
   74 linux_to_bsd_ipc_perm(struct l_ipc_perm *lpp, struct ipc_perm *bpp)
   75 {
   76     bpp->key = lpp->key;
   77     bpp->uid = lpp->uid;
   78     bpp->gid = lpp->gid;
   79     bpp->cuid = lpp->cuid;
   80     bpp->cgid = lpp->cgid;
   81     bpp->mode = lpp->mode;
   82     bpp->seq = lpp->seq;
   83 }
   84 
   85 /*
   86  * MPSAFE
   87  */
   88 static void
   89 bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct l_ipc_perm *lpp)
   90 {
   91     lpp->key = bpp->key;
   92     lpp->uid = bpp->uid;
   93     lpp->gid = bpp->gid;
   94     lpp->cuid = bpp->cuid;
   95     lpp->cgid = bpp->cgid;
   96     lpp->mode = bpp->mode;
   97     lpp->seq = bpp->seq;
   98 }
   99 
  100 /*
  101  * MPSAFE
  102  */
  103 static void
  104 linux_to_bsd_semid_ds(struct l_semid_ds *lsp, struct semid_ds *bsp)
  105 {
  106     linux_to_bsd_ipc_perm(&lsp->sem_perm, &bsp->sem_perm);
  107     bsp->sem_otime = lsp->sem_otime;
  108     bsp->sem_ctime = lsp->sem_ctime;
  109     bsp->sem_nsems = lsp->sem_nsems;
  110     bsp->sem_base = lsp->sem_base;
  111 }
  112 
  113 /*
  114  * MPSAFE
  115  */
  116 static void
  117 bsd_to_linux_semid_ds(struct semid_ds *bsp, struct l_semid_ds *lsp)
  118 {
  119         bsd_to_linux_ipc_perm(&bsp->sem_perm, &lsp->sem_perm);
  120         lsp->sem_otime = bsp->sem_otime;
  121         lsp->sem_ctime = bsp->sem_ctime;
  122         lsp->sem_nsems = bsp->sem_nsems;
  123         lsp->sem_base = bsp->sem_base;
  124 }
  125 
  126 /*
  127  * MPSAFE
  128  */
  129 static void
  130 linux_to_bsd_shmid_ds(struct l_shmid_ds *lsp, struct shmid_ds *bsp)
  131 {
  132     linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
  133     bsp->shm_segsz = lsp->shm_segsz;
  134     bsp->shm_lpid = lsp->shm_lpid;
  135     bsp->shm_cpid = lsp->shm_cpid;
  136     bsp->shm_nattch = lsp->shm_nattch;
  137     bsp->shm_atime = lsp->shm_atime;
  138     bsp->shm_dtime = lsp->shm_dtime;
  139     bsp->shm_ctime = lsp->shm_ctime;
  140 }
  141 
  142 /*
  143  * MPSAFE
  144  */
  145 static void
  146 bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp)
  147 {
  148     bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
  149     if (bsp->shm_segsz > INT_MAX)
  150             lsp->shm_segsz = INT_MAX;
  151     else
  152             lsp->shm_segsz = bsp->shm_segsz;
  153     lsp->shm_lpid = bsp->shm_lpid;
  154     lsp->shm_cpid = bsp->shm_cpid;
  155     lsp->shm_nattch = bsp->shm_nattch;
  156     lsp->shm_atime = bsp->shm_atime;
  157     lsp->shm_dtime = bsp->shm_dtime;
  158     lsp->shm_ctime = bsp->shm_ctime;
  159     lsp->private3 = 0;
  160 }
  161 
  162 static void
  163 linux_to_bsd_msqid_ds(struct l_msqid_ds *lsp, struct msqid_ds *bsp)
  164 {
  165     linux_to_bsd_ipc_perm(&lsp->msg_perm, &bsp->msg_perm);
  166     bsp->msg_cbytes = lsp->msg_cbytes;
  167     bsp->msg_qnum = lsp->msg_qnum;
  168     bsp->msg_qbytes = lsp->msg_qbytes;
  169     bsp->msg_lspid = lsp->msg_lspid;
  170     bsp->msg_lrpid = lsp->msg_lrpid;
  171     bsp->msg_stime = lsp->msg_stime;
  172     bsp->msg_rtime = lsp->msg_rtime;
  173     bsp->msg_ctime = lsp->msg_ctime;
  174 }
  175 
  176 static void
  177 bsd_to_linux_msqid_ds(struct msqid_ds *bsp, struct l_msqid_ds *lsp)
  178 {
  179     bsd_to_linux_ipc_perm(&bsp->msg_perm, &lsp->msg_perm);
  180     lsp->msg_cbytes = bsp->msg_cbytes;
  181     lsp->msg_qnum = bsp->msg_qnum;
  182     lsp->msg_qbytes = bsp->msg_qbytes;
  183     lsp->msg_lspid = bsp->msg_lspid;
  184     lsp->msg_lrpid = bsp->msg_lrpid;
  185     lsp->msg_stime = bsp->msg_stime;
  186     lsp->msg_rtime = bsp->msg_rtime;
  187     lsp->msg_ctime = bsp->msg_ctime;
  188 }
  189 
  190 static void
  191 linux_ipc_perm_to_ipc64_perm(struct l_ipc_perm *in, struct l_ipc64_perm *out)
  192 {
  193 
  194         /* XXX: do we really need to do something here? */
  195         out->key = in->key;
  196         out->uid = in->uid;
  197         out->gid = in->gid;
  198         out->cuid = in->cuid;
  199         out->cgid = in->cgid;
  200         out->mode = in->mode;
  201         out->seq = in->seq;
  202 }
  203 
  204 static int
  205 linux_msqid_pullup(l_int ver, struct l_msqid_ds *linux_msqid, caddr_t uaddr)
  206 {
  207         struct l_msqid64_ds linux_msqid64;
  208         int error;
  209 
  210         if (ver == LINUX_IPC_64) {
  211                 error = copyin(uaddr, &linux_msqid64, sizeof(linux_msqid64));
  212                 if (error != 0)
  213                         return (error);
  214 
  215                 bzero(linux_msqid, sizeof(*linux_msqid));
  216 
  217                 linux_msqid->msg_perm.uid = linux_msqid64.msg_perm.uid;
  218                 linux_msqid->msg_perm.gid = linux_msqid64.msg_perm.gid;
  219                 linux_msqid->msg_perm.mode = linux_msqid64.msg_perm.mode;
  220 
  221                 if (linux_msqid64.msg_qbytes > USHRT_MAX)
  222                         linux_msqid->msg_lqbytes = linux_msqid64.msg_qbytes;
  223                 else
  224                         linux_msqid->msg_qbytes = linux_msqid64.msg_qbytes;
  225         } else {
  226                 error = copyin(uaddr, linux_msqid, sizeof(*linux_msqid));
  227         }
  228         return (error);
  229 }
  230 
  231 static int
  232 linux_msqid_pushdown(l_int ver, struct l_msqid_ds *linux_msqid, caddr_t uaddr)
  233 {
  234         struct l_msqid64_ds linux_msqid64;
  235 
  236         if (ver == LINUX_IPC_64) {
  237                 bzero(&linux_msqid64, sizeof(linux_msqid64));
  238 
  239                 linux_ipc_perm_to_ipc64_perm(&linux_msqid->msg_perm,
  240                     &linux_msqid64.msg_perm);
  241 
  242                 linux_msqid64.msg_stime = linux_msqid->msg_stime;
  243                 linux_msqid64.msg_rtime = linux_msqid->msg_rtime;
  244                 linux_msqid64.msg_ctime = linux_msqid->msg_ctime;
  245 
  246                 if (linux_msqid->msg_cbytes == 0)
  247                         linux_msqid64.msg_cbytes = linux_msqid->msg_lcbytes;
  248                 else
  249                         linux_msqid64.msg_cbytes = linux_msqid->msg_cbytes;
  250 
  251                 linux_msqid64.msg_qnum = linux_msqid->msg_qnum;
  252 
  253                 if (linux_msqid->msg_qbytes == 0)
  254                         linux_msqid64.msg_qbytes = linux_msqid->msg_lqbytes;
  255                 else
  256                         linux_msqid64.msg_qbytes = linux_msqid->msg_qbytes;
  257 
  258                 linux_msqid64.msg_lspid = linux_msqid->msg_lspid;
  259                 linux_msqid64.msg_lrpid = linux_msqid->msg_lrpid;
  260 
  261                 return (copyout(&linux_msqid64, uaddr, sizeof(linux_msqid64)));
  262         } else {
  263                 return (copyout(linux_msqid, uaddr, sizeof(*linux_msqid)));
  264         }
  265 }
  266 
  267 static int
  268 linux_semid_pullup(l_int ver, struct l_semid_ds *linux_semid, caddr_t uaddr)
  269 {
  270         struct l_semid64_ds linux_semid64;
  271         int error;
  272 
  273         if (ver == LINUX_IPC_64) {
  274                 error = copyin(uaddr, &linux_semid64, sizeof(linux_semid64));
  275                 if (error != 0)
  276                         return (error);
  277 
  278                 bzero(linux_semid, sizeof(*linux_semid));
  279 
  280                 linux_semid->sem_perm.uid = linux_semid64.sem_perm.uid;
  281                 linux_semid->sem_perm.gid = linux_semid64.sem_perm.gid;
  282                 linux_semid->sem_perm.mode = linux_semid64.sem_perm.mode;
  283         } else {
  284                 error = copyin(uaddr, linux_semid, sizeof(*linux_semid));
  285         }
  286         return (error);
  287 }
  288 
  289 static int
  290 linux_semid_pushdown(l_int ver, struct l_semid_ds *linux_semid, caddr_t uaddr)
  291 {
  292         struct l_semid64_ds linux_semid64;
  293 
  294         if (ver == LINUX_IPC_64) {
  295                 bzero(&linux_semid64, sizeof(linux_semid64));
  296 
  297                 linux_ipc_perm_to_ipc64_perm(&linux_semid->sem_perm,
  298                     &linux_semid64.sem_perm);
  299 
  300                 linux_semid64.sem_otime = linux_semid->sem_otime;
  301                 linux_semid64.sem_ctime = linux_semid->sem_ctime;
  302                 linux_semid64.sem_nsems = linux_semid->sem_nsems;
  303 
  304                 return (copyout(&linux_semid64, uaddr, sizeof(linux_semid64)));
  305         } else {
  306                 return (copyout(linux_semid, uaddr, sizeof(*linux_semid)));
  307         }
  308 }
  309 
  310 static int
  311 linux_shmid_pullup(l_int ver, struct l_shmid_ds *linux_shmid, caddr_t uaddr)
  312 {
  313         struct l_shmid64_ds linux_shmid64;
  314         int error;
  315 
  316         if (ver == LINUX_IPC_64) {
  317                 error = copyin(uaddr, &linux_shmid64, sizeof(linux_shmid64));
  318                 if (error != 0)
  319                         return (error);
  320 
  321                 bzero(linux_shmid, sizeof(*linux_shmid));
  322 
  323                 linux_shmid->shm_perm.uid = linux_shmid64.shm_perm.uid;
  324                 linux_shmid->shm_perm.gid = linux_shmid64.shm_perm.gid;
  325                 linux_shmid->shm_perm.mode = linux_shmid64.shm_perm.mode;
  326         } else {
  327                 error = copyin(uaddr, linux_shmid, sizeof(*linux_shmid));
  328         }
  329         return (error);
  330 }
  331 
  332 static int
  333 linux_shmid_pushdown(l_int ver, struct l_shmid_ds *linux_shmid, caddr_t uaddr)
  334 {
  335         struct l_shmid64_ds linux_shmid64;
  336 
  337         /*
  338          * XXX: This is backwards and loses information in shm_nattch
  339          * and shm_segsz.  We should probably either expose the BSD
  340          * shmid structure directly and convert it to either the
  341          * non-64 or 64 variant directly or the code should always
  342          * convert to the 64 variant and then truncate values into the
  343          * non-64 variant if needed since the 64 variant has more
  344          * precision.
  345          */
  346         if (ver == LINUX_IPC_64) {
  347                 bzero(&linux_shmid64, sizeof(linux_shmid64));
  348 
  349                 linux_ipc_perm_to_ipc64_perm(&linux_shmid->shm_perm,
  350                     &linux_shmid64.shm_perm);
  351 
  352                 linux_shmid64.shm_segsz = linux_shmid->shm_segsz;
  353                 linux_shmid64.shm_atime = linux_shmid->shm_atime;
  354                 linux_shmid64.shm_dtime = linux_shmid->shm_dtime;
  355                 linux_shmid64.shm_ctime = linux_shmid->shm_ctime;
  356                 linux_shmid64.shm_cpid = linux_shmid->shm_cpid;
  357                 linux_shmid64.shm_lpid = linux_shmid->shm_lpid;
  358                 linux_shmid64.shm_nattch = linux_shmid->shm_nattch;
  359 
  360                 return (copyout(&linux_shmid64, uaddr, sizeof(linux_shmid64)));
  361         } else {
  362                 return (copyout(linux_shmid, uaddr, sizeof(*linux_shmid)));
  363         }
  364 }
  365 
  366 static int
  367 linux_shminfo_pushdown(l_int ver, struct l_shminfo *linux_shminfo,
  368     caddr_t uaddr)
  369 {
  370         struct l_shminfo64 linux_shminfo64;
  371 
  372         if (ver == LINUX_IPC_64) {
  373                 bzero(&linux_shminfo64, sizeof(linux_shminfo64));
  374 
  375                 linux_shminfo64.shmmax = linux_shminfo->shmmax;
  376                 linux_shminfo64.shmmin = linux_shminfo->shmmin;
  377                 linux_shminfo64.shmmni = linux_shminfo->shmmni;
  378                 linux_shminfo64.shmseg = linux_shminfo->shmseg;
  379                 linux_shminfo64.shmall = linux_shminfo->shmall;
  380 
  381                 return (copyout(&linux_shminfo64, uaddr,
  382                     sizeof(linux_shminfo64)));
  383         } else {
  384                 return (copyout(linux_shminfo, uaddr, sizeof(*linux_shminfo)));
  385         }
  386 }
  387 
  388 /*
  389  * MPSAFE
  390  */
  391 int
  392 linux_semop(struct linux_semop_args *args)
  393 {
  394         struct semop_args bsd_args;
  395         int error;
  396 
  397         bsd_args.sysmsg_result = 0;
  398         bsd_args.semid = args->semid;
  399         bsd_args.sops = (struct sembuf *)args->tsops;
  400         bsd_args.nsops = args->nsops;
  401         error = sys_semop(&bsd_args);
  402         args->sysmsg_result = bsd_args.sysmsg_result;
  403         return(error);
  404 }
  405 
  406 /*
  407  * MPSAFE
  408  */
  409 int
  410 linux_semget(struct linux_semget_args *args)
  411 {
  412         struct semget_args bsd_args;
  413         int error;
  414 
  415         bsd_args.sysmsg_result = 0;
  416         bsd_args.key = args->key;
  417         bsd_args.nsems = args->nsems;
  418         bsd_args.semflg = args->semflg;
  419         error = sys_semget(&bsd_args);
  420         args->sysmsg_result = bsd_args.sysmsg_result;
  421         return(error);
  422 }
  423 
  424 /*
  425  * MPSAFE
  426  */
  427 int
  428 linux_semctl(struct linux_semctl_args *args)
  429 {
  430         struct l_semid_ds linux_semid;
  431         struct __semctl_args bsd_args;
  432         struct l_seminfo linux_seminfo;
  433         int error;
  434         union semun *unptr;
  435         caddr_t sg;
  436 
  437         sg = stackgap_init();
  438 
  439         /* Make sure the arg parameter can be copied in. */
  440         unptr = stackgap_alloc(&sg, sizeof(union semun));
  441         bcopy(&args->arg, unptr, sizeof(union semun));
  442 
  443         bsd_args.sysmsg_result = 0;
  444         bsd_args.semid = args->semid;
  445         bsd_args.semnum = args->semnum;
  446         bsd_args.arg = unptr;
  447 
  448         switch (args->cmd & ~LINUX_IPC_64) {
  449         case LINUX_IPC_RMID:
  450                 bsd_args.cmd = IPC_RMID;
  451                 break;
  452         case LINUX_GETNCNT:
  453                 bsd_args.cmd = GETNCNT;
  454                 break;
  455         case LINUX_GETPID:
  456                 bsd_args.cmd = GETPID;
  457                 break;
  458         case LINUX_GETVAL:
  459                 bsd_args.cmd = GETVAL;
  460                 break;
  461         case LINUX_GETZCNT:
  462                 bsd_args.cmd = GETZCNT;
  463                 break;
  464         case LINUX_SETVAL:
  465                 bsd_args.cmd = SETVAL;
  466                 break;
  467         case LINUX_IPC_SET:
  468                 bsd_args.cmd = IPC_SET;
  469                 error = linux_semid_pullup(args->cmd & LINUX_IPC_64,
  470                     &linux_semid, (caddr_t)args->arg.buf);
  471                 if (error)
  472                         return (error);
  473                 unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds));
  474                 linux_to_bsd_semid_ds(&linux_semid, unptr->buf);
  475                 break;
  476         case LINUX_IPC_STAT:
  477         case LINUX_SEM_STAT:
  478                 if ((args->cmd & ~LINUX_IPC_64) == LINUX_IPC_STAT)
  479                         bsd_args.cmd = IPC_STAT;
  480                 else
  481                         bsd_args.cmd = SEM_STAT;
  482                 unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds));
  483                 error = sys___semctl(&bsd_args);
  484                 if (error)
  485                         return error;
  486                 args->sysmsg_result = IXSEQ_TO_IPCID(bsd_args.semid, 
  487                                                         unptr->buf->sem_perm);
  488                 bsd_to_linux_semid_ds(unptr->buf, &linux_semid);
  489                 error = linux_semid_pushdown(args->cmd & LINUX_IPC_64,
  490                     &linux_semid, (caddr_t)(args->arg.buf));
  491                 if (error == 0)
  492                         args->sysmsg_iresult = ((args->cmd & ~LINUX_IPC_64) == SEM_STAT)
  493                             ? bsd_args.sysmsg_result : 0;
  494                 return (error);
  495         case LINUX_IPC_INFO:
  496         case LINUX_SEM_INFO:
  497                 error = copyin((caddr_t)args->arg.buf, &linux_seminfo, 
  498                                                 sizeof(linux_seminfo) );
  499                 if (error)
  500                         return error;
  501                 bcopy(&seminfo, &linux_seminfo, sizeof(linux_seminfo) );
  502 /* XXX BSD equivalent?
  503 #define used_semids 10
  504 #define used_sems 10
  505                 linux_seminfo.semusz = used_semids;
  506                 linux_seminfo.semaem = used_sems;
  507 */
  508                 error = copyout((caddr_t)&linux_seminfo, (caddr_t)args->arg.buf,
  509                                                 sizeof(linux_seminfo) );
  510                 if (error)
  511                         return error;
  512                 args->sysmsg_result = seminfo.semmni;
  513                 return 0;                       /* No need for __semctl call */
  514         case LINUX_GETALL:
  515                 bsd_args.cmd = GETALL;
  516                 break;
  517         case LINUX_SETALL:
  518                 bsd_args.cmd = SETALL;
  519                 break;
  520         default:
  521                 uprintf("linux: 'ipc' type=%d not implemented\n", args->cmd & ~LINUX_IPC_64);
  522                 return EINVAL;
  523         }
  524         error = sys___semctl(&bsd_args);
  525         args->sysmsg_result = bsd_args.sysmsg_result;
  526         return(error);
  527 }
  528 
  529 /*
  530  * MPSAFE
  531  */
  532 int
  533 linux_msgsnd(struct linux_msgsnd_args *args)
  534 {
  535     struct msgsnd_args bsd_args;
  536     int error;
  537 
  538     if ((l_long)args->msgsz < 0 || args->msgsz > (l_long)msginfo.msgmax)
  539         return (EINVAL);
  540     bsd_args.sysmsg_result = 0;
  541     bsd_args.msqid = args->msqid;
  542     bsd_args.msgp = args->msgp;
  543     bsd_args.msgsz = args->msgsz;
  544     bsd_args.msgflg = args->msgflg;
  545     error = sys_msgsnd(&bsd_args);
  546     args->sysmsg_result = bsd_args.sysmsg_result;
  547     return(error);
  548 }
  549 
  550 /*
  551  * MPSAFE
  552  */
  553 int
  554 linux_msgrcv(struct linux_msgrcv_args *args)
  555 {
  556     struct msgrcv_args bsd_args; 
  557     int error;
  558     if ((l_long)args->msgsz < 0 || args->msgsz > (l_long)msginfo.msgmax)
  559             return (EINVAL);
  560     bsd_args.sysmsg_result = 0;
  561     bsd_args.msqid = args->msqid;
  562     bsd_args.msgp = args->msgp;
  563     bsd_args.msgsz = args->msgsz;
  564     bsd_args.msgtyp = 0; /* XXX - args->msgtyp; */
  565     bsd_args.msgflg = args->msgflg;
  566     error = sys_msgrcv(&bsd_args);
  567     args->sysmsg_result = bsd_args.sysmsg_result;
  568     return(error);
  569 }
  570 
  571 /*
  572  * MPSAFE
  573  */
  574 int
  575 linux_msgget(struct linux_msgget_args *args)
  576 {
  577     struct msgget_args bsd_args;
  578     int error;
  579 
  580     bsd_args.sysmsg_result = 0;
  581     bsd_args.key = args->key;
  582     bsd_args.msgflg = args->msgflg;
  583     error = sys_msgget(&bsd_args);
  584     args->sysmsg_result = bsd_args.sysmsg_result;
  585     return(error);
  586 }
  587 
  588 /*
  589  * MPSAFE
  590  */
  591 int
  592 linux_msgctl(struct linux_msgctl_args *args)
  593 {
  594     struct msgctl_args bsd_args;
  595     struct l_msqid_ds linux_msqid;
  596     int error, bsd_cmd;
  597     struct msqid_ds *unptr;
  598     caddr_t sg;
  599    
  600    sg = stackgap_init();
  601         /* Make sure the arg parameter can be copied in. */
  602         unptr = stackgap_alloc(&sg, sizeof(struct msqid_ds));
  603         bcopy(&args->buf, unptr, sizeof(struct msqid_ds));
  604 
  605     bsd_cmd = args->cmd & ~LINUX_IPC_64;
  606     bsd_args.sysmsg_result = 0;
  607     bsd_args.msqid = args->msqid;
  608     bsd_args.cmd = bsd_cmd;
  609     bsd_args.buf = unptr;
  610     switch(bsd_cmd) {
  611     case LINUX_IPC_INFO:
  612     case LINUX_MSG_INFO: {
  613         struct l_msginfo linux_msginfo;
  614 
  615         /*
  616          * XXX MSG_INFO uses the same data structure but returns different
  617          * dynamic counters in msgpool, msgmap, and msgtql fields.
  618          */
  619         linux_msginfo.msgpool = (long)msginfo.msgmni *
  620             (long)msginfo.msgmnb / 1024L;       /* XXX MSG_INFO. */
  621         linux_msginfo.msgmap = msginfo.msgmnb;  /* XXX MSG_INFO. */
  622         linux_msginfo.msgmax = msginfo.msgmax;
  623         linux_msginfo.msgmnb = msginfo.msgmnb;
  624         linux_msginfo.msgmni = msginfo.msgmni;
  625         linux_msginfo.msgssz = msginfo.msgssz;
  626         linux_msginfo.msgtql = msginfo.msgtql;  /* XXX MSG_INFO. */
  627         linux_msginfo.msgseg = msginfo.msgseg;
  628         error = copyout(&linux_msginfo, PTRIN(args->buf),
  629             sizeof(linux_msginfo));
  630         if (error == 0)
  631             args->sysmsg_iresult = msginfo.msgmni;      /* XXX */
  632 
  633         return (error);
  634     }
  635 
  636 /*
  637  * TODO: implement this
  638  * case LINUX_MSG_STAT:
  639  */
  640     case LINUX_IPC_STAT:
  641         /* NOTHING */
  642         break;
  643 
  644     case LINUX_IPC_SET:
  645         error = linux_msqid_pullup(args->cmd & LINUX_IPC_64,
  646             &linux_msqid, (caddr_t)(args->buf));
  647         if (error)
  648             return (error);
  649         linux_to_bsd_msqid_ds(&linux_msqid, unptr);
  650         break;
  651 
  652     case LINUX_IPC_RMID:
  653         /* NOTHING */
  654         break;
  655 
  656     default:
  657         return (EINVAL);
  658         break;
  659     }
  660 
  661     error = sys_msgctl(&bsd_args);
  662     if (error != 0)
  663         if (bsd_cmd != LINUX_IPC_RMID || error != EINVAL)
  664             return (error);
  665     if (bsd_cmd == LINUX_IPC_STAT) {
  666         bsd_to_linux_msqid_ds(bsd_args.buf, &linux_msqid);
  667         return (linux_msqid_pushdown(args->cmd & LINUX_IPC_64,
  668           &linux_msqid, PTRIN(args->buf)));
  669     }
  670     args->sysmsg_result = bsd_args.sysmsg_result;
  671     return ((args->cmd == LINUX_IPC_RMID && error == EINVAL) ? 0 : error);
  672 
  673 
  674 
  675 
  676 }
  677 
  678 /*
  679  * MPSAFE
  680  */
  681 int
  682 linux_shmat(struct linux_shmat_args *args)
  683 {
  684     struct shmat_args bsd_args;
  685     int error;
  686 
  687     bsd_args.sysmsg_result = 0;
  688     bsd_args.shmid = args->shmid;
  689     bsd_args.shmaddr = args->shmaddr;
  690     bsd_args.shmflg = args->shmflg;
  691     if ((error = sys_shmat(&bsd_args)))
  692         return error;
  693 #ifdef __i386__
  694     if ((error = copyout(&bsd_args.sysmsg_lresult, (caddr_t)args->raddr, sizeof(l_ulong))))
  695         return error;
  696     args->sysmsg_result = 0;
  697 #else
  698     args->sysmsg_result = bsd_args.sysmsg_result;
  699 #endif
  700     return 0;
  701 }
  702 
  703 /*
  704  * MPSAFE
  705  */
  706 int
  707 linux_shmdt(struct linux_shmdt_args *args)
  708 {
  709     struct shmdt_args bsd_args;
  710     int error;
  711 
  712     bsd_args.sysmsg_result = 0;
  713     bsd_args.shmaddr = args->shmaddr;
  714     error = sys_shmdt(&bsd_args);
  715     args->sysmsg_result = bsd_args.sysmsg_result;
  716     return(error);
  717 }
  718 
  719 /*
  720  * MPSAFE
  721  */
  722 int
  723 linux_shmget(struct linux_shmget_args *args)
  724 {
  725     struct shmget_args bsd_args;
  726     int error;
  727 
  728     bsd_args.sysmsg_result = 0;
  729     bsd_args.key = args->key;
  730     bsd_args.size = args->size;
  731     bsd_args.shmflg = args->shmflg;
  732     error = sys_shmget(&bsd_args);
  733     args->sysmsg_result = bsd_args.sysmsg_result;
  734     return(error);
  735 }
  736 
  737 /*
  738  * MPSAFE
  739  */
  740 extern int shm_nused;
  741 int
  742 linux_shmctl(struct linux_shmctl_args *args)
  743 {
  744     struct l_shmid_ds linux_shmid;
  745     struct l_shminfo linux_shminfo;
  746     struct l_shm_info linux_shm_info;
  747     struct shmctl_args bsd_args;
  748     int error;
  749     caddr_t sg = stackgap_init();
  750 
  751     bsd_args.sysmsg_result = 0;
  752     switch (args->cmd & ~LINUX_IPC_64) {
  753     case LINUX_IPC_STAT:
  754     case LINUX_SHM_STAT:
  755         bsd_args.shmid = args->shmid;
  756         bsd_args.cmd = IPC_STAT;
  757         bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  758         if ((error = sys_shmctl(&bsd_args)))
  759             return error;
  760         bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid);
  761         args->sysmsg_result = bsd_args.sysmsg_result;
  762         return (linux_shmid_pushdown(args->cmd & LINUX_IPC_64,
  763              &linux_shmid, PTRIN(args->buf)));
  764 
  765     case LINUX_IPC_SET:
  766         if ((error = linux_shmid_pullup(args->cmd & LINUX_IPC_64,
  767           &linux_shmid, PTRIN(args->buf))))
  768             return error;
  769         bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  770         linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf);
  771         bsd_args.shmid = args->shmid;
  772         bsd_args.cmd = IPC_SET;
  773         break;
  774     case LINUX_IPC_RMID:
  775         bsd_args.shmid = args->shmid;
  776         bsd_args.cmd = IPC_RMID;
  777         if (args->buf == NULL)
  778             bsd_args.buf = NULL;
  779         else {
  780             if ((error = linux_shmid_pullup(args->cmd & LINUX_IPC_64,
  781                     &linux_shmid, PTRIN(args->buf))))
  782                 return error;
  783             bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  784             linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf);
  785         }
  786         break;
  787     case LINUX_IPC_INFO:
  788         bsd_to_linux_shminfo(&shminfo, &linux_shminfo);
  789         return (linux_shminfo_pushdown(args->cmd & LINUX_IPC_64,
  790             &linux_shminfo, PTRIN(args->buf)));
  791         break;
  792     case LINUX_SHM_INFO:
  793         linux_shm_info.used_ids = shm_nused;
  794         linux_shm_info.shm_tot = 0;
  795         linux_shm_info.shm_rss = 0;
  796         linux_shm_info.shm_swp = 0;
  797         linux_shm_info.swap_attempts = 0;
  798         linux_shm_info.swap_successes = 0;
  799         return copyout(&linux_shm_info, PTRIN(args->buf),
  800             sizeof(struct l_shm_info));
  801     
  802     case LINUX_SHM_LOCK:
  803     case LINUX_SHM_UNLOCK:
  804     default:
  805         uprintf("linux: 'ipc' type=%d not implemented\n", args->cmd & ~LINUX_IPC_64);
  806         return EINVAL;
  807     }
  808     error = sys_shmctl(&bsd_args);
  809     args->sysmsg_result = bsd_args.sysmsg_result;
  810     return(error);
  811 }

Cache object: 1836bf4f5f1b6945d91fd1a1768154b1


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