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/ibcs2/ibcs2_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: ibcs2_ipc.c,v 1.27 2007/12/20 23:02:49 dsl Exp $       */
    2 
    3 /*
    4  * Copyright (c) 1995 Scott Bartram
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. The name of the author may not be used to endorse or promote products
   13  *    derived from this software without specific prior written permission
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __KERNEL_RCSID(0, "$NetBSD: ibcs2_ipc.c,v 1.27 2007/12/20 23:02:49 dsl Exp $");
   29 
   30 #if defined(_KERNEL_OPT)
   31 #include "opt_sysv.h"
   32 #endif
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/namei.h>
   37 #include <sys/proc.h>
   38 #include <sys/file.h>
   39 #include <sys/stat.h>
   40 #include <sys/filedesc.h>
   41 #include <sys/ioctl.h>
   42 #include <sys/ipc.h>
   43 #include <sys/kernel.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/mman.h>
   46 #include <sys/mount.h>
   47 #include <sys/reboot.h>
   48 #include <sys/resource.h>
   49 #include <sys/resourcevar.h>
   50 #include <sys/signal.h>
   51 #include <sys/signalvar.h>
   52 #include <sys/socket.h>
   53 #include <sys/time.h>
   54 #include <sys/times.h>
   55 #include <sys/vnode.h>
   56 #include <sys/uio.h>
   57 #include <sys/wait.h>
   58 #include <sys/utsname.h>
   59 #include <sys/unistd.h>
   60 #include <sys/msg.h>
   61 #include <sys/sem.h>
   62 #include <sys/shm.h>
   63 #include <sys/syscallargs.h>
   64 
   65 #include <compat/ibcs2/ibcs2_types.h>
   66 #include <compat/ibcs2/ibcs2_signal.h>
   67 #include <compat/ibcs2/ibcs2_syscallargs.h>
   68 #include <compat/ibcs2/ibcs2_util.h>
   69 
   70 #include <compat/sys/sem.h>
   71 #include <compat/sys/shm.h>
   72 #include <compat/sys/msg.h>
   73 
   74 /* Verify that the standard values are correct. */
   75 typedef char x[IPC_RMID == 0 && IPC_SET == 1 && IPC_STAT == 2 ? 1 : -1];
   76 
   77 struct ibcs2_ipc_perm {
   78         ibcs2_uid_t uid;
   79         ibcs2_gid_t gid;
   80         ibcs2_uid_t cuid;
   81         ibcs2_gid_t cgid;
   82         ibcs2_mode_t mode;
   83         u_short seq;
   84         ibcs2_key_t key;
   85 };
   86 
   87 struct ibcs2_msqid_ds {
   88         struct ibcs2_ipc_perm msg_perm;
   89         struct __msg *msg_first;        /* kernel address don't copyout */
   90         struct __msg *msg_last;         /* kernel address don't copyout */
   91         u_short msg_cbytes;
   92         u_short msg_qnum;
   93         u_short msg_qbytes;
   94         u_short msg_lspid;
   95         u_short msg_lrpid;
   96         ibcs2_time_t msg_stime;
   97         ibcs2_time_t msg_rtime;
   98         ibcs2_time_t msg_ctime;
   99 };
  100 
  101 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
  102 static void
  103 cvt_perm2iperm(const struct ipc_perm *bp, struct ibcs2_ipc_perm *ibp)
  104 {
  105         ibp->cuid = bp->cuid;
  106         ibp->cgid = bp->cgid;
  107         ibp->uid = bp->uid;
  108         ibp->gid = bp->gid;
  109         ibp->mode = bp->mode;
  110         ibp->seq = bp->_seq;
  111         ibp->key = bp->_key;
  112 }
  113 
  114 static void
  115 cvt_iperm2perm(const struct ibcs2_ipc_perm *ibp, struct ipc_perm *bp)
  116 {
  117         bp->cuid = ibp->cuid;
  118         bp->cgid = ibp->cgid;
  119         bp->uid = ibp->uid;
  120         bp->gid = ibp->gid;
  121         bp->mode = ibp->mode;
  122         bp->_seq = ibp->seq;
  123         bp->_key = ibp->key;
  124 }
  125 #endif /* SYSVMSG || SYSVSEM || SYSVMSG */
  126 
  127 #ifdef SYSVMSG
  128 
  129 /*
  130  * iBCS2 msgsys call
  131  */
  132 
  133 static void
  134 cvt_msqid2imsqid(const struct msqid_ds *bp, struct ibcs2_msqid_ds *ibp)
  135 {
  136         cvt_perm2iperm(&bp->msg_perm, &ibp->msg_perm);
  137         ibp->msg_first = NULL;
  138         ibp->msg_last = NULL;
  139         ibp->msg_cbytes = bp->_msg_cbytes;
  140         ibp->msg_qnum = bp->msg_qnum;
  141         ibp->msg_qbytes = bp->msg_qbytes;
  142         ibp->msg_lspid = bp->msg_lspid;
  143         ibp->msg_lrpid = bp->msg_lrpid;
  144         ibp->msg_stime = bp->msg_stime;
  145         ibp->msg_rtime = bp->msg_rtime;
  146         ibp->msg_ctime = bp->msg_ctime;
  147 }
  148 
  149 static void
  150 cvt_imsqid2msqid(struct ibcs2_msqid_ds *ibp, struct msqid_ds *bp)
  151 {
  152         cvt_iperm2perm(&ibp->msg_perm, &bp->msg_perm);
  153         bp->_msg_first = NULL;
  154         bp->_msg_last = NULL;
  155         bp->_msg_cbytes = ibp->msg_cbytes;
  156         bp->msg_qnum = ibp->msg_qnum;
  157         bp->msg_qbytes = ibp->msg_qbytes;
  158         bp->msg_lspid = ibp->msg_lspid;
  159         bp->msg_lrpid = ibp->msg_lrpid;
  160         bp->msg_stime = ibp->msg_stime;
  161         bp->msg_rtime = ibp->msg_rtime;
  162         bp->msg_ctime = ibp->msg_ctime;
  163 }
  164 
  165 static int
  166 do_compat_10_sys_msgsys(struct lwp *l, const struct ibcs2_sys_msgsys_args *uap,
  167     register_t *retval, int which)
  168 {
  169     struct compat_10_sys_msgsys_args bsd_ua;
  170 
  171     SCARG(&bsd_ua, which) = which;
  172     SCARG(&bsd_ua, a2) = SCARG(uap, a2);
  173     SCARG(&bsd_ua, a3) = SCARG(uap, a3);
  174     SCARG(&bsd_ua, a4) = SCARG(uap, a4);
  175     SCARG(&bsd_ua, a5) = SCARG(uap, a5);
  176     SCARG(&bsd_ua, a6) = SCARG(uap, a6);
  177 
  178     return compat_10_sys_msgsys(l, &bsd_ua, retval);
  179 }
  180 
  181 int
  182 ibcs2_sys_msgsys(struct lwp *l, const struct ibcs2_sys_msgsys_args *uap, register_t *retval)
  183 {
  184 #ifdef SYSVMSG
  185         /* {
  186                 syscallarg(int) which;
  187                 syscallarg(int) a2;
  188                 syscallarg(int) a3;
  189                 syscallarg(int) a4;
  190                 syscallarg(int) a5;
  191                 syscallarg(int) a6;
  192         } */
  193         int error;
  194         struct msqid_ds msqbuf;
  195         struct ibcs2_msqid_ds msqbuf_ibcs2, *ibp;
  196 
  197         switch (SCARG(uap, which)) {
  198         case 0:                         /* msgget */
  199                 return do_compat_10_sys_msgsys(l, uap, retval, 1);
  200         case 1:                         /* msgctl */
  201                 ibp = (void *)SCARG(uap, a4);
  202                 switch (SCARG(uap, a3)) {
  203                 case IPC_STAT:
  204                         error = msgctl1(l, SCARG(uap, a2), IPC_STAT, &msqbuf);
  205                         if (error == 0) {
  206                                 cvt_msqid2imsqid(&msqbuf, &msqbuf_ibcs2);
  207                                 error = copyout(&msqbuf_ibcs2, ibp,
  208                                     sizeof msqbuf_ibcs2);
  209                         }
  210                         return error;
  211                 case IPC_SET:
  212                         error = copyin(ibp, &msqbuf_ibcs2, sizeof msqbuf_ibcs2);
  213                         if (error == 0) {
  214                                 cvt_imsqid2msqid(&msqbuf_ibcs2, &msqbuf);
  215                                 error = msgctl1(l, SCARG(uap, a2),
  216                                     IPC_SET, &msqbuf);
  217                         }
  218                         return error;
  219                 case IPC_RMID:
  220                         return msgctl1(l, SCARG(uap, a2), IPC_RMID, NULL);
  221                 }
  222                 return EINVAL;
  223         case 2:                         /* msgrcv */
  224                 return do_compat_10_sys_msgsys(l, uap, retval, 3);
  225         case 3:                         /* msgsnd */
  226                 return do_compat_10_sys_msgsys(l, uap, retval, 2);
  227         default:
  228                 break;
  229         }
  230 #endif
  231         return EINVAL;
  232 }
  233 
  234 #endif /* SYSVMSG */
  235 
  236 #ifdef SYSVSEM
  237 
  238 /*
  239  * iBCS2 semsys call
  240  */
  241 
  242 struct ibcs2_semid_ds {
  243         struct ibcs2_ipc_perm sem_perm;
  244         struct ibcs2_sem *sem_base;
  245         u_short sem_nsems;
  246         u_short pad1;
  247         ibcs2_time_t sem_otime;
  248         ibcs2_time_t sem_ctime;
  249 };
  250 
  251 struct ibcs2_sem {
  252         u_short semval;
  253         ibcs2_pid_t sempid;
  254         u_short semncnt;
  255         u_short semzcnt;
  256 };
  257 
  258 #ifdef notdef
  259 static void cvt_sem2isem(struct sem *, struct ibcs2_sem *);
  260 static void cvt_isem2sem(struct ibcs2_sem *, struct sem *);
  261 
  262 static void
  263 cvt_sem2isem(struct __sem *bp, struct ibcs2_sem *ibp)
  264 {
  265         ibp->semval = bp->semval;
  266         ibp->sempid = bp->sempid;
  267         ibp->semncnt = bp->semncnt;
  268         ibp->semzcnt = bp->semzcnt;
  269 }
  270 
  271 static void
  272 cvt_isem2sem(struct ibcs2_sem *ibp, struct __sem *bp)
  273 {
  274         bp->semval = ibp->semval;
  275         bp->sempid = ibp->sempid;
  276         bp->semncnt = ibp->semncnt;
  277         bp->semzcnt = ibp->semzcnt;
  278 }
  279 #endif
  280 
  281 static void
  282 cvt_semid2isemid(const struct semid_ds *bp, struct ibcs2_semid_ds *ibp)
  283 {
  284         cvt_perm2iperm(&bp->sem_perm, &ibp->sem_perm);
  285         ibp->sem_base = (struct ibcs2_sem *)bp->_sem_base;
  286         ibp->sem_nsems = bp->sem_nsems;
  287         ibp->sem_otime = bp->sem_otime;
  288         ibp->sem_ctime = bp->sem_ctime;
  289 }
  290 
  291 
  292 static void
  293 cvt_isemid2semid(const struct ibcs2_semid_ds *ibp, struct semid_ds *bp)
  294 {
  295         cvt_iperm2perm(&ibp->sem_perm, &bp->sem_perm);
  296         bp->_sem_base = (struct __sem *)ibp->sem_base;
  297         bp->sem_nsems = ibp->sem_nsems;
  298         bp->sem_otime = ibp->sem_otime;
  299         bp->sem_ctime = ibp->sem_ctime;
  300 }
  301 
  302 int
  303 ibcs2_sys_semsys(struct lwp *l, const struct ibcs2_sys_semsys_args *uap, register_t *retval)
  304 {
  305 #ifdef SYSVSEM
  306         /* {
  307                 syscallarg(int) which;
  308                 syscallarg(int) a2;
  309                 syscallarg(int) a3;
  310                 syscallarg(int) a4;
  311                 syscallarg(int) a5;
  312         } */
  313         struct semid_ds sembuf;
  314         struct ibcs2_semid_ds isembuf;
  315         void *pass_arg;
  316         int a5 = SCARG(uap, a5);
  317         int error;
  318 
  319         switch (SCARG(uap, which)) {
  320         case 0:                                 /* semctl */
  321 #define semctl_semid    SCARG(uap, a2)
  322 #define semctl_semnum   SCARG(uap, a3)
  323 #define semctl_cmd      SCARG(uap, a4)
  324 #define semctl_arg      ((union __semun *)&a5)
  325                 pass_arg = get_semctl_arg(semctl_cmd, &sembuf, semctl_arg);
  326                 if (semctl_cmd == IPC_SET) {
  327                         error = copyin(semctl_arg->buf, &isembuf, sizeof isembuf);
  328                         if (error != 0)
  329                                 return error;
  330                         cvt_isemid2semid(&isembuf, &sembuf);
  331                 }
  332                 error = semctl1(l, semctl_semid, semctl_semnum, semctl_cmd, 
  333                     pass_arg, retval);
  334                 if (error == 0 && semctl_cmd == IPC_STAT) {
  335                         cvt_semid2isemid(&sembuf, &isembuf);
  336                         error = copyout(&isembuf, semctl_arg->buf, sizeof(isembuf));
  337                 }
  338                 return error;
  339 #undef  semctl_semid
  340 #undef  semctl_semnum
  341 #undef  semctl_cmd
  342 #undef  semctl_arg
  343 
  344         case 1:                         /* semget */
  345                 return compat_10_sys_semsys(l, (const void *)uap, retval);
  346 
  347         case 2:                         /* semop */
  348                 return compat_10_sys_semsys(l, (const void *)uap, retval);
  349         }
  350 #endif
  351         return EINVAL;
  352 }
  353 
  354 #endif /* SYSVSEM */
  355 
  356 #ifdef SYSVSHM
  357 
  358 /*
  359  * iBCS2 shmsys call
  360  */
  361 
  362 struct ibcs2_shmid_ds {
  363         struct ibcs2_ipc_perm shm_perm;
  364         int shm_segsz;
  365         int pad1;
  366         char pad2[4];
  367         u_short shm_lpid;
  368         u_short shm_cpid;
  369         u_short shm_nattch;
  370         u_short shm_cnattch;
  371         ibcs2_time_t shm_atime;
  372         ibcs2_time_t shm_dtime;
  373         ibcs2_time_t shm_ctime;
  374 };
  375 
  376 static void
  377 cvt_shmid2ishmid(const struct shmid_ds *bp, struct ibcs2_shmid_ds *ibp)
  378 {
  379         cvt_perm2iperm(&bp->shm_perm, &ibp->shm_perm);
  380         ibp->shm_segsz = bp->shm_segsz;
  381         ibp->shm_lpid = bp->shm_lpid;
  382         ibp->shm_cpid = bp->shm_cpid;
  383         ibp->shm_nattch = bp->shm_nattch;
  384         ibp->shm_cnattch = 0;                   /* ignored anyway */
  385         ibp->shm_atime = bp->shm_atime;
  386         ibp->shm_dtime = bp->shm_dtime;
  387         ibp->shm_ctime = bp->shm_ctime;
  388 }
  389 
  390 static void
  391 cvt_ishmid2shmid(const struct ibcs2_shmid_ds *ibp, struct shmid_ds *bp)
  392 {
  393         cvt_iperm2perm(&ibp->shm_perm, &bp->shm_perm);
  394         bp->shm_segsz = ibp->shm_segsz;
  395         bp->shm_lpid = ibp->shm_lpid;
  396         bp->shm_cpid = ibp->shm_cpid;
  397         bp->shm_nattch = ibp->shm_nattch;
  398         bp->shm_atime = ibp->shm_atime;
  399         bp->shm_dtime = ibp->shm_dtime;
  400         bp->shm_ctime = ibp->shm_ctime;
  401         bp->_shm_internal = (void *)0;          /* ignored anyway */
  402         return;
  403 }
  404 
  405 int
  406 ibcs2_sys_shmsys(struct lwp *l, const struct ibcs2_sys_shmsys_args *uap, register_t *retval)
  407 {
  408 #ifdef SYSVSHM
  409         /* {
  410                 syscallarg(int) which;
  411                 syscallarg(int) a2;
  412                 syscallarg(int) a3;
  413                 syscallarg(int) a4;
  414         } */
  415         struct shmid_ds shmbuf;
  416         struct ibcs2_shmid_ds *isp, ishmbuf;
  417         int cmd, error;
  418 
  419         switch (SCARG(uap, which)) {
  420         case 0:                                         /* shmat */
  421                 break;
  422 
  423         case 1:                                         /* shmctl */
  424                 cmd = SCARG(uap, a3);
  425                 isp = (struct ibcs2_shmid_ds *)SCARG(uap, a4);
  426                 if (cmd == IPC_SET) {
  427                         error = copyin(isp, &ishmbuf, sizeof(ishmbuf));
  428                         if (error)
  429                                 return error;
  430                         cvt_ishmid2shmid(&ishmbuf, &shmbuf);
  431                 }
  432 
  433                 error = shmctl1(l, SCARG(uap, a2), cmd,
  434                     (cmd == IPC_SET || cmd == IPC_STAT) ? &shmbuf : NULL);
  435 
  436                 if (error == 0 && cmd == IPC_STAT) {
  437                         cvt_shmid2ishmid(&shmbuf, &ishmbuf);
  438                         error = copyout(&ishmbuf, isp, sizeof(ishmbuf));
  439                 }
  440                 return error;
  441 
  442         case 2:                                         /* shmdt */
  443                 break;
  444 
  445         case 3:                                         /* shmget */
  446                 break;
  447 
  448         default:
  449                 return EINVAL;
  450         }
  451         return compat_10_sys_shmsys(l, (const void *)uap, retval);
  452 #else
  453         return EINVAL;
  454 #endif
  455 }
  456 
  457 #endif /* SYSVSHM */

Cache object: 316d2bfe322dd05a0ed4fea734d67844


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