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/i386/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 withough 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/i386/linux/linux_ipc.c,v 1.8.2.3 1999/09/05 08:14:15 peter Exp $
   29  */
   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/sem.h>
   37 #include <sys/shm.h>
   38 
   39 #include <i386/linux/linux.h>
   40 #include <i386/linux/linux_proto.h>
   41 #include <i386/linux/linux_util.h>
   42 
   43 static int linux_semop __P((struct proc *, struct linux_ipc_args *, int *));
   44 static int linux_semget __P((struct proc *, struct linux_ipc_args *, int *));
   45 static int linux_semctl __P((struct proc *, struct linux_ipc_args *, int *));
   46 static int linux_msgsnd __P((struct proc *, struct linux_ipc_args *, int *));
   47 static int linux_msgrcv __P((struct proc *, struct linux_ipc_args *, int *));
   48 static int linux_msgctl __P((struct proc *, struct linux_ipc_args *, int *));
   49 static int linux_shmat __P((struct proc *, struct linux_ipc_args *, int *));
   50 static int linux_shmdt __P((struct proc *, struct linux_ipc_args *, int *));
   51 static int linux_shmget __P((struct proc *, struct linux_ipc_args *, int *));
   52 static int linux_shmctl __P((struct proc *, struct linux_ipc_args *, int *));
   53 
   54 struct linux_ipc_perm {
   55     linux_key_t key;
   56     unsigned short uid;
   57     unsigned short gid;
   58     unsigned short cuid;
   59     unsigned short cgid;
   60     unsigned short mode;
   61     unsigned short seq;
   62 };
   63 
   64 static void
   65 linux_to_bsd_ipc_perm(struct linux_ipc_perm *lpp, struct ipc_perm *bpp)
   66 {
   67     bpp->key = lpp->key;
   68     bpp->uid = lpp->uid;
   69     bpp->gid = lpp->gid;
   70     bpp->cuid = lpp->cuid;
   71     bpp->cgid = lpp->cgid;
   72     bpp->mode = lpp->mode;
   73     bpp->seq = lpp->seq;
   74 }
   75 
   76 
   77 static void
   78 bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct linux_ipc_perm *lpp)
   79 {
   80     lpp->key = bpp->key;
   81     lpp->uid = bpp->uid;
   82     lpp->gid = bpp->gid;
   83     lpp->cuid = bpp->cuid;
   84     lpp->cgid = bpp->cgid;
   85     lpp->mode = bpp->mode;
   86     lpp->seq = bpp->seq;
   87 }
   88 
   89 struct linux_semid_ds {
   90         struct linux_ipc_perm   sem_perm;
   91         linux_time_t            sem_otime;
   92         linux_time_t            sem_ctime;
   93         void                    *sem_base;
   94         void                    *sem_pending;
   95         void                    *sem_pending_last;
   96         void                    *undo;
   97         ushort                  sem_nsems;
   98 };
   99 
  100 struct linux_shmid_ds {
  101     struct linux_ipc_perm shm_perm;
  102     int shm_segsz;
  103     linux_time_t shm_atime;
  104     linux_time_t shm_dtime;
  105     linux_time_t shm_ctime;
  106     ushort shm_cpid;
  107     ushort shm_lpid;
  108     short shm_nattch;
  109     ushort private1;
  110     void *private2;
  111     void *private3;
  112 };
  113 
  114 static void
  115 linux_to_bsd_semid_ds(struct linux_semid_ds *lsp, struct semid_ds *bsp)
  116 {
  117     linux_to_bsd_ipc_perm(&lsp->sem_perm, &bsp->sem_perm);
  118     bsp->sem_otime = lsp->sem_otime;
  119     bsp->sem_ctime = lsp->sem_ctime;
  120     bsp->sem_nsems = lsp->sem_nsems;
  121     bsp->sem_base = lsp->sem_base;
  122 }
  123 
  124 static void
  125 bsd_to_linux_semid_ds(struct semid_ds *bsp, struct linux_semid_ds *lsp)
  126 {
  127         bsd_to_linux_ipc_perm(&bsp->sem_perm, &lsp->sem_perm);
  128         lsp->sem_otime = bsp->sem_otime;
  129         lsp->sem_ctime = bsp->sem_ctime;
  130         lsp->sem_nsems = bsp->sem_nsems;
  131         lsp->sem_base = bsp->sem_base;
  132 }
  133 
  134 static void
  135 linux_to_bsd_shmid_ds(struct linux_shmid_ds *lsp, struct shmid_ds *bsp)
  136 {
  137     linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
  138     bsp->shm_segsz = lsp->shm_segsz;
  139     bsp->shm_lpid = lsp->shm_lpid;
  140     bsp->shm_cpid = lsp->shm_cpid;
  141     bsp->shm_nattch = lsp->shm_nattch;
  142     bsp->shm_atime = lsp->shm_atime;
  143     bsp->shm_dtime = lsp->shm_dtime;
  144     bsp->shm_ctime = lsp->shm_ctime;
  145     bsp->shm_internal = lsp->private3;  /* this goes (yet) SOS */
  146 }
  147 
  148 static void
  149 bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct linux_shmid_ds *lsp)
  150 {
  151     bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
  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 = bsp->shm_internal;  /* this goes (yet) SOS */
  160 }
  161 
  162 static int
  163 linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
  164 {
  165         struct semop_args /* {
  166         int     semid;
  167         struct  sembuf *sops;
  168         int             nsops;
  169         } */ bsd_args;
  170 
  171         bsd_args.semid = args->arg1;
  172         bsd_args.sops = (struct sembuf *)args->ptr;
  173         bsd_args.nsops = args->arg2;
  174         return semop(p, &bsd_args, retval);
  175 }
  176 
  177 static int
  178 linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
  179 {
  180         struct semget_args /* {
  181         key_t   key;
  182         int             nsems;
  183         int             semflg;
  184         } */ bsd_args;
  185 
  186         bsd_args.key = args->arg1;
  187         bsd_args.nsems = args->arg2;
  188         bsd_args.semflg = args->arg3;
  189         return semget(p, &bsd_args, retval);
  190 }
  191 
  192 static int
  193 linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
  194 {
  195         struct linux_semid_ds   linux_semid;
  196         struct semid_ds bsd_semid;
  197         struct __semctl_args /* {
  198         int             semid;
  199         int             semnum;
  200         int             cmd;
  201         union   semun *arg;
  202         } */ bsd_args;
  203         int     error;
  204         caddr_t sg, unptr, dsp, ldsp;
  205 
  206         sg = stackgap_init();
  207         bsd_args.semid = args->arg1;
  208         bsd_args.semnum = args->arg2;
  209         bsd_args.cmd = args->arg3;
  210         bsd_args.arg = (union semun *)args->ptr;
  211 
  212         switch (args->arg3) {
  213         case LINUX_IPC_RMID:
  214                 bsd_args.cmd = IPC_RMID;
  215                 break;
  216         case LINUX_GETNCNT:
  217                 bsd_args.cmd = GETNCNT;
  218                 break;
  219         case LINUX_GETPID:
  220                 bsd_args.cmd = GETPID;
  221                 break;
  222         case LINUX_GETVAL:
  223                 bsd_args.cmd = GETVAL;
  224                 break;
  225         case LINUX_GETZCNT:
  226                 bsd_args.cmd = GETZCNT;
  227                 break;
  228         case LINUX_SETVAL:
  229                 bsd_args.cmd = SETVAL;
  230                 break;
  231         case LINUX_IPC_SET:
  232                 bsd_args.cmd = IPC_SET;
  233                 error = copyin(args->ptr, &ldsp, sizeof(ldsp));
  234                 if (error)
  235                         return error;
  236                 error = copyin(ldsp, (caddr_t)&linux_semid, sizeof(linux_semid));
  237                 if (error)
  238                         return error;
  239                 linux_to_bsd_semid_ds(&linux_semid, &bsd_semid);
  240                 unptr = stackgap_alloc(&sg, sizeof(union semun));
  241                 dsp = stackgap_alloc(&sg, sizeof(struct semid_ds));
  242                 error = copyout((caddr_t)&bsd_semid, dsp, sizeof(bsd_semid));
  243                 if (error)
  244                         return error;
  245                 error = copyout((caddr_t)&dsp, unptr, sizeof(dsp));
  246                 if (error)
  247                         return error;
  248                 bsd_args.arg = (union semun *)unptr;
  249                 return __semctl(p, &bsd_args, retval);
  250         case LINUX_IPC_STAT:
  251                 bsd_args.cmd = IPC_STAT;
  252                 unptr = stackgap_alloc(&sg, sizeof(union semun *));
  253                 dsp = stackgap_alloc(&sg, sizeof(struct semid_ds));
  254                 error = copyout((caddr_t)&dsp, unptr, sizeof(dsp));
  255                 if (error)
  256                         return error;
  257                 bsd_args.arg = (union semun *)unptr;
  258                 error = __semctl(p, &bsd_args, retval);
  259                 if (error)
  260                         return error;
  261                 error = copyin(dsp, (caddr_t)&bsd_semid, sizeof(bsd_semid));
  262                 if (error)
  263                         return error;
  264                 bsd_to_linux_semid_ds(&bsd_semid, &linux_semid);
  265                 error = copyin(args->ptr, &ldsp, sizeof(ldsp));
  266                 if (error)
  267                         return error;
  268                 return copyout((caddr_t)&linux_semid, ldsp, sizeof(linux_semid));
  269         case LINUX_GETALL:
  270                 /* FALLTHROUGH */
  271         case LINUX_SETALL:
  272                 /* FALLTHROUGH */
  273         default:
  274                 uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
  275                 return EINVAL;
  276         }
  277         return __semctl(p, &bsd_args, retval);
  278 }
  279 
  280 static int
  281 linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
  282 {
  283     struct msgsnd_args /* {
  284         int     msqid;   
  285         void    *msgp;   
  286         size_t  msgsz;   
  287         int     msgflg; 
  288     } */ bsd_args;
  289 
  290     bsd_args.msqid = args->arg1;
  291     bsd_args.msgp = args->ptr;
  292     bsd_args.msgsz = args->arg2;
  293     bsd_args.msgflg = args->arg3;
  294     return msgsnd(p, &bsd_args, retval);
  295 }
  296 
  297 static int
  298 linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
  299 {
  300     struct msgrcv_args /* {     
  301         int     msqid;   
  302         void    *msgp;   
  303         size_t  msgsz;   
  304         long    msgtyp; 
  305         int     msgflg; 
  306     } */ bsd_args; 
  307 
  308     bsd_args.msqid = args->arg1;
  309     bsd_args.msgp = args->ptr;
  310     bsd_args.msgsz = args->arg2;
  311     bsd_args.msgtyp = 0;
  312     bsd_args.msgflg = args->arg3;
  313     return msgrcv(p, &bsd_args, retval);
  314 }
  315 
  316 static int
  317 linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
  318 {
  319     struct msgget_args /* {
  320         key_t   key;
  321         int     msgflg;
  322     } */ bsd_args;
  323 
  324     bsd_args.key = args->arg1;
  325     bsd_args.msgflg = args->arg2;
  326     return msgget(p, &bsd_args, retval);
  327 }
  328 
  329 static int
  330 linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
  331 {
  332     struct msgctl_args /* {
  333         int     msqid; 
  334         int     cmd;
  335         struct  msqid_ds *buf;
  336     } */ bsd_args;
  337 
  338     bsd_args.msqid = args->arg1;
  339     bsd_args.cmd = args->arg2;
  340     bsd_args.buf = (struct msqid_ds *)args->ptr;
  341     return msgctl(p, &bsd_args, retval);
  342 }
  343 
  344 static int
  345 linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
  346 {
  347     struct shmat_args /* {
  348         int shmid;
  349         void *shmaddr;
  350         int shmflg;
  351     } */ bsd_args;
  352     int error;
  353 
  354     bsd_args.shmid = args->arg1;
  355     bsd_args.shmaddr = args->ptr;
  356     bsd_args.shmflg = args->arg2;
  357     if ((error = shmat(p, &bsd_args, retval)))
  358         return error;
  359     if ((error = copyout(retval, (caddr_t)args->arg3, sizeof(int))))
  360         return error;
  361     retval[0] = 0;
  362     return 0;
  363 }
  364 
  365 static int
  366 linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
  367 {
  368     struct shmdt_args /* {
  369         void *shmaddr;
  370     } */ bsd_args;
  371 
  372     bsd_args.shmaddr = args->ptr;
  373     return shmdt(p, &bsd_args, retval);
  374 }
  375 
  376 static int
  377 linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
  378 {
  379     struct shmget_args /* {
  380         key_t key;
  381         int size;
  382         int shmflg;
  383     } */ bsd_args;
  384 
  385     bsd_args.key = args->arg1;
  386     bsd_args.size = args->arg2;
  387     bsd_args.shmflg = args->arg3;
  388     return shmget(p, &bsd_args, retval);
  389 }
  390 
  391 static int
  392 linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
  393 {
  394     struct shmid_ds bsd_shmid;
  395     struct linux_shmid_ds linux_shmid;
  396     struct shmctl_args /* {
  397         int shmid;
  398         int cmd;
  399         struct shmid_ds *buf;
  400     } */ bsd_args;
  401     int error;
  402     caddr_t sg = stackgap_init();
  403 
  404     switch (args->arg2) {
  405     case LINUX_IPC_STAT:
  406         bsd_args.shmid = args->arg1;
  407         bsd_args.cmd = IPC_STAT;
  408         bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  409         if ((error = shmctl(p, &bsd_args, retval)))
  410             return error;
  411         if ((error = copyin((caddr_t)bsd_args.buf, (caddr_t)&bsd_shmid,
  412                             sizeof(struct shmid_ds))))
  413             return error;
  414         bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid);
  415         return copyout((caddr_t)&linux_shmid, args->ptr, sizeof(linux_shmid));
  416 
  417     case LINUX_IPC_SET:
  418         if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
  419                             sizeof(linux_shmid))))
  420             return error;
  421         linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
  422         bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  423         if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
  424                              sizeof(struct shmid_ds))))
  425             return error;
  426         bsd_args.shmid = args->arg1;
  427         bsd_args.cmd = IPC_SET;
  428         return shmctl(p, &bsd_args, retval);
  429 
  430     case LINUX_IPC_RMID:
  431         bsd_args.shmid = args->arg1;
  432         bsd_args.cmd = IPC_RMID;
  433         if (NULL == args->ptr)
  434             bsd_args.buf = NULL;
  435         else {
  436             if ((error = copyin(args->ptr, (caddr_t)&linux_shmid, 
  437                                 sizeof(linux_shmid))))
  438                 return error;
  439             linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
  440             bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  441             if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
  442                                 sizeof(struct shmid_ds))))
  443                 return error;
  444         }
  445         return shmctl(p, &bsd_args, retval);
  446 
  447     case LINUX_IPC_INFO:
  448     case LINUX_SHM_STAT:
  449     case LINUX_SHM_INFO:
  450     case LINUX_SHM_LOCK:
  451     case LINUX_SHM_UNLOCK:
  452     default:
  453         uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
  454         return EINVAL;
  455     }
  456 }
  457 
  458 int
  459 linux_ipc(struct proc *p, struct linux_ipc_args *args, int *retval)
  460 {
  461     switch (args->what) {
  462     case LINUX_SEMOP:
  463         return linux_semop(p, args, retval);
  464     case LINUX_SEMGET:
  465         return linux_semget(p, args, retval);
  466     case LINUX_SEMCTL:
  467         return linux_semctl(p, args, retval);
  468     case LINUX_MSGSND:
  469         return linux_msgsnd(p, args, retval);
  470     case LINUX_MSGRCV:
  471         return linux_msgrcv(p, args, retval);
  472     case LINUX_MSGGET:
  473         return linux_msgget(p, args, retval);
  474     case LINUX_MSGCTL:
  475         return linux_msgctl(p, args, retval);
  476     case LINUX_SHMAT:
  477         return linux_shmat(p, args, retval);
  478     case LINUX_SHMDT:
  479         return linux_shmdt(p, args, retval);
  480     case LINUX_SHMGET:
  481         return linux_shmget(p, args, retval);
  482     case LINUX_SHMCTL:
  483         return linux_shmctl(p, args, retval);
  484     default:
  485         uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
  486         return ENOSYS;
  487     }
  488 }

Cache object: 9bb21165fbecad0e11301fd9bd52a17a


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