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/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$
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/sysproto.h>
   34 #include <sys/proc.h>
   35 #include <sys/sem.h>
   36 #include <sys/shm.h>
   37 
   38 #include <machine/../linux/linux.h>
   39 #include <machine/../linux/linux_proto.h>
   40 #include <compat/linux/linux_ipc.h>
   41 #include <compat/linux/linux_util.h>
   42 
   43 struct l_seminfo {
   44         l_int semmap;
   45         l_int semmni;
   46         l_int semmns;
   47         l_int semmnu;
   48         l_int semmsl;
   49         l_int semopm;
   50         l_int semume;
   51         l_int semusz;
   52         l_int semvmx;
   53         l_int semaem;
   54 };
   55 
   56 struct l_shminfo {
   57         l_int shmmax;
   58         l_int shmmin;
   59         l_int shmmni;
   60         l_int shmseg;
   61         l_int shmall;
   62 };
   63 
   64 struct l_shm_info {
   65         l_int used_ids;
   66         l_ulong shm_tot;  /* total allocated shm */
   67         l_ulong shm_rss;  /* total resident shm */
   68         l_ulong shm_swp;  /* total swapped shm */
   69         l_ulong swap_attempts;
   70         l_ulong swap_successes;
   71 };
   72 
   73 struct l_ipc_perm {
   74         l_key_t         key;
   75         l_uid16_t       uid;
   76         l_gid16_t       gid;
   77         l_uid16_t       cuid;
   78         l_gid16_t       cgid;
   79         l_ushort        mode;
   80         l_ushort        seq;
   81 };
   82 
   83 static void
   84 linux_to_bsd_ipc_perm(struct l_ipc_perm *lpp, struct ipc_perm *bpp)
   85 {
   86     bpp->key = lpp->key;
   87     bpp->uid = lpp->uid;
   88     bpp->gid = lpp->gid;
   89     bpp->cuid = lpp->cuid;
   90     bpp->cgid = lpp->cgid;
   91     bpp->mode = lpp->mode;
   92     bpp->seq = lpp->seq;
   93 }
   94 
   95 
   96 static void
   97 bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct l_ipc_perm *lpp)
   98 {
   99     lpp->key = bpp->key;
  100     lpp->uid = bpp->uid;
  101     lpp->gid = bpp->gid;
  102     lpp->cuid = bpp->cuid;
  103     lpp->cgid = bpp->cgid;
  104     lpp->mode = bpp->mode;
  105     lpp->seq = bpp->seq;
  106 }
  107 
  108 struct l_semid_ds {
  109         struct l_ipc_perm       sem_perm;
  110         l_time_t                sem_otime;
  111         l_time_t                sem_ctime;
  112         void                    *sem_base;
  113         void                    *sem_pending;
  114         void                    *sem_pending_last;
  115         void                    *undo;
  116         l_ushort                sem_nsems;
  117 };
  118 
  119 struct l_shmid_ds {
  120         struct l_ipc_perm       shm_perm;
  121         l_int                   shm_segsz;
  122         l_time_t                shm_atime;
  123         l_time_t                shm_dtime;
  124         l_time_t                shm_ctime;
  125         l_ushort                shm_cpid;
  126         l_ushort                shm_lpid;
  127         l_short                 shm_nattch;
  128         l_ushort                private1;
  129         void                    *private2;
  130         void                    *private3;
  131 };
  132 
  133 static void
  134 linux_to_bsd_semid_ds(struct l_semid_ds *lsp, struct semid_ds *bsp)
  135 {
  136     linux_to_bsd_ipc_perm(&lsp->sem_perm, &bsp->sem_perm);
  137     bsp->sem_otime = lsp->sem_otime;
  138     bsp->sem_ctime = lsp->sem_ctime;
  139     bsp->sem_nsems = lsp->sem_nsems;
  140     bsp->sem_base = lsp->sem_base;
  141 }
  142 
  143 static void
  144 bsd_to_linux_semid_ds(struct semid_ds *bsp, struct l_semid_ds *lsp)
  145 {
  146         bsd_to_linux_ipc_perm(&bsp->sem_perm, &lsp->sem_perm);
  147         lsp->sem_otime = bsp->sem_otime;
  148         lsp->sem_ctime = bsp->sem_ctime;
  149         lsp->sem_nsems = bsp->sem_nsems;
  150         lsp->sem_base = bsp->sem_base;
  151 }
  152 
  153 static void
  154 linux_to_bsd_shmid_ds(struct l_shmid_ds *lsp, struct shmid_ds *bsp)
  155 {
  156     linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
  157     bsp->shm_segsz = lsp->shm_segsz;
  158     bsp->shm_lpid = lsp->shm_lpid;
  159     bsp->shm_cpid = lsp->shm_cpid;
  160     bsp->shm_nattch = lsp->shm_nattch;
  161     bsp->shm_atime = lsp->shm_atime;
  162     bsp->shm_dtime = lsp->shm_dtime;
  163     bsp->shm_ctime = lsp->shm_ctime;
  164     bsp->shm_internal = lsp->private3;  /* this goes (yet) SOS */
  165 }
  166 
  167 static void
  168 bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp)
  169 {
  170     bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
  171     lsp->shm_segsz = bsp->shm_segsz;
  172     lsp->shm_lpid = bsp->shm_lpid;
  173     lsp->shm_cpid = bsp->shm_cpid;
  174     lsp->shm_nattch = bsp->shm_nattch;
  175     lsp->shm_atime = bsp->shm_atime;
  176     lsp->shm_dtime = bsp->shm_dtime;
  177     lsp->shm_ctime = bsp->shm_ctime;
  178     lsp->private3 = bsp->shm_internal;  /* this goes (yet) SOS */
  179 }
  180 
  181 int
  182 linux_semop(struct proc *p, struct linux_semop_args *args)
  183 {
  184         struct semop_args /* {
  185         int     semid;
  186         struct  sembuf *sops;
  187         int             nsops;
  188         } */ bsd_args;
  189 
  190         bsd_args.semid = args->semid;
  191         bsd_args.sops = (struct sembuf *)args->tsops;
  192         bsd_args.nsops = args->nsops;
  193         return semop(p, &bsd_args);
  194 }
  195 
  196 int
  197 linux_semget(struct proc *p, struct linux_semget_args *args)
  198 {
  199         struct semget_args /* {
  200         key_t   key;
  201         int             nsems;
  202         int             semflg;
  203         } */ bsd_args;
  204 
  205         bsd_args.key = args->key;
  206         bsd_args.nsems = args->nsems;
  207         bsd_args.semflg = args->semflg;
  208         return semget(p, &bsd_args);
  209 }
  210 
  211 int
  212 linux_semctl(struct proc *p, struct linux_semctl_args *args)
  213 {
  214         struct l_semid_ds linux_semid;
  215         struct __semctl_args /* {
  216                 int             semid;
  217                 int             semnum;
  218                 int             cmd;
  219                 union semun     *arg;
  220         } */ bsd_args;
  221         struct l_seminfo linux_seminfo;
  222         int error;
  223         union semun *unptr;
  224         caddr_t sg;
  225 
  226         sg = stackgap_init();
  227 
  228         /* Make sure the arg parameter can be copied in. */
  229         unptr = stackgap_alloc(&sg, sizeof(union semun));
  230         bcopy(&args->arg, unptr, sizeof(union semun));
  231 
  232         bsd_args.semid = args->semid;
  233         bsd_args.semnum = args->semnum;
  234         bsd_args.arg = unptr;
  235 
  236         switch (args->cmd) {
  237         case LINUX_IPC_RMID:
  238                 bsd_args.cmd = IPC_RMID;
  239                 break;
  240         case LINUX_GETNCNT:
  241                 bsd_args.cmd = GETNCNT;
  242                 break;
  243         case LINUX_GETPID:
  244                 bsd_args.cmd = GETPID;
  245                 break;
  246         case LINUX_GETVAL:
  247                 bsd_args.cmd = GETVAL;
  248                 break;
  249         case LINUX_GETZCNT:
  250                 bsd_args.cmd = GETZCNT;
  251                 break;
  252         case LINUX_SETVAL:
  253                 bsd_args.cmd = SETVAL;
  254                 break;
  255         case LINUX_IPC_SET:
  256                 bsd_args.cmd = IPC_SET;
  257                 error = copyin((caddr_t)args->arg.buf, &linux_semid,
  258                     sizeof(linux_semid));
  259                 if (error)
  260                         return (error);
  261                 unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds));
  262                 linux_to_bsd_semid_ds(&linux_semid, unptr->buf);
  263                 return __semctl(p, &bsd_args);
  264         case LINUX_IPC_STAT:
  265                 bsd_args.cmd = IPC_STAT;
  266                 unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds));
  267                 error = __semctl(p, &bsd_args);
  268                 if (error)
  269                         return error;
  270                 p->p_retval[0] = IXSEQ_TO_IPCID(bsd_args.semid, 
  271                                                         unptr->buf->sem_perm);
  272                 bsd_to_linux_semid_ds(unptr->buf, &linux_semid);
  273                 return copyout(&linux_semid, (caddr_t)args->arg.buf,
  274                                             sizeof(linux_semid));
  275         case LINUX_IPC_INFO:
  276         case LINUX_SEM_INFO:
  277                 error = copyin((caddr_t)args->arg.buf, &linux_seminfo, 
  278                                                 sizeof(linux_seminfo) );
  279                 if (error)
  280                         return error;
  281                 bcopy(&seminfo, &linux_seminfo, sizeof(linux_seminfo) );
  282 /* XXX BSD equivalent?
  283 #define used_semids 10
  284 #define used_sems 10
  285                 linux_seminfo.semusz = used_semids;
  286                 linux_seminfo.semaem = used_sems;
  287 */
  288                 error = copyout((caddr_t)&linux_seminfo, (caddr_t)args->arg.buf,
  289                                                 sizeof(linux_seminfo) );
  290                 if (error)
  291                         return error;
  292                 p->p_retval[0] = seminfo.semmni;
  293                 return 0;                       /* No need for __semctl call */
  294         case LINUX_GETALL:
  295                 /* FALLTHROUGH */
  296         case LINUX_SETALL:
  297                 /* FALLTHROUGH */
  298         default:
  299                 uprintf("linux: 'ipc' typ=%d not implemented\n", args->cmd);
  300                 return EINVAL;
  301         }
  302         return __semctl(p, &bsd_args);
  303 }
  304 
  305 int
  306 linux_msgsnd(struct proc *p, struct linux_msgsnd_args *args)
  307 {
  308     struct msgsnd_args /* {
  309         int     msqid;   
  310         void    *msgp;   
  311         size_t  msgsz;   
  312         int     msgflg; 
  313     } */ bsd_args;
  314 
  315     bsd_args.msqid = args->msqid;
  316     bsd_args.msgp = args->msgp;
  317     bsd_args.msgsz = args->msgsz;
  318     bsd_args.msgflg = args->msgflg;
  319     return msgsnd(p, &bsd_args);
  320 }
  321 
  322 int
  323 linux_msgrcv(struct proc *p, struct linux_msgrcv_args *args)
  324 {
  325     struct msgrcv_args /* {     
  326         int     msqid;   
  327         void    *msgp;   
  328         size_t  msgsz;   
  329         long    msgtyp; 
  330         int     msgflg; 
  331     } */ bsd_args; 
  332 
  333     bsd_args.msqid = args->msqid;
  334     bsd_args.msgp = args->msgp;
  335     bsd_args.msgsz = args->msgsz;
  336     bsd_args.msgtyp = 0; /* XXX - args->msgtyp; */
  337     bsd_args.msgflg = args->msgflg;
  338     return msgrcv(p, &bsd_args);
  339 }
  340 
  341 int
  342 linux_msgget(struct proc *p, struct linux_msgget_args *args)
  343 {
  344     struct msgget_args /* {
  345         key_t   key;
  346         int     msgflg;
  347     } */ bsd_args;
  348 
  349     bsd_args.key = args->key;
  350     bsd_args.msgflg = args->msgflg;
  351     return msgget(p, &bsd_args);
  352 }
  353 
  354 int
  355 linux_msgctl(struct proc *p, struct linux_msgctl_args *args)
  356 {
  357     struct msgctl_args /* {
  358         int     msqid; 
  359         int     cmd;
  360         struct  msqid_ds *buf;
  361     } */ bsd_args;
  362     int error;
  363 
  364     bsd_args.msqid = args->msqid;
  365     bsd_args.cmd = args->cmd;
  366     bsd_args.buf = (struct msqid_ds *)args->buf;
  367     error = msgctl(p, &bsd_args);
  368     return ((args->cmd == LINUX_IPC_RMID && error == EINVAL) ? 0 : error);
  369 }
  370 
  371 int
  372 linux_shmat(struct proc *p, struct linux_shmat_args *args)
  373 {
  374     struct shmat_args /* {
  375         int shmid;
  376         void *shmaddr;
  377         int shmflg;
  378     } */ bsd_args;
  379     int error;
  380 
  381     bsd_args.shmid = args->shmid;
  382     bsd_args.shmaddr = args->shmaddr;
  383     bsd_args.shmflg = args->shmflg;
  384     if ((error = shmat(p, &bsd_args)))
  385         return error;
  386 #ifdef __i386__
  387     if ((error = copyout(p->p_retval, (caddr_t)args->raddr, sizeof(l_ulong))))
  388         return error;
  389     p->p_retval[0] = 0;
  390 #endif
  391     return 0;
  392 }
  393 
  394 int
  395 linux_shmdt(struct proc *p, struct linux_shmdt_args *args)
  396 {
  397     struct shmdt_args /* {
  398         void *shmaddr;
  399     } */ bsd_args;
  400 
  401     bsd_args.shmaddr = args->shmaddr;
  402     return shmdt(p, &bsd_args);
  403 }
  404 
  405 int
  406 linux_shmget(struct proc *p, struct linux_shmget_args *args)
  407 {
  408     struct shmget_args /* {
  409         key_t key;
  410         int size;
  411         int shmflg;
  412     } */ bsd_args;
  413 
  414     bsd_args.key = args->key;
  415     bsd_args.size = args->size;
  416     bsd_args.shmflg = args->shmflg;
  417     return shmget(p, &bsd_args);
  418 }
  419 
  420 int
  421 linux_shmctl(struct proc *p, struct linux_shmctl_args *args)
  422 {
  423     struct l_shmid_ds linux_shmid;
  424     struct shmctl_args /* {
  425         int shmid;
  426         int cmd;
  427         struct shmid_ds *buf;
  428     } */ bsd_args;
  429     int error;
  430     caddr_t sg = stackgap_init();
  431 
  432     switch (args->cmd) {
  433     case LINUX_IPC_STAT:
  434         bsd_args.shmid = args->shmid;
  435         bsd_args.cmd = IPC_STAT;
  436         bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  437         if ((error = shmctl(p, &bsd_args)))
  438             return error;
  439         bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid);
  440         return copyout(&linux_shmid, (caddr_t)args->buf, sizeof(linux_shmid));
  441 
  442     case LINUX_IPC_SET:
  443         if ((error = copyin((caddr_t)args->buf, &linux_shmid,
  444                 sizeof(linux_shmid))))
  445             return error;
  446         bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  447         linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf);
  448         bsd_args.shmid = args->shmid;
  449         bsd_args.cmd = IPC_SET;
  450         return shmctl(p, &bsd_args);
  451 
  452     case LINUX_IPC_RMID:
  453         bsd_args.shmid = args->shmid;
  454         bsd_args.cmd = IPC_RMID;
  455         if (args->buf == NULL)
  456             bsd_args.buf = NULL;
  457         else {
  458             if ((error = copyin((caddr_t)args->buf, &linux_shmid, 
  459                                 sizeof(linux_shmid))))
  460                 return error;
  461             bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
  462             linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf);
  463         }
  464         return shmctl(p, &bsd_args);
  465 
  466     case LINUX_IPC_INFO:
  467     case LINUX_SHM_STAT:
  468     case LINUX_SHM_INFO:
  469     case LINUX_SHM_LOCK:
  470     case LINUX_SHM_UNLOCK:
  471     default:
  472         uprintf("linux: 'ipc' typ=%d not implemented\n", args->cmd);
  473         return EINVAL;
  474     }
  475 }

Cache object: 41316a2d0744938e8b0608bbb7aa1d26


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