1c21dee17SSøren Schmidt /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
37f2d13d6SPedro F. Giffuni *
49a14aa01SUlrich Spörlein * Copyright (c) 1994-1995 Søren Schmidt
5c21dee17SSøren Schmidt * All rights reserved.
6c21dee17SSøren Schmidt *
7c21dee17SSøren Schmidt * Redistribution and use in source and binary forms, with or without
8c21dee17SSøren Schmidt * modification, are permitted provided that the following conditions
9c21dee17SSøren Schmidt * are met:
10c21dee17SSøren Schmidt * 1. Redistributions of source code must retain the above copyright
110ba1b365SEd Maste * notice, this list of conditions and the following disclaimer.
12c21dee17SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright
13c21dee17SSøren Schmidt * notice, this list of conditions and the following disclaimer in the
14c21dee17SSøren Schmidt * documentation and/or other materials provided with the distribution.
15c21dee17SSøren Schmidt *
160ba1b365SEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
170ba1b365SEd Maste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
180ba1b365SEd Maste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
190ba1b365SEd Maste * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
200ba1b365SEd Maste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
210ba1b365SEd Maste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
220ba1b365SEd Maste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
230ba1b365SEd Maste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
240ba1b365SEd Maste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
250ba1b365SEd Maste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
260ba1b365SEd Maste * SUCH DAMAGE.
27c21dee17SSøren Schmidt */
28c21dee17SSøren Schmidt
29c21dee17SSøren Schmidt #include <sys/param.h>
30104a9b7eSAlexander Kabaev #include <sys/limits.h>
313ad9c842SMaxim Sobolev #include <sys/msg.h>
32d8e53d94SDmitry Chagin #include <sys/proc.h>
339b86a416SKATO Takenori #include <sys/sem.h>
34c21dee17SSøren Schmidt #include <sys/shm.h>
35c10e04f5SDmitry Chagin #include <sys/stat.h>
36d8e53d94SDmitry Chagin #include <sys/syscallsubr.h>
37513eb69eSDmitry Chagin #include <sys/sysent.h>
38d8e53d94SDmitry Chagin #include <sys/sysproto.h>
39c21dee17SSøren Schmidt
401997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32
414af27623STim J. Robbins #include <machine/../linux32/linux.h>
424af27623STim J. Robbins #include <machine/../linux32/linux32_proto.h>
431997c537SDavid E. O'Brien #else
441997c537SDavid E. O'Brien #include <machine/../linux/linux.h>
451997c537SDavid E. O'Brien #include <machine/../linux/linux_proto.h>
464af27623STim J. Robbins #endif
47afa66fa8SMarcel Moolenaar #include <compat/linux/linux_ipc.h>
48ab60bc84SDmitry Chagin #include <compat/linux/linux_ipc64.h>
49c8a79231SDmitry Chagin #include <compat/linux/linux_time.h>
50afa66fa8SMarcel Moolenaar #include <compat/linux/linux_util.h>
51c21dee17SSøren Schmidt
52ab60bc84SDmitry Chagin /*
53ab60bc84SDmitry Chagin * old, pre 2.4 kernel
54ab60bc84SDmitry Chagin */
55ab60bc84SDmitry Chagin struct l_ipc_perm {
56ab60bc84SDmitry Chagin l_key_t key;
57ab60bc84SDmitry Chagin l_uid16_t uid;
58ab60bc84SDmitry Chagin l_gid16_t gid;
59ab60bc84SDmitry Chagin l_uid16_t cuid;
60ab60bc84SDmitry Chagin l_gid16_t cgid;
61ab60bc84SDmitry Chagin l_ushort mode;
62ab60bc84SDmitry Chagin l_ushort seq;
63ab60bc84SDmitry Chagin };
64ab60bc84SDmitry Chagin
65a6e5348eSMichael Reifenberger struct l_seminfo {
66a6e5348eSMichael Reifenberger l_int semmap;
67a6e5348eSMichael Reifenberger l_int semmni;
68a6e5348eSMichael Reifenberger l_int semmns;
69a6e5348eSMichael Reifenberger l_int semmnu;
70a6e5348eSMichael Reifenberger l_int semmsl;
71a6e5348eSMichael Reifenberger l_int semopm;
72a6e5348eSMichael Reifenberger l_int semume;
73a6e5348eSMichael Reifenberger l_int semusz;
74a6e5348eSMichael Reifenberger l_int semvmx;
75a6e5348eSMichael Reifenberger l_int semaem;
76a6e5348eSMichael Reifenberger };
77a6e5348eSMichael Reifenberger
78a6e5348eSMichael Reifenberger struct l_shminfo {
79a6e5348eSMichael Reifenberger l_int shmmax;
80a6e5348eSMichael Reifenberger l_int shmmin;
81a6e5348eSMichael Reifenberger l_int shmmni;
82a6e5348eSMichael Reifenberger l_int shmseg;
83a6e5348eSMichael Reifenberger l_int shmall;
84a6e5348eSMichael Reifenberger };
85a6e5348eSMichael Reifenberger
86a6e5348eSMichael Reifenberger struct l_shm_info {
87a6e5348eSMichael Reifenberger l_int used_ids;
88a6e5348eSMichael Reifenberger l_ulong shm_tot; /* total allocated shm */
89a6e5348eSMichael Reifenberger l_ulong shm_rss; /* total resident shm */
90a6e5348eSMichael Reifenberger l_ulong shm_swp; /* total swapped shm */
91a6e5348eSMichael Reifenberger l_ulong swap_attempts;
92a6e5348eSMichael Reifenberger l_ulong swap_successes;
93a6e5348eSMichael Reifenberger };
94a6e5348eSMichael Reifenberger
9534ec45feSJung-uk Kim struct l_msginfo {
9634ec45feSJung-uk Kim l_int msgpool;
9734ec45feSJung-uk Kim l_int msgmap;
9834ec45feSJung-uk Kim l_int msgmax;
9934ec45feSJung-uk Kim l_int msgmnb;
10034ec45feSJung-uk Kim l_int msgmni;
10134ec45feSJung-uk Kim l_int msgssz;
10234ec45feSJung-uk Kim l_int msgtql;
10334ec45feSJung-uk Kim l_ushort msgseg;
10434ec45feSJung-uk Kim };
10534ec45feSJung-uk Kim
106491dec93SMichael Reifenberger static void
bsd_to_linux_shminfo(struct shminfo * bpp,struct l_shminfo64 * lpp)107ab60bc84SDmitry Chagin bsd_to_linux_shminfo( struct shminfo *bpp, struct l_shminfo64 *lpp)
108491dec93SMichael Reifenberger {
10931f7ad15SDmitry Chagin
110491dec93SMichael Reifenberger lpp->shmmax = bpp->shmmax;
111491dec93SMichael Reifenberger lpp->shmmin = bpp->shmmin;
112491dec93SMichael Reifenberger lpp->shmmni = bpp->shmmni;
113491dec93SMichael Reifenberger lpp->shmseg = bpp->shmseg;
114491dec93SMichael Reifenberger lpp->shmall = bpp->shmall;
115491dec93SMichael Reifenberger }
116491dec93SMichael Reifenberger
117491dec93SMichael Reifenberger static void
bsd_to_linux_shm_info(struct shm_info * bpp,struct l_shm_info * lpp)118491dec93SMichael Reifenberger bsd_to_linux_shm_info( struct shm_info *bpp, struct l_shm_info *lpp)
119491dec93SMichael Reifenberger {
12031f7ad15SDmitry Chagin
121491dec93SMichael Reifenberger lpp->used_ids = bpp->used_ids;
122491dec93SMichael Reifenberger lpp->shm_tot = bpp->shm_tot;
123491dec93SMichael Reifenberger lpp->shm_rss = bpp->shm_rss;
124491dec93SMichael Reifenberger lpp->shm_swp = bpp->shm_swp;
125491dec93SMichael Reifenberger lpp->swap_attempts = bpp->swap_attempts;
126491dec93SMichael Reifenberger lpp->swap_successes = bpp->swap_successes;
127491dec93SMichael Reifenberger }
128491dec93SMichael Reifenberger
129c21dee17SSøren Schmidt static void
linux_to_bsd_ipc_perm(struct l_ipc64_perm * lpp,struct ipc_perm * bpp)130ab60bc84SDmitry Chagin linux_to_bsd_ipc_perm(struct l_ipc64_perm *lpp, struct ipc_perm *bpp)
131c21dee17SSøren Schmidt {
13231f7ad15SDmitry Chagin
133c21dee17SSøren Schmidt bpp->key = lpp->key;
134c21dee17SSøren Schmidt bpp->uid = lpp->uid;
135c21dee17SSøren Schmidt bpp->gid = lpp->gid;
136c21dee17SSøren Schmidt bpp->cuid = lpp->cuid;
137c21dee17SSøren Schmidt bpp->cgid = lpp->cgid;
138c21dee17SSøren Schmidt bpp->mode = lpp->mode;
139c21dee17SSøren Schmidt bpp->seq = lpp->seq;
140c21dee17SSøren Schmidt }
141c21dee17SSøren Schmidt
142c21dee17SSøren Schmidt static void
bsd_to_linux_ipc_perm(struct ipc_perm * bpp,struct l_ipc64_perm * lpp)143ab60bc84SDmitry Chagin bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct l_ipc64_perm *lpp)
144c21dee17SSøren Schmidt {
14531f7ad15SDmitry Chagin
146c21dee17SSøren Schmidt lpp->key = bpp->key;
147c21dee17SSøren Schmidt lpp->uid = bpp->uid;
148c21dee17SSøren Schmidt lpp->gid = bpp->gid;
149c21dee17SSøren Schmidt lpp->cuid = bpp->cuid;
150c21dee17SSøren Schmidt lpp->cgid = bpp->cgid;
151c10e04f5SDmitry Chagin lpp->mode = bpp->mode & (S_IRWXU|S_IRWXG|S_IRWXO);
152c21dee17SSøren Schmidt lpp->seq = bpp->seq;
153c21dee17SSøren Schmidt }
154c21dee17SSøren Schmidt
1553ad9c842SMaxim Sobolev struct l_msqid_ds {
1563ad9c842SMaxim Sobolev struct l_ipc_perm msg_perm;
1574af27623STim J. Robbins l_uintptr_t msg_first; /* first message on queue,unused */
1584af27623STim J. Robbins l_uintptr_t msg_last; /* last message in queue,unused */
1593ad9c842SMaxim Sobolev l_time_t msg_stime; /* last msgsnd time */
1603ad9c842SMaxim Sobolev l_time_t msg_rtime; /* last msgrcv time */
1613ad9c842SMaxim Sobolev l_time_t msg_ctime; /* last change time */
1623ad9c842SMaxim Sobolev l_ulong msg_lcbytes; /* Reuse junk fields for 32 bit */
1633ad9c842SMaxim Sobolev l_ulong msg_lqbytes; /* ditto */
1643ad9c842SMaxim Sobolev l_ushort msg_cbytes; /* current number of bytes on queue */
1653ad9c842SMaxim Sobolev l_ushort msg_qnum; /* number of messages in queue */
1663ad9c842SMaxim Sobolev l_ushort msg_qbytes; /* max number of bytes on queue */
1673ad9c842SMaxim Sobolev l_pid_t msg_lspid; /* pid of last msgsnd */
1683ad9c842SMaxim Sobolev l_pid_t msg_lrpid; /* last receive pid */
169e45e3698SDmitry Chagin };
1703ad9c842SMaxim Sobolev
1715002a60fSMarcel Moolenaar struct l_semid_ds {
1725002a60fSMarcel Moolenaar struct l_ipc_perm sem_perm;
1735002a60fSMarcel Moolenaar l_time_t sem_otime;
1745002a60fSMarcel Moolenaar l_time_t sem_ctime;
1754af27623STim J. Robbins l_uintptr_t sem_base;
1764af27623STim J. Robbins l_uintptr_t sem_pending;
1774af27623STim J. Robbins l_uintptr_t sem_pending_last;
1784af27623STim J. Robbins l_uintptr_t undo;
1795002a60fSMarcel Moolenaar l_ushort sem_nsems;
180e45e3698SDmitry Chagin };
1819b86a416SKATO Takenori
1825002a60fSMarcel Moolenaar struct l_shmid_ds {
1835002a60fSMarcel Moolenaar struct l_ipc_perm shm_perm;
1845002a60fSMarcel Moolenaar l_int shm_segsz;
1855002a60fSMarcel Moolenaar l_time_t shm_atime;
1865002a60fSMarcel Moolenaar l_time_t shm_dtime;
1875002a60fSMarcel Moolenaar l_time_t shm_ctime;
1885002a60fSMarcel Moolenaar l_ushort shm_cpid;
1895002a60fSMarcel Moolenaar l_ushort shm_lpid;
1905002a60fSMarcel Moolenaar l_short shm_nattch;
1915002a60fSMarcel Moolenaar l_ushort private1;
1924af27623STim J. Robbins l_uintptr_t private2;
1934af27623STim J. Robbins l_uintptr_t private3;
194c21dee17SSøren Schmidt };
195c21dee17SSøren Schmidt
196c21dee17SSøren Schmidt static void
linux_to_bsd_semid_ds(struct l_semid64_ds * lsp,struct semid_ds * bsp)197ab60bc84SDmitry Chagin linux_to_bsd_semid_ds(struct l_semid64_ds *lsp, struct semid_ds *bsp)
1989b86a416SKATO Takenori {
19931f7ad15SDmitry Chagin
2009b86a416SKATO Takenori linux_to_bsd_ipc_perm(&lsp->sem_perm, &bsp->sem_perm);
2019b86a416SKATO Takenori bsp->sem_otime = lsp->sem_otime;
2029b86a416SKATO Takenori bsp->sem_ctime = lsp->sem_ctime;
2039b86a416SKATO Takenori bsp->sem_nsems = lsp->sem_nsems;
2049b86a416SKATO Takenori }
2059b86a416SKATO Takenori
2069b86a416SKATO Takenori static void
bsd_to_linux_semid_ds(struct semid_ds * bsp,struct l_semid64_ds * lsp)207ab60bc84SDmitry Chagin bsd_to_linux_semid_ds(struct semid_ds *bsp, struct l_semid64_ds *lsp)
2089b86a416SKATO Takenori {
20931f7ad15SDmitry Chagin
2109b86a416SKATO Takenori bsd_to_linux_ipc_perm(&bsp->sem_perm, &lsp->sem_perm);
2119b86a416SKATO Takenori lsp->sem_otime = bsp->sem_otime;
2129b86a416SKATO Takenori lsp->sem_ctime = bsp->sem_ctime;
2139b86a416SKATO Takenori lsp->sem_nsems = bsp->sem_nsems;
2149b86a416SKATO Takenori }
2159b86a416SKATO Takenori
2169b86a416SKATO Takenori static void
linux_to_bsd_shmid_ds(struct l_shmid64_ds * lsp,struct shmid_ds * bsp)217ab60bc84SDmitry Chagin linux_to_bsd_shmid_ds(struct l_shmid64_ds *lsp, struct shmid_ds *bsp)
218c21dee17SSøren Schmidt {
21931f7ad15SDmitry Chagin
220c21dee17SSøren Schmidt linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
221c21dee17SSøren Schmidt bsp->shm_segsz = lsp->shm_segsz;
222c21dee17SSøren Schmidt bsp->shm_lpid = lsp->shm_lpid;
223c21dee17SSøren Schmidt bsp->shm_cpid = lsp->shm_cpid;
224c21dee17SSøren Schmidt bsp->shm_nattch = lsp->shm_nattch;
225c21dee17SSøren Schmidt bsp->shm_atime = lsp->shm_atime;
226c21dee17SSøren Schmidt bsp->shm_dtime = lsp->shm_dtime;
227c21dee17SSøren Schmidt bsp->shm_ctime = lsp->shm_ctime;
228c21dee17SSøren Schmidt }
229c21dee17SSøren Schmidt
230c21dee17SSøren Schmidt static void
bsd_to_linux_shmid_ds(struct shmid_ds * bsp,struct l_shmid64_ds * lsp)231ab60bc84SDmitry Chagin bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid64_ds *lsp)
232c21dee17SSøren Schmidt {
23331f7ad15SDmitry Chagin
234c21dee17SSøren Schmidt bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
235c21dee17SSøren Schmidt lsp->shm_segsz = bsp->shm_segsz;
236c21dee17SSøren Schmidt lsp->shm_lpid = bsp->shm_lpid;
237c21dee17SSøren Schmidt lsp->shm_cpid = bsp->shm_cpid;
238c21dee17SSøren Schmidt lsp->shm_nattch = bsp->shm_nattch;
239c21dee17SSøren Schmidt lsp->shm_atime = bsp->shm_atime;
240c21dee17SSøren Schmidt lsp->shm_dtime = bsp->shm_dtime;
241c21dee17SSøren Schmidt lsp->shm_ctime = bsp->shm_ctime;
242c21dee17SSøren Schmidt }
243c21dee17SSøren Schmidt
2443ad9c842SMaxim Sobolev static void
linux_to_bsd_msqid_ds(struct l_msqid64_ds * lsp,struct msqid_ds * bsp)245ab60bc84SDmitry Chagin linux_to_bsd_msqid_ds(struct l_msqid64_ds *lsp, struct msqid_ds *bsp)
2463ad9c842SMaxim Sobolev {
24731f7ad15SDmitry Chagin
2483ad9c842SMaxim Sobolev linux_to_bsd_ipc_perm(&lsp->msg_perm, &bsp->msg_perm);
2493ad9c842SMaxim Sobolev bsp->msg_cbytes = lsp->msg_cbytes;
2503ad9c842SMaxim Sobolev bsp->msg_qnum = lsp->msg_qnum;
2513ad9c842SMaxim Sobolev bsp->msg_qbytes = lsp->msg_qbytes;
2523ad9c842SMaxim Sobolev bsp->msg_lspid = lsp->msg_lspid;
2533ad9c842SMaxim Sobolev bsp->msg_lrpid = lsp->msg_lrpid;
2543ad9c842SMaxim Sobolev bsp->msg_stime = lsp->msg_stime;
2553ad9c842SMaxim Sobolev bsp->msg_rtime = lsp->msg_rtime;
2563ad9c842SMaxim Sobolev bsp->msg_ctime = lsp->msg_ctime;
2573ad9c842SMaxim Sobolev }
2583ad9c842SMaxim Sobolev
2593ad9c842SMaxim Sobolev static void
bsd_to_linux_msqid_ds(struct msqid_ds * bsp,struct l_msqid64_ds * lsp)260ab60bc84SDmitry Chagin bsd_to_linux_msqid_ds(struct msqid_ds *bsp, struct l_msqid64_ds *lsp)
2613ad9c842SMaxim Sobolev {
26231f7ad15SDmitry Chagin
2633ad9c842SMaxim Sobolev bsd_to_linux_ipc_perm(&bsp->msg_perm, &lsp->msg_perm);
2643ad9c842SMaxim Sobolev lsp->msg_cbytes = bsp->msg_cbytes;
2653ad9c842SMaxim Sobolev lsp->msg_qnum = bsp->msg_qnum;
2663ad9c842SMaxim Sobolev lsp->msg_qbytes = bsp->msg_qbytes;
2673ad9c842SMaxim Sobolev lsp->msg_lspid = bsp->msg_lspid;
2683ad9c842SMaxim Sobolev lsp->msg_lrpid = bsp->msg_lrpid;
2693ad9c842SMaxim Sobolev lsp->msg_stime = bsp->msg_stime;
2703ad9c842SMaxim Sobolev lsp->msg_rtime = bsp->msg_rtime;
2713ad9c842SMaxim Sobolev lsp->msg_ctime = bsp->msg_ctime;
2723ad9c842SMaxim Sobolev }
2733ad9c842SMaxim Sobolev
274ab60bc84SDmitry Chagin static int
linux_ipc64_perm_to_ipc_perm(struct l_ipc64_perm * in,struct l_ipc_perm * out)275ab60bc84SDmitry Chagin linux_ipc64_perm_to_ipc_perm(struct l_ipc64_perm *in, struct l_ipc_perm *out)
2763ad9c842SMaxim Sobolev {
2773ad9c842SMaxim Sobolev
2783ad9c842SMaxim Sobolev out->key = in->key;
2793ad9c842SMaxim Sobolev out->uid = in->uid;
2803ad9c842SMaxim Sobolev out->gid = in->gid;
2813ad9c842SMaxim Sobolev out->cuid = in->cuid;
2823ad9c842SMaxim Sobolev out->cgid = in->cgid;
2833ad9c842SMaxim Sobolev out->mode = in->mode;
2843ad9c842SMaxim Sobolev out->seq = in->seq;
285ab60bc84SDmitry Chagin
286ab60bc84SDmitry Chagin /* Linux does not check overflow */
287ab60bc84SDmitry Chagin if (out->uid != in->uid || out->gid != in->gid ||
288ab60bc84SDmitry Chagin out->cuid != in->cuid || out->cgid != in->cgid ||
289ab60bc84SDmitry Chagin out->mode != in->mode)
290ab60bc84SDmitry Chagin return (EOVERFLOW);
291ab60bc84SDmitry Chagin else
292ab60bc84SDmitry Chagin return (0);
2933ad9c842SMaxim Sobolev }
2943ad9c842SMaxim Sobolev
2953ad9c842SMaxim Sobolev static int
linux_msqid_pullup(l_int ver,struct l_msqid64_ds * linux_msqid64,caddr_t uaddr)296ab60bc84SDmitry Chagin linux_msqid_pullup(l_int ver, struct l_msqid64_ds *linux_msqid64, caddr_t uaddr)
2973ad9c842SMaxim Sobolev {
298ab60bc84SDmitry Chagin struct l_msqid_ds linux_msqid;
2993ad9c842SMaxim Sobolev int error;
3003ad9c842SMaxim Sobolev
301ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
302ab60bc84SDmitry Chagin return (copyin(uaddr, linux_msqid64, sizeof(*linux_msqid64)));
303eb089321SDmitry Chagin
304ab60bc84SDmitry Chagin error = copyin(uaddr, &linux_msqid, sizeof(linux_msqid));
3053ad9c842SMaxim Sobolev if (error != 0)
3063ad9c842SMaxim Sobolev return (error);
3073ad9c842SMaxim Sobolev
308ab60bc84SDmitry Chagin bzero(linux_msqid64, sizeof(*linux_msqid64));
309ab60bc84SDmitry Chagin linux_msqid64->msg_perm.uid = linux_msqid.msg_perm.uid;
310ab60bc84SDmitry Chagin linux_msqid64->msg_perm.gid = linux_msqid.msg_perm.gid;
311ab60bc84SDmitry Chagin linux_msqid64->msg_perm.mode = linux_msqid.msg_perm.mode;
312ab60bc84SDmitry Chagin if (linux_msqid.msg_qbytes == 0)
313ab60bc84SDmitry Chagin linux_msqid64->msg_qbytes = linux_msqid.msg_lqbytes;
3143ad9c842SMaxim Sobolev else
315ab60bc84SDmitry Chagin linux_msqid64->msg_qbytes = linux_msqid.msg_qbytes;
316ab60bc84SDmitry Chagin return (0);
317ab60bc84SDmitry Chagin }
3183ad9c842SMaxim Sobolev
3193ad9c842SMaxim Sobolev static int
linux_msqid_pushdown(l_int ver,struct l_msqid64_ds * linux_msqid64,caddr_t uaddr)320ab60bc84SDmitry Chagin linux_msqid_pushdown(l_int ver, struct l_msqid64_ds *linux_msqid64, caddr_t uaddr)
3213ad9c842SMaxim Sobolev {
322ab60bc84SDmitry Chagin struct l_msqid_ds linux_msqid;
3233ad9c842SMaxim Sobolev int error;
3243ad9c842SMaxim Sobolev
325ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
326ab60bc84SDmitry Chagin return (copyout(linux_msqid64, uaddr, sizeof(*linux_msqid64)));
327ab60bc84SDmitry Chagin
328eb089321SDmitry Chagin bzero(&linux_msqid, sizeof(linux_msqid));
329ab60bc84SDmitry Chagin error = linux_ipc64_perm_to_ipc_perm(&linux_msqid64->msg_perm,
330ab60bc84SDmitry Chagin &linux_msqid.msg_perm);
3313ad9c842SMaxim Sobolev if (error != 0)
3323ad9c842SMaxim Sobolev return (error);
3333ad9c842SMaxim Sobolev
334ab60bc84SDmitry Chagin linux_msqid.msg_stime = linux_msqid64->msg_stime;
335ab60bc84SDmitry Chagin linux_msqid.msg_rtime = linux_msqid64->msg_rtime;
336ab60bc84SDmitry Chagin linux_msqid.msg_ctime = linux_msqid64->msg_ctime;
3373ad9c842SMaxim Sobolev
338ab60bc84SDmitry Chagin if (linux_msqid64->msg_cbytes > USHRT_MAX)
339ab60bc84SDmitry Chagin linux_msqid.msg_cbytes = USHRT_MAX;
340ab60bc84SDmitry Chagin else
341ab60bc84SDmitry Chagin linux_msqid.msg_cbytes = linux_msqid64->msg_cbytes;
342ab60bc84SDmitry Chagin linux_msqid.msg_lcbytes = linux_msqid64->msg_cbytes;
343ab60bc84SDmitry Chagin if (linux_msqid64->msg_qnum > USHRT_MAX)
344c6950243SDmitry Chagin linux_msqid.msg_qnum = USHRT_MAX;
345ab60bc84SDmitry Chagin else
346ab60bc84SDmitry Chagin linux_msqid.msg_qnum = linux_msqid64->msg_qnum;
347ab60bc84SDmitry Chagin if (linux_msqid64->msg_qbytes > USHRT_MAX)
348c6950243SDmitry Chagin linux_msqid.msg_qbytes = USHRT_MAX;
349ab60bc84SDmitry Chagin else
350ab60bc84SDmitry Chagin linux_msqid.msg_qbytes = linux_msqid64->msg_qbytes;
351ab60bc84SDmitry Chagin linux_msqid.msg_lqbytes = linux_msqid64->msg_qbytes;
352ab60bc84SDmitry Chagin linux_msqid.msg_lspid = linux_msqid64->msg_lspid;
353ab60bc84SDmitry Chagin linux_msqid.msg_lrpid = linux_msqid64->msg_lrpid;
35431f7ad15SDmitry Chagin
355ab60bc84SDmitry Chagin /* Linux does not check overflow */
356ab60bc84SDmitry Chagin if (linux_msqid.msg_stime != linux_msqid64->msg_stime ||
357ab60bc84SDmitry Chagin linux_msqid.msg_rtime != linux_msqid64->msg_rtime ||
358ab60bc84SDmitry Chagin linux_msqid.msg_ctime != linux_msqid64->msg_ctime)
359ab60bc84SDmitry Chagin return (EOVERFLOW);
360ab60bc84SDmitry Chagin return (copyout(&linux_msqid, uaddr, sizeof(linux_msqid)));
361ab60bc84SDmitry Chagin }
3623ad9c842SMaxim Sobolev
3633ad9c842SMaxim Sobolev static int
linux_semid_pullup(l_int ver,struct l_semid64_ds * linux_semid64,caddr_t uaddr)364ab60bc84SDmitry Chagin linux_semid_pullup(l_int ver, struct l_semid64_ds *linux_semid64, caddr_t uaddr)
3653ad9c842SMaxim Sobolev {
366ab60bc84SDmitry Chagin struct l_semid_ds linux_semid;
3673ad9c842SMaxim Sobolev int error;
3683ad9c842SMaxim Sobolev
369ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
370ab60bc84SDmitry Chagin return (copyin(uaddr, linux_semid64, sizeof(*linux_semid64)));
371ab60bc84SDmitry Chagin error = copyin(uaddr, &linux_semid, sizeof(linux_semid));
3723ad9c842SMaxim Sobolev if (error != 0)
3733ad9c842SMaxim Sobolev return (error);
3743ad9c842SMaxim Sobolev
375ab60bc84SDmitry Chagin bzero(linux_semid64, sizeof(*linux_semid64));
376ab60bc84SDmitry Chagin linux_semid64->sem_perm.uid = linux_semid.sem_perm.uid;
377ab60bc84SDmitry Chagin linux_semid64->sem_perm.gid = linux_semid.sem_perm.gid;
378ab60bc84SDmitry Chagin linux_semid64->sem_perm.mode = linux_semid.sem_perm.mode;
379ab60bc84SDmitry Chagin return (0);
380ab60bc84SDmitry Chagin }
3813ad9c842SMaxim Sobolev
3823ad9c842SMaxim Sobolev static int
linux_semid_pushdown(l_int ver,struct l_semid64_ds * linux_semid64,caddr_t uaddr)383ab60bc84SDmitry Chagin linux_semid_pushdown(l_int ver, struct l_semid64_ds *linux_semid64, caddr_t uaddr)
3843ad9c842SMaxim Sobolev {
385ab60bc84SDmitry Chagin struct l_semid_ds linux_semid;
386ab60bc84SDmitry Chagin int error;
3873ad9c842SMaxim Sobolev
388ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
389ab60bc84SDmitry Chagin return (copyout(linux_semid64, uaddr, sizeof(*linux_semid64)));
3903ad9c842SMaxim Sobolev
391eb089321SDmitry Chagin bzero(&linux_semid, sizeof(linux_semid));
392ab60bc84SDmitry Chagin error = linux_ipc64_perm_to_ipc_perm(&linux_semid64->sem_perm,
393ab60bc84SDmitry Chagin &linux_semid.sem_perm);
394ab60bc84SDmitry Chagin if (error != 0)
395ab60bc84SDmitry Chagin return (error);
3963ad9c842SMaxim Sobolev
397ab60bc84SDmitry Chagin linux_semid.sem_otime = linux_semid64->sem_otime;
398ab60bc84SDmitry Chagin linux_semid.sem_ctime = linux_semid64->sem_ctime;
399ab60bc84SDmitry Chagin linux_semid.sem_nsems = linux_semid64->sem_nsems;
4003ad9c842SMaxim Sobolev
401ab60bc84SDmitry Chagin /* Linux does not check overflow */
402ab60bc84SDmitry Chagin if (linux_semid.sem_otime != linux_semid64->sem_otime ||
403ab60bc84SDmitry Chagin linux_semid.sem_ctime != linux_semid64->sem_ctime ||
404ab60bc84SDmitry Chagin linux_semid.sem_nsems != linux_semid64->sem_nsems)
405ab60bc84SDmitry Chagin return (EOVERFLOW);
406ab60bc84SDmitry Chagin return (copyout(&linux_semid, uaddr, sizeof(linux_semid)));
407ab60bc84SDmitry Chagin }
4083ad9c842SMaxim Sobolev
4093ad9c842SMaxim Sobolev static int
linux_shmid_pullup(l_int ver,struct l_shmid64_ds * linux_shmid64,caddr_t uaddr)410ab60bc84SDmitry Chagin linux_shmid_pullup(l_int ver, struct l_shmid64_ds *linux_shmid64, caddr_t uaddr)
411ab60bc84SDmitry Chagin {
412ab60bc84SDmitry Chagin struct l_shmid_ds linux_shmid;
413ab60bc84SDmitry Chagin int error;
414ab60bc84SDmitry Chagin
415ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
416ab60bc84SDmitry Chagin return (copyin(uaddr, linux_shmid64, sizeof(*linux_shmid64)));
417eb089321SDmitry Chagin
418ab60bc84SDmitry Chagin error = copyin(uaddr, &linux_shmid, sizeof(linux_shmid));
419ab60bc84SDmitry Chagin if (error != 0)
420ab60bc84SDmitry Chagin return (error);
421ab60bc84SDmitry Chagin
422ab60bc84SDmitry Chagin bzero(linux_shmid64, sizeof(*linux_shmid64));
423ab60bc84SDmitry Chagin linux_shmid64->shm_perm.uid = linux_shmid.shm_perm.uid;
424ab60bc84SDmitry Chagin linux_shmid64->shm_perm.gid = linux_shmid.shm_perm.gid;
425ab60bc84SDmitry Chagin linux_shmid64->shm_perm.mode = linux_shmid.shm_perm.mode;
426ab60bc84SDmitry Chagin return (0);
427ab60bc84SDmitry Chagin }
428ab60bc84SDmitry Chagin
429ab60bc84SDmitry Chagin static int
linux_shmid_pushdown(l_int ver,struct l_shmid64_ds * linux_shmid64,caddr_t uaddr)430ab60bc84SDmitry Chagin linux_shmid_pushdown(l_int ver, struct l_shmid64_ds *linux_shmid64, caddr_t uaddr)
431ab60bc84SDmitry Chagin {
432ab60bc84SDmitry Chagin struct l_shmid_ds linux_shmid;
433ab60bc84SDmitry Chagin int error;
434ab60bc84SDmitry Chagin
435ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
436ab60bc84SDmitry Chagin return (copyout(linux_shmid64, uaddr, sizeof(*linux_shmid64)));
437ab60bc84SDmitry Chagin
438eb089321SDmitry Chagin bzero(&linux_shmid, sizeof(linux_shmid));
439ab60bc84SDmitry Chagin error = linux_ipc64_perm_to_ipc_perm(&linux_shmid64->shm_perm,
440ab60bc84SDmitry Chagin &linux_shmid.shm_perm);
441ab60bc84SDmitry Chagin if (error != 0)
442ab60bc84SDmitry Chagin return (error);
443ab60bc84SDmitry Chagin
444ab60bc84SDmitry Chagin linux_shmid.shm_segsz = linux_shmid64->shm_segsz;
445ab60bc84SDmitry Chagin linux_shmid.shm_atime = linux_shmid64->shm_atime;
446ab60bc84SDmitry Chagin linux_shmid.shm_dtime = linux_shmid64->shm_dtime;
447ab60bc84SDmitry Chagin linux_shmid.shm_ctime = linux_shmid64->shm_ctime;
448ab60bc84SDmitry Chagin linux_shmid.shm_cpid = linux_shmid64->shm_cpid;
449ab60bc84SDmitry Chagin linux_shmid.shm_lpid = linux_shmid64->shm_lpid;
450ab60bc84SDmitry Chagin linux_shmid.shm_nattch = linux_shmid64->shm_nattch;
451ab60bc84SDmitry Chagin
452ab60bc84SDmitry Chagin /* Linux does not check overflow */
453ab60bc84SDmitry Chagin if (linux_shmid.shm_segsz != linux_shmid64->shm_segsz ||
454ab60bc84SDmitry Chagin linux_shmid.shm_atime != linux_shmid64->shm_atime ||
455ab60bc84SDmitry Chagin linux_shmid.shm_dtime != linux_shmid64->shm_dtime ||
456ab60bc84SDmitry Chagin linux_shmid.shm_ctime != linux_shmid64->shm_ctime ||
457ab60bc84SDmitry Chagin linux_shmid.shm_cpid != linux_shmid64->shm_cpid ||
458ab60bc84SDmitry Chagin linux_shmid.shm_lpid != linux_shmid64->shm_lpid ||
459ab60bc84SDmitry Chagin linux_shmid.shm_nattch != linux_shmid64->shm_nattch)
460ab60bc84SDmitry Chagin return (EOVERFLOW);
461ab60bc84SDmitry Chagin return (copyout(&linux_shmid, uaddr, sizeof(linux_shmid)));
462ab60bc84SDmitry Chagin }
463ab60bc84SDmitry Chagin
464ab60bc84SDmitry Chagin static int
linux_shminfo_pushdown(l_int ver,struct l_shminfo64 * linux_shminfo64,caddr_t uaddr)465ab60bc84SDmitry Chagin linux_shminfo_pushdown(l_int ver, struct l_shminfo64 *linux_shminfo64,
4663ad9c842SMaxim Sobolev caddr_t uaddr)
4673ad9c842SMaxim Sobolev {
468ab60bc84SDmitry Chagin struct l_shminfo linux_shminfo;
4693ad9c842SMaxim Sobolev
470ab60bc84SDmitry Chagin if (ver == LINUX_IPC_64 || SV_CURPROC_FLAG(SV_LP64))
471ab60bc84SDmitry Chagin return (copyout(linux_shminfo64, uaddr,
472ab60bc84SDmitry Chagin sizeof(*linux_shminfo64)));
4733ad9c842SMaxim Sobolev
474eb089321SDmitry Chagin bzero(&linux_shminfo, sizeof(linux_shminfo));
475ab60bc84SDmitry Chagin linux_shminfo.shmmax = linux_shminfo64->shmmax;
476ab60bc84SDmitry Chagin linux_shminfo.shmmin = linux_shminfo64->shmmin;
477ab60bc84SDmitry Chagin linux_shminfo.shmmni = linux_shminfo64->shmmni;
478ab60bc84SDmitry Chagin linux_shminfo.shmseg = linux_shminfo64->shmseg;
479ab60bc84SDmitry Chagin linux_shminfo.shmall = linux_shminfo64->shmall;
480eb089321SDmitry Chagin return (copyout(&linux_shminfo, uaddr, sizeof(linux_shminfo)));
4813ad9c842SMaxim Sobolev }
4823ad9c842SMaxim Sobolev
4833245a2ecSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
4843245a2ecSDmitry Chagin int
linux_semtimedop_time64(struct thread * td,struct linux_semtimedop_time64_args * args)4853245a2ecSDmitry Chagin linux_semtimedop_time64(struct thread *td, struct linux_semtimedop_time64_args *args)
4863245a2ecSDmitry Chagin {
4873245a2ecSDmitry Chagin struct timespec ts, *tsa;
4883245a2ecSDmitry Chagin int error;
4893245a2ecSDmitry Chagin
4903245a2ecSDmitry Chagin if (args->timeout) {
491707e567aSDmitry Chagin error = linux_get_timespec64(&ts, args->timeout);
4923245a2ecSDmitry Chagin if (error != 0)
4933245a2ecSDmitry Chagin return (error);
4943245a2ecSDmitry Chagin tsa = &ts;
4953245a2ecSDmitry Chagin } else
4963245a2ecSDmitry Chagin tsa = NULL;
4973245a2ecSDmitry Chagin
4983245a2ecSDmitry Chagin return (kern_semop(td, args->semid, PTRIN(args->tsops),
4993245a2ecSDmitry Chagin args->nsops, tsa));
5003245a2ecSDmitry Chagin }
5013245a2ecSDmitry Chagin #endif /* __i386__) || (__amd64__ && COMPAT_LINUX32) */
5023245a2ecSDmitry Chagin
5033245a2ecSDmitry Chagin int
linux_semtimedop(struct thread * td,struct linux_semtimedop_args * args)5043245a2ecSDmitry Chagin linux_semtimedop(struct thread *td, struct linux_semtimedop_args *args)
5053245a2ecSDmitry Chagin {
5063245a2ecSDmitry Chagin struct timespec ts, *tsa;
5073245a2ecSDmitry Chagin int error;
5083245a2ecSDmitry Chagin
5093245a2ecSDmitry Chagin if (args->timeout) {
510707e567aSDmitry Chagin error = linux_get_timespec(&ts, args->timeout);
5113245a2ecSDmitry Chagin if (error != 0)
5123245a2ecSDmitry Chagin return (error);
5133245a2ecSDmitry Chagin tsa = &ts;
5143245a2ecSDmitry Chagin } else
5153245a2ecSDmitry Chagin tsa = NULL;
5163245a2ecSDmitry Chagin
5173245a2ecSDmitry Chagin return (kern_semop(td, args->semid, PTRIN(args->tsops),
5183245a2ecSDmitry Chagin args->nsops, tsa));
5193245a2ecSDmitry Chagin }
5203245a2ecSDmitry Chagin
521afa66fa8SMarcel Moolenaar int
linux_semget(struct thread * td,struct linux_semget_args * args)522b40ce416SJulian Elischer linux_semget(struct thread *td, struct linux_semget_args *args)
523c21dee17SSøren Schmidt {
5243e0c56a7SDmitry Chagin struct semget_args bsd_args = {
5253e0c56a7SDmitry Chagin .key = args->key,
5263e0c56a7SDmitry Chagin .nsems = args->nsems,
5273e0c56a7SDmitry Chagin .semflg = args->semflg
5283e0c56a7SDmitry Chagin };
5299b86a416SKATO Takenori
5303ad9c842SMaxim Sobolev if (args->nsems < 0)
5313ad9c842SMaxim Sobolev return (EINVAL);
5328451d0ddSKip Macy return (sys_semget(td, &bsd_args));
533c21dee17SSøren Schmidt }
534c21dee17SSøren Schmidt
535afa66fa8SMarcel Moolenaar int
linux_semctl(struct thread * td,struct linux_semctl_args * args)536b40ce416SJulian Elischer linux_semctl(struct thread *td, struct linux_semctl_args *args)
537c21dee17SSøren Schmidt {
538ab60bc84SDmitry Chagin struct l_semid64_ds linux_semid64;
539a6e5348eSMichael Reifenberger struct l_seminfo linux_seminfo;
54049d409a1SJohn Baldwin struct semid_ds semid;
54149d409a1SJohn Baldwin union semun semun;
542b1ee5b65SJohn Baldwin register_t rval;
54349d409a1SJohn Baldwin int cmd, error;
5449b86a416SKATO Takenori
5456eee883aSEitan Adler memset(&linux_seminfo, 0, sizeof(linux_seminfo));
5466eee883aSEitan Adler memset(&linux_semid64, 0, sizeof(linux_semid64));
5476eee883aSEitan Adler
5483ad9c842SMaxim Sobolev switch (args->cmd & ~LINUX_IPC_64) {
5499b86a416SKATO Takenori case LINUX_IPC_RMID:
55049d409a1SJohn Baldwin cmd = IPC_RMID;
5519b86a416SKATO Takenori break;
5529b86a416SKATO Takenori case LINUX_GETNCNT:
55349d409a1SJohn Baldwin cmd = GETNCNT;
5549b86a416SKATO Takenori break;
5559b86a416SKATO Takenori case LINUX_GETPID:
55649d409a1SJohn Baldwin cmd = GETPID;
5579b86a416SKATO Takenori break;
5589b86a416SKATO Takenori case LINUX_GETVAL:
55949d409a1SJohn Baldwin cmd = GETVAL;
5609b86a416SKATO Takenori break;
5619b86a416SKATO Takenori case LINUX_GETZCNT:
56249d409a1SJohn Baldwin cmd = GETZCNT;
5639b86a416SKATO Takenori break;
5649b86a416SKATO Takenori case LINUX_SETVAL:
56549d409a1SJohn Baldwin cmd = SETVAL;
56649d409a1SJohn Baldwin semun.val = args->arg.val;
5679b86a416SKATO Takenori break;
5689b86a416SKATO Takenori case LINUX_IPC_SET:
56949d409a1SJohn Baldwin cmd = IPC_SET;
5703ad9c842SMaxim Sobolev error = linux_semid_pullup(args->cmd & LINUX_IPC_64,
571ab60bc84SDmitry Chagin &linux_semid64, PTRIN(args->arg.buf));
5728042c504SDmitry Chagin if (error != 0)
5735002a60fSMarcel Moolenaar return (error);
574ab60bc84SDmitry Chagin linux_to_bsd_semid_ds(&linux_semid64, &semid);
57549d409a1SJohn Baldwin semun.buf = &semid;
576b1ee5b65SJohn Baldwin return (kern_semctl(td, args->semid, args->semnum, cmd, &semun,
577b1ee5b65SJohn Baldwin td->td_retval));
5789b86a416SKATO Takenori case LINUX_IPC_STAT:
57949d409a1SJohn Baldwin cmd = IPC_STAT;
580ab60bc84SDmitry Chagin semun.buf = &semid;
581ab60bc84SDmitry Chagin error = kern_semctl(td, args->semid, args->semnum, cmd, &semun,
582ab60bc84SDmitry Chagin &rval);
583ab60bc84SDmitry Chagin if (error != 0)
584ab60bc84SDmitry Chagin return (error);
585ab60bc84SDmitry Chagin bsd_to_linux_semid_ds(&semid, &linux_semid64);
586ab60bc84SDmitry Chagin return (linux_semid_pushdown(args->cmd & LINUX_IPC_64,
587ab60bc84SDmitry Chagin &linux_semid64, PTRIN(args->arg.buf)));
588ab60bc84SDmitry Chagin case LINUX_SEM_STAT:
58949d409a1SJohn Baldwin cmd = SEM_STAT;
59049d409a1SJohn Baldwin semun.buf = &semid;
59149d409a1SJohn Baldwin error = kern_semctl(td, args->semid, args->semnum, cmd, &semun,
592b1ee5b65SJohn Baldwin &rval);
5938042c504SDmitry Chagin if (error != 0)
59449d409a1SJohn Baldwin return (error);
595ab60bc84SDmitry Chagin bsd_to_linux_semid_ds(&semid, &linux_semid64);
596b1ee5b65SJohn Baldwin error = linux_semid_pushdown(args->cmd & LINUX_IPC_64,
597ab60bc84SDmitry Chagin &linux_semid64, PTRIN(args->arg.buf));
598b1ee5b65SJohn Baldwin if (error == 0)
599ab60bc84SDmitry Chagin td->td_retval[0] = rval;
600b1ee5b65SJohn Baldwin return (error);
601a6e5348eSMichael Reifenberger case LINUX_IPC_INFO:
602a6e5348eSMichael Reifenberger case LINUX_SEM_INFO:
6031080a2c8SBjoern A. Zeeb bcopy(&seminfo, &linux_seminfo.semmni, sizeof(linux_seminfo) -
6041080a2c8SBjoern A. Zeeb sizeof(linux_seminfo.semmap) );
6051080a2c8SBjoern A. Zeeb /*
60674d7a253SBjoern A. Zeeb * Linux does not use the semmap field but populates it with
60774d7a253SBjoern A. Zeeb * the defined value from SEMMAP, which really is redefined to
60874d7a253SBjoern A. Zeeb * SEMMNS, which they define as SEMMNI * SEMMSL. Try to
60974d7a253SBjoern A. Zeeb * simulate this returning our dynamic semmns value.
6101080a2c8SBjoern A. Zeeb */
6111080a2c8SBjoern A. Zeeb linux_seminfo.semmap = linux_seminfo.semmns;
612a6e5348eSMichael Reifenberger /* XXX BSD equivalent?
613a6e5348eSMichael Reifenberger #define used_semids 10
614a6e5348eSMichael Reifenberger #define used_sems 10
615a6e5348eSMichael Reifenberger linux_seminfo.semusz = used_semids;
616a6e5348eSMichael Reifenberger linux_seminfo.semaem = used_sems;
617a6e5348eSMichael Reifenberger */
6184af27623STim J. Robbins error = copyout(&linux_seminfo,
6194af27623STim J. Robbins PTRIN(args->arg.buf), sizeof(linux_seminfo));
6208042c504SDmitry Chagin if (error != 0)
62131f7ad15SDmitry Chagin return (error);
622ab60bc84SDmitry Chagin /*
623ab60bc84SDmitry Chagin * TODO: Linux return the last assigned id, not the semmni.
624ab60bc84SDmitry Chagin */
625a6e5348eSMichael Reifenberger td->td_retval[0] = seminfo.semmni;
626ab60bc84SDmitry Chagin return (0);
6279b86a416SKATO Takenori case LINUX_GETALL:
62817011df1SAlexander Leidinger cmd = GETALL;
629ab60bc84SDmitry Chagin semun.array = PTRIN(args->arg.array);
63017011df1SAlexander Leidinger break;
6319b86a416SKATO Takenori case LINUX_SETALL:
63217011df1SAlexander Leidinger cmd = SETALL;
633ab60bc84SDmitry Chagin semun.array = PTRIN(args->arg.array);
63417011df1SAlexander Leidinger break;
6359b86a416SKATO Takenori default:
636e15583ceSAlfred Perlstein linux_msg(td, "ipc type %d is not implemented",
6373ad9c842SMaxim Sobolev args->cmd & ~LINUX_IPC_64);
63831f7ad15SDmitry Chagin return (EINVAL);
6399b86a416SKATO Takenori }
640b1ee5b65SJohn Baldwin return (kern_semctl(td, args->semid, args->semnum, cmd, &semun,
641b1ee5b65SJohn Baldwin td->td_retval));
642c21dee17SSøren Schmidt }
643c21dee17SSøren Schmidt
644afa66fa8SMarcel Moolenaar int
linux_msgsnd(struct thread * td,struct linux_msgsnd_args * args)645b40ce416SJulian Elischer linux_msgsnd(struct thread *td, struct linux_msgsnd_args *args)
646c21dee17SSøren Schmidt {
647f61480ecSJung-uk Kim const void *msgp;
648f61480ecSJung-uk Kim long mtype;
649f61480ecSJung-uk Kim l_long lmtype;
650f61480ecSJung-uk Kim int error;
651bb5889bdSSøren Schmidt
65234ec45feSJung-uk Kim if ((l_long)args->msgsz < 0 || args->msgsz > (l_long)msginfo.msgmax)
653f61480ecSJung-uk Kim return (EINVAL);
654f61480ecSJung-uk Kim msgp = PTRIN(args->msgp);
655f61480ecSJung-uk Kim if ((error = copyin(msgp, &lmtype, sizeof(lmtype))) != 0)
656f61480ecSJung-uk Kim return (error);
657f61480ecSJung-uk Kim mtype = (long)lmtype;
658f61480ecSJung-uk Kim return (kern_msgsnd(td, args->msqid,
659f61480ecSJung-uk Kim (const char *)msgp + sizeof(lmtype),
660f61480ecSJung-uk Kim args->msgsz, args->msgflg, mtype));
661c21dee17SSøren Schmidt }
662c21dee17SSøren Schmidt
663afa66fa8SMarcel Moolenaar int
linux_msgrcv(struct thread * td,struct linux_msgrcv_args * args)664b40ce416SJulian Elischer linux_msgrcv(struct thread *td, struct linux_msgrcv_args *args)
665c21dee17SSøren Schmidt {
666bb5889bdSSøren Schmidt void *msgp;
667f61480ecSJung-uk Kim long mtype;
668f61480ecSJung-uk Kim l_long lmtype;
669f61480ecSJung-uk Kim int error;
670bb5889bdSSøren Schmidt
67134ec45feSJung-uk Kim if ((l_long)args->msgsz < 0 || args->msgsz > (l_long)msginfo.msgmax)
672f61480ecSJung-uk Kim return (EINVAL);
673f61480ecSJung-uk Kim msgp = PTRIN(args->msgp);
674f61480ecSJung-uk Kim if ((error = kern_msgrcv(td, args->msqid,
675f61480ecSJung-uk Kim (char *)msgp + sizeof(lmtype), args->msgsz,
676f61480ecSJung-uk Kim args->msgtyp, args->msgflg, &mtype)) != 0)
677f61480ecSJung-uk Kim return (error);
678f61480ecSJung-uk Kim lmtype = (l_long)mtype;
679f61480ecSJung-uk Kim return (copyout(&lmtype, msgp, sizeof(lmtype)));
680c21dee17SSøren Schmidt }
681c21dee17SSøren Schmidt
682afa66fa8SMarcel Moolenaar int
linux_msgget(struct thread * td,struct linux_msgget_args * args)683b40ce416SJulian Elischer linux_msgget(struct thread *td, struct linux_msgget_args *args)
684c21dee17SSøren Schmidt {
6853e0c56a7SDmitry Chagin struct msgget_args bsd_args = {
6863e0c56a7SDmitry Chagin .key = args->key,
6873e0c56a7SDmitry Chagin .msgflg = args->msgflg
6883e0c56a7SDmitry Chagin };
689bb5889bdSSøren Schmidt
6908451d0ddSKip Macy return (sys_msgget(td, &bsd_args));
691c21dee17SSøren Schmidt }
692c21dee17SSøren Schmidt
693afa66fa8SMarcel Moolenaar int
linux_msgctl(struct thread * td,struct linux_msgctl_args * args)694b40ce416SJulian Elischer linux_msgctl(struct thread *td, struct linux_msgctl_args *args)
695c21dee17SSøren Schmidt {
696f4b6eb04SMaxim Sobolev int error, bsd_cmd;
697ab60bc84SDmitry Chagin struct l_msqid64_ds linux_msqid64;
698f4b6eb04SMaxim Sobolev struct msqid_ds bsd_msqid;
699bb5889bdSSøren Schmidt
7006eee883aSEitan Adler memset(&linux_msqid64, 0, sizeof(linux_msqid64));
7016eee883aSEitan Adler
702f3ea244eSJohn Baldwin bsd_cmd = args->cmd & ~LINUX_IPC_64;
70334ec45feSJung-uk Kim switch (bsd_cmd) {
70434ec45feSJung-uk Kim case LINUX_IPC_INFO:
70534ec45feSJung-uk Kim case LINUX_MSG_INFO: {
70634ec45feSJung-uk Kim struct l_msginfo linux_msginfo;
70734ec45feSJung-uk Kim
7086eee883aSEitan Adler memset(&linux_msginfo, 0, sizeof(linux_msginfo));
70934ec45feSJung-uk Kim /*
71034ec45feSJung-uk Kim * XXX MSG_INFO uses the same data structure but returns different
71134ec45feSJung-uk Kim * dynamic counters in msgpool, msgmap, and msgtql fields.
71234ec45feSJung-uk Kim */
71334ec45feSJung-uk Kim linux_msginfo.msgpool = (long)msginfo.msgmni *
71434ec45feSJung-uk Kim (long)msginfo.msgmnb / 1024L; /* XXX MSG_INFO. */
71534ec45feSJung-uk Kim linux_msginfo.msgmap = msginfo.msgmnb; /* XXX MSG_INFO. */
71634ec45feSJung-uk Kim linux_msginfo.msgmax = msginfo.msgmax;
71734ec45feSJung-uk Kim linux_msginfo.msgmnb = msginfo.msgmnb;
71834ec45feSJung-uk Kim linux_msginfo.msgmni = msginfo.msgmni;
71934ec45feSJung-uk Kim linux_msginfo.msgssz = msginfo.msgssz;
72034ec45feSJung-uk Kim linux_msginfo.msgtql = msginfo.msgtql; /* XXX MSG_INFO. */
72134ec45feSJung-uk Kim linux_msginfo.msgseg = msginfo.msgseg;
72234ec45feSJung-uk Kim error = copyout(&linux_msginfo, PTRIN(args->buf),
72334ec45feSJung-uk Kim sizeof(linux_msginfo));
72434ec45feSJung-uk Kim if (error == 0)
72534ec45feSJung-uk Kim td->td_retval[0] = msginfo.msgmni; /* XXX */
72634ec45feSJung-uk Kim
72734ec45feSJung-uk Kim return (error);
72834ec45feSJung-uk Kim }
72934ec45feSJung-uk Kim
7307356a43cSRoman Divacky /*
7317356a43cSRoman Divacky * TODO: implement this
7327356a43cSRoman Divacky * case LINUX_MSG_STAT:
7337356a43cSRoman Divacky */
7347356a43cSRoman Divacky case LINUX_IPC_STAT:
7357356a43cSRoman Divacky /* NOTHING */
7367356a43cSRoman Divacky break;
7377356a43cSRoman Divacky
73834ec45feSJung-uk Kim case LINUX_IPC_SET:
7393ad9c842SMaxim Sobolev error = linux_msqid_pullup(args->cmd & LINUX_IPC_64,
740ab60bc84SDmitry Chagin &linux_msqid64, PTRIN(args->buf));
7418042c504SDmitry Chagin if (error != 0)
7423ad9c842SMaxim Sobolev return (error);
743ab60bc84SDmitry Chagin linux_to_bsd_msqid_ds(&linux_msqid64, &bsd_msqid);
74434ec45feSJung-uk Kim break;
7457356a43cSRoman Divacky
7467356a43cSRoman Divacky case LINUX_IPC_RMID:
7477356a43cSRoman Divacky /* NOTHING */
7487356a43cSRoman Divacky break;
7497356a43cSRoman Divacky
7507356a43cSRoman Divacky default:
7517356a43cSRoman Divacky return (EINVAL);
7527356a43cSRoman Divacky break;
753f3ea244eSJohn Baldwin }
7543ad9c842SMaxim Sobolev
75576951d21SJohn Baldwin error = kern_msgctl(td, args->msqid, bsd_cmd, &bsd_msqid);
756ab60bc84SDmitry Chagin if (error != 0) {
757ab60bc84SDmitry Chagin if (bsd_cmd == LINUX_IPC_RMID && error == EACCES)
758ab60bc84SDmitry Chagin return (EPERM);
759f4b6eb04SMaxim Sobolev if (bsd_cmd != LINUX_IPC_RMID || error != EINVAL)
7603ad9c842SMaxim Sobolev return (error);
761ab60bc84SDmitry Chagin }
7623ad9c842SMaxim Sobolev
763f4b6eb04SMaxim Sobolev if (bsd_cmd == LINUX_IPC_STAT) {
764ab60bc84SDmitry Chagin bsd_to_linux_msqid_ds(&bsd_msqid, &linux_msqid64);
7653ad9c842SMaxim Sobolev return (linux_msqid_pushdown(args->cmd & LINUX_IPC_64,
766ab60bc84SDmitry Chagin &linux_msqid64, PTRIN(args->buf)));
7673ad9c842SMaxim Sobolev }
7683ad9c842SMaxim Sobolev
7693ad9c842SMaxim Sobolev return (0);
770c21dee17SSøren Schmidt }
771c21dee17SSøren Schmidt
772afa66fa8SMarcel Moolenaar int
linux_shmat(struct thread * td,struct linux_shmat_args * args)773b40ce416SJulian Elischer linux_shmat(struct thread *td, struct linux_shmat_args *args)
774c21dee17SSøren Schmidt {
7753e0c56a7SDmitry Chagin struct shmat_args bsd_args = {
7763e0c56a7SDmitry Chagin .shmid = args->shmid,
7773e0c56a7SDmitry Chagin .shmaddr = PTRIN(args->shmaddr),
7783e0c56a7SDmitry Chagin .shmflg = args->shmflg
7793e0c56a7SDmitry Chagin };
780c21dee17SSøren Schmidt
7817dabf89bSDmitry Chagin return (sys_shmat(td, &bsd_args));
782c21dee17SSøren Schmidt }
783c21dee17SSøren Schmidt
784afa66fa8SMarcel Moolenaar int
linux_shmdt(struct thread * td,struct linux_shmdt_args * args)785b40ce416SJulian Elischer linux_shmdt(struct thread *td, struct linux_shmdt_args *args)
786c21dee17SSøren Schmidt {
7873e0c56a7SDmitry Chagin struct shmdt_args bsd_args = {
7883e0c56a7SDmitry Chagin .shmaddr = PTRIN(args->shmaddr)
7893e0c56a7SDmitry Chagin };
790c21dee17SSøren Schmidt
7918451d0ddSKip Macy return (sys_shmdt(td, &bsd_args));
792c21dee17SSøren Schmidt }
793c21dee17SSøren Schmidt
794afa66fa8SMarcel Moolenaar int
linux_shmget(struct thread * td,struct linux_shmget_args * args)795b40ce416SJulian Elischer linux_shmget(struct thread *td, struct linux_shmget_args *args)
796c21dee17SSøren Schmidt {
7973e0c56a7SDmitry Chagin struct shmget_args bsd_args = {
7983e0c56a7SDmitry Chagin .key = args->key,
7993e0c56a7SDmitry Chagin .size = args->size,
8003e0c56a7SDmitry Chagin .shmflg = args->shmflg
8013e0c56a7SDmitry Chagin };
802c21dee17SSøren Schmidt
8038451d0ddSKip Macy return (sys_shmget(td, &bsd_args));
804c21dee17SSøren Schmidt }
805c21dee17SSøren Schmidt
806afa66fa8SMarcel Moolenaar int
linux_shmctl(struct thread * td,struct linux_shmctl_args * args)807b40ce416SJulian Elischer linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
808c21dee17SSøren Schmidt {
809ab60bc84SDmitry Chagin struct l_shmid64_ds linux_shmid64;
810ab60bc84SDmitry Chagin struct l_shminfo64 linux_shminfo64;
811491dec93SMichael Reifenberger struct l_shm_info linux_shm_info;
812f130dcf2SMartin Blapp struct shmid_ds bsd_shmid;
813c21dee17SSøren Schmidt int error;
814c21dee17SSøren Schmidt
8156eee883aSEitan Adler memset(&linux_shm_info, 0, sizeof(linux_shm_info));
8166eee883aSEitan Adler memset(&linux_shmid64, 0, sizeof(linux_shmid64));
8176eee883aSEitan Adler memset(&linux_shminfo64, 0, sizeof(linux_shminfo64));
8186eee883aSEitan Adler
8193ad9c842SMaxim Sobolev switch (args->cmd & ~LINUX_IPC_64) {
820f130dcf2SMartin Blapp case LINUX_IPC_INFO: {
821f130dcf2SMartin Blapp struct shminfo bsd_shminfo;
822f130dcf2SMartin Blapp
823f130dcf2SMartin Blapp /* Perform shmctl wanting removed segments lookup */
824f130dcf2SMartin Blapp error = kern_shmctl(td, args->shmid, IPC_INFO,
8258528552bSJohn Baldwin (void *)&bsd_shminfo, NULL);
8268042c504SDmitry Chagin if (error != 0)
82731f7ad15SDmitry Chagin return (error);
828f130dcf2SMartin Blapp
829ab60bc84SDmitry Chagin bsd_to_linux_shminfo(&bsd_shminfo, &linux_shminfo64);
830f130dcf2SMartin Blapp
8313ad9c842SMaxim Sobolev return (linux_shminfo_pushdown(args->cmd & LINUX_IPC_64,
832ab60bc84SDmitry Chagin &linux_shminfo64, PTRIN(args->buf)));
833f130dcf2SMartin Blapp }
834491dec93SMichael Reifenberger
835f130dcf2SMartin Blapp case LINUX_SHM_INFO: {
836f130dcf2SMartin Blapp struct shm_info bsd_shm_info;
837f130dcf2SMartin Blapp
838f130dcf2SMartin Blapp /* Perform shmctl wanting removed segments lookup */
839f130dcf2SMartin Blapp error = kern_shmctl(td, args->shmid, SHM_INFO,
8408528552bSJohn Baldwin (void *)&bsd_shm_info, NULL);
8418042c504SDmitry Chagin if (error != 0)
84231f7ad15SDmitry Chagin return (error);
843f130dcf2SMartin Blapp
844f130dcf2SMartin Blapp bsd_to_linux_shm_info(&bsd_shm_info, &linux_shm_info);
845f130dcf2SMartin Blapp
84631f7ad15SDmitry Chagin return (copyout(&linux_shm_info, PTRIN(args->buf),
84731f7ad15SDmitry Chagin sizeof(struct l_shm_info)));
848f130dcf2SMartin Blapp }
849491dec93SMichael Reifenberger
850c21dee17SSøren Schmidt case LINUX_IPC_STAT:
851f130dcf2SMartin Blapp /* Perform shmctl wanting removed segments lookup */
852f130dcf2SMartin Blapp error = kern_shmctl(td, args->shmid, IPC_STAT,
8538528552bSJohn Baldwin (void *)&bsd_shmid, NULL);
8548042c504SDmitry Chagin if (error != 0)
85531f7ad15SDmitry Chagin return (error);
856f130dcf2SMartin Blapp
857ab60bc84SDmitry Chagin bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid64);
858f130dcf2SMartin Blapp
8593ad9c842SMaxim Sobolev return (linux_shmid_pushdown(args->cmd & LINUX_IPC_64,
860ab60bc84SDmitry Chagin &linux_shmid64, PTRIN(args->buf)));
861c21dee17SSøren Schmidt
862491dec93SMichael Reifenberger case LINUX_SHM_STAT:
863f130dcf2SMartin Blapp /* Perform shmctl wanting removed segments lookup */
864f130dcf2SMartin Blapp error = kern_shmctl(td, args->shmid, IPC_STAT,
8658528552bSJohn Baldwin (void *)&bsd_shmid, NULL);
8668042c504SDmitry Chagin if (error != 0)
86731f7ad15SDmitry Chagin return (error);
868f130dcf2SMartin Blapp
869ab60bc84SDmitry Chagin bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid64);
870f130dcf2SMartin Blapp
8713ad9c842SMaxim Sobolev return (linux_shmid_pushdown(args->cmd & LINUX_IPC_64,
872ab60bc84SDmitry Chagin &linux_shmid64, PTRIN(args->buf)));
873491dec93SMichael Reifenberger
874c21dee17SSøren Schmidt case LINUX_IPC_SET:
8753ad9c842SMaxim Sobolev error = linux_shmid_pullup(args->cmd & LINUX_IPC_64,
876ab60bc84SDmitry Chagin &linux_shmid64, PTRIN(args->buf));
8778042c504SDmitry Chagin if (error != 0)
87831f7ad15SDmitry Chagin return (error);
879c21dee17SSøren Schmidt
880ab60bc84SDmitry Chagin linux_to_bsd_shmid_ds(&linux_shmid64, &bsd_shmid);
881f130dcf2SMartin Blapp
882f130dcf2SMartin Blapp /* Perform shmctl wanting removed segments lookup */
88331f7ad15SDmitry Chagin return (kern_shmctl(td, args->shmid, IPC_SET,
88431f7ad15SDmitry Chagin (void *)&bsd_shmid, NULL));
885f130dcf2SMartin Blapp
886f130dcf2SMartin Blapp case LINUX_IPC_RMID: {
887f130dcf2SMartin Blapp void *buf;
888f130dcf2SMartin Blapp
8894af27623STim J. Robbins if (args->buf == 0)
890f130dcf2SMartin Blapp buf = NULL;
891ba988339SJordan K. Hubbard else {
8923ad9c842SMaxim Sobolev error = linux_shmid_pullup(args->cmd & LINUX_IPC_64,
893ab60bc84SDmitry Chagin &linux_shmid64, PTRIN(args->buf));
8948042c504SDmitry Chagin if (error != 0)
89531f7ad15SDmitry Chagin return (error);
896ab60bc84SDmitry Chagin linux_to_bsd_shmid_ds(&linux_shmid64, &bsd_shmid);
897f130dcf2SMartin Blapp buf = (void *)&bsd_shmid;
898ba988339SJordan K. Hubbard }
89931f7ad15SDmitry Chagin return (kern_shmctl(td, args->shmid, IPC_RMID, buf, NULL));
900f130dcf2SMartin Blapp }
901c21dee17SSøren Schmidt
902c21dee17SSøren Schmidt case LINUX_SHM_LOCK:
90331f7ad15SDmitry Chagin /* FALLTHROUGH */
904c21dee17SSøren Schmidt case LINUX_SHM_UNLOCK:
90531f7ad15SDmitry Chagin /* FALLTHROUGH */
906c21dee17SSøren Schmidt default:
90731f7ad15SDmitry Chagin linux_msg(td, "ipc type %d not implemented",
90831f7ad15SDmitry Chagin args->cmd & ~LINUX_IPC_64);
90931f7ad15SDmitry Chagin return (EINVAL);
910c21dee17SSøren Schmidt }
911c21dee17SSøren Schmidt }
912813a5e14SJohn Baldwin
913813a5e14SJohn Baldwin MODULE_DEPEND(linux, sysvmsg, 1, 1, 1);
914813a5e14SJohn Baldwin MODULE_DEPEND(linux, sysvsem, 1, 1, 1);
915813a5e14SJohn Baldwin MODULE_DEPEND(linux, sysvshm, 1, 1, 1);
916