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_ipccall.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_ipccall.c,v 1.31 2008/04/28 20:23:43 martin Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: linux_ipccall.c,v 1.31 2008/04/28 20:23:43 martin Exp $");
   34 
   35 #if defined(_KERNEL_OPT)
   36 #include "opt_sysv.h"
   37 #endif
   38 
   39 #include <sys/param.h>
   40 #include <sys/shm.h>
   41 #include <sys/sem.h>
   42 #include <sys/msg.h>
   43 #include <sys/proc.h>
   44 #include <sys/systm.h>
   45 
   46 /* real syscalls */
   47 #include <sys/mount.h>
   48 #include <sys/syscallargs.h>
   49 
   50 /* sys_ipc + args prototype */
   51 #include <compat/linux/common/linux_types.h>
   52 #include <compat/linux/common/linux_signal.h>
   53 
   54 #include <compat/linux/linux_syscallargs.h>
   55 #include <compat/linux/linux_syscall.h>
   56 
   57 /* general ipc defines */
   58 #include <compat/linux/common/linux_ipc.h>
   59 
   60 /* prototypes for real/normal linux-emul syscalls */
   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 /* prototypes for sys_ipc stuff */
   66 #include <compat/linux/common/linux_ipccall.h>
   67 
   68 /* Used on: arm, i386, m68k, mips, ppc, sparc, sparc64 */
   69 /* Not used on: alpha */
   70 
   71 /*
   72  * Stuff to deal with the SysV ipc/shm/semaphore interface in Linux.
   73  * The main difference is, that Linux handles it all via one
   74  * system call, which has the usual maximum amount of 5 arguments.
   75  * This results in a kludge for calls that take 6 of them.
   76  *
   77  * The SYSV??? options have to be enabled to get the appropriate
   78  * functions to work.
   79  */
   80 
   81 int
   82 linux_sys_ipc(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
   83 {
   84         /* {
   85                 syscallarg(int) what;
   86                 syscallarg(int) a1;
   87                 syscallarg(int) a2;
   88                 syscallarg(int) a3;
   89                 syscallarg(void *) ptr;
   90         } */
   91 
   92         switch (SCARG(uap, what)) {
   93 #ifdef SYSVSEM
   94         case LINUX_SYS_semop:
   95                 return linux_semop(l, uap, retval);
   96         case LINUX_SYS_semget:
   97                 return linux_semget(l, uap, retval);
   98         case LINUX_SYS_semctl: {
   99                 struct linux_sys_semctl_args bsa;
  100                 union linux_semun arg;
  101                 int error;
  102 
  103                 SCARG(&bsa, semid) = SCARG(uap, a1);
  104                 SCARG(&bsa, semnum) = SCARG(uap, a2);
  105                 SCARG(&bsa, cmd) = SCARG(uap, a3);
  106                 /* Convert from (union linux_semun *) to (union linux_semun) */
  107                 if ((error = copyin(SCARG(uap, ptr), &arg, sizeof arg)))
  108                         return error;
  109                 SCARG(&bsa, arg) = arg;
  110 
  111                 return linux_sys_semctl(l, &bsa, retval);
  112             }
  113 #endif
  114 #ifdef SYSVMSG
  115         case LINUX_SYS_msgsnd:
  116                 return linux_msgsnd(l, uap, retval);
  117         case LINUX_SYS_msgrcv:
  118                 return linux_msgrcv(l, uap, retval);
  119         case LINUX_SYS_msgget:
  120                 return linux_msgget(l, uap, retval);
  121         case LINUX_SYS_msgctl: {
  122                 struct linux_sys_msgctl_args bsa;
  123 
  124                 SCARG(&bsa, msqid) = SCARG(uap, a1);
  125                 SCARG(&bsa, cmd) = SCARG(uap, a2);
  126                 SCARG(&bsa, buf) = (struct linux_msqid_ds *)SCARG(uap, ptr);
  127 
  128                 return linux_sys_msgctl(l, &bsa, retval);
  129             }
  130 #endif
  131 #ifdef SYSVSHM
  132         case LINUX_SYS_shmat: {
  133                 struct linux_sys_shmat_args bsa;
  134 
  135                 SCARG(&bsa, shmid) = SCARG(uap, a1);
  136                 SCARG(&bsa, shmaddr) = (void *)SCARG(uap, ptr);
  137                 SCARG(&bsa, shmflg) = SCARG(uap, a2);
  138                 /* XXX passing pointer inside int here */
  139                 SCARG(&bsa, raddr) = (u_long *)SCARG(uap, a3);
  140 
  141                 return linux_sys_shmat(l, &bsa, retval);
  142             }
  143         case LINUX_SYS_shmdt:
  144                 return linux_shmdt(l, uap, retval);
  145         case LINUX_SYS_shmget:
  146                 return linux_shmget(l, uap, retval);
  147         case LINUX_SYS_shmctl: {
  148                 struct linux_sys_shmctl_args bsa;
  149 
  150                 SCARG(&bsa, shmid) = SCARG(uap, a1);
  151                 SCARG(&bsa, cmd) = SCARG(uap, a2);
  152                 SCARG(&bsa, buf) = (struct linux_shmid_ds *)SCARG(uap, ptr);
  153 
  154                 return linux_sys_shmctl(l, &bsa, retval);
  155             }
  156 #endif
  157         default:
  158                 return ENOSYS;
  159         }
  160 }
  161 
  162 #ifdef SYSVSEM
  163 inline int
  164 linux_semop(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  165 {
  166         /* {
  167                 syscallarg(int) what;
  168                 syscallarg(int) a1;
  169                 syscallarg(int) a2;
  170                 syscallarg(int) a3;
  171                 syscallarg(void *) ptr;
  172         } */
  173         struct sys_semop_args bsa;
  174 
  175         SCARG(&bsa, semid) = SCARG(uap, a1);
  176         SCARG(&bsa, sops) = (struct sembuf *)SCARG(uap, ptr);
  177         SCARG(&bsa, nsops) = SCARG(uap, a2);
  178 
  179         return sys_semop(l, &bsa, retval);
  180 }
  181 
  182 inline int
  183 linux_semget(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  184 {
  185         /* {
  186                 syscallarg(int) what;
  187                 syscallarg(int) a1;
  188                 syscallarg(int) a2;
  189                 syscallarg(int) a3;
  190                 syscallarg(void *) ptr;
  191         } */
  192         struct sys_semget_args bsa;
  193 
  194         SCARG(&bsa, key) = (key_t)SCARG(uap, a1);
  195         SCARG(&bsa, nsems) = SCARG(uap, a2);
  196         SCARG(&bsa, semflg) = SCARG(uap, a3);
  197 
  198         return sys_semget(l, &bsa, retval);
  199 }
  200 
  201 #endif /* SYSVSEM */
  202 
  203 #ifdef SYSVMSG
  204 
  205 inline int
  206 linux_msgsnd(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  207 {
  208         struct sys_msgsnd_args bma;
  209 
  210         SCARG(&bma, msqid) = SCARG(uap, a1);
  211         SCARG(&bma, msgp) = SCARG(uap, ptr);
  212         SCARG(&bma, msgsz) = SCARG(uap, a2);
  213         SCARG(&bma, msgflg) = SCARG(uap, a3);
  214 
  215         return sys_msgsnd(l, &bma, retval);
  216 }
  217 
  218 inline int
  219 linux_msgrcv(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  220 {
  221         struct sys_msgrcv_args bma;
  222         struct linux_msgrcv_msgarg kluge;
  223         int error;
  224 
  225         if ((error = copyin(SCARG(uap, ptr), &kluge, sizeof kluge)))
  226                 return error;
  227 
  228         SCARG(&bma, msqid) = SCARG(uap, a1);
  229         SCARG(&bma, msgp) = kluge.msg;
  230         SCARG(&bma, msgsz) = SCARG(uap, a2);
  231         SCARG(&bma, msgtyp) = kluge.type;
  232         SCARG(&bma, msgflg) = SCARG(uap, a3);
  233 
  234         return sys_msgrcv(l, &bma, retval);
  235 }
  236 
  237 inline int
  238 linux_msgget(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  239 {
  240         struct sys_msgget_args bma;
  241 
  242         SCARG(&bma, key) = (key_t)SCARG(uap, a1);
  243         SCARG(&bma, msgflg) = SCARG(uap, a2);
  244 
  245         return sys_msgget(l, &bma, retval);
  246 }
  247 
  248 #endif /* SYSVMSG */
  249 
  250 #ifdef SYSVSHM
  251 /*
  252  * shmdt(): this could have been mapped directly, if it wasn't for
  253  * the extra indirection by the linux_ipc system call.
  254  */
  255 inline int
  256 linux_shmdt(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  257 {
  258         struct sys_shmdt_args bsa;
  259 
  260         SCARG(&bsa, shmaddr) = SCARG(uap, ptr);
  261 
  262         return sys_shmdt(l, &bsa, retval);
  263 }
  264 
  265 /*
  266  * Same story as shmdt.
  267  */
  268 inline int
  269 linux_shmget(struct lwp *l, const struct linux_sys_ipc_args *uap, register_t *retval)
  270 {
  271         struct linux_sys_shmget_args bsa;
  272 
  273         SCARG(&bsa, key) = SCARG(uap, a1);
  274         SCARG(&bsa, size) = SCARG(uap, a2);
  275         SCARG(&bsa, shmflg) = SCARG(uap, a3);
  276 
  277         return linux_sys_shmget(l, &bsa, retval);
  278 }
  279 
  280 #endif /* SYSVSHM */

Cache object: e4080a026fab0e309eef70929610aec2


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