svr4_ipc.c revision 159993
1285612Sdelphij/*-
2181834Sroberto * Copyright (c) 1995 The NetBSD Foundation, Inc.
3285612Sdelphij * All rights reserved.
4330567Sgordon *
5181834Sroberto * This code is derived from software contributed to The NetBSD Foundation
6181834Sroberto * by Christos Zoulas.
7181834Sroberto *
8285612Sdelphij * Redistribution and use in source and binary forms, with or without
9181834Sroberto * modification, are permitted provided that the following conditions
10285612Sdelphij * are met:
11285612Sdelphij * 1. Redistributions of source code must retain the above copyright
12285612Sdelphij *    notice, this list of conditions and the following disclaimer.
13285612Sdelphij * 2. Redistributions in binary form must reproduce the above copyright
14285612Sdelphij *    notice, this list of conditions and the following disclaimer in the
15285612Sdelphij *    documentation and/or other materials provided with the distribution.
16285612Sdelphij * 3. All advertising materials mentioning features or use of this software
17181834Sroberto *    must display the following acknowledgement:
18285612Sdelphij *        This product includes software developed by the NetBSD
19285612Sdelphij *        Foundation, Inc. and its contributors.
20181834Sroberto * 4. Neither the name of The NetBSD Foundation nor the names of its
21316722Sdelphij *    contributors may be used to endorse or promote products derived
22285612Sdelphij *    from this software without specific prior written permission.
23285612Sdelphij *
24285612Sdelphij * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25285612Sdelphij * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26285612Sdelphij * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27285612Sdelphij * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28285612Sdelphij * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29285612Sdelphij * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30285612Sdelphij * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31285612Sdelphij * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32285612Sdelphij * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33285612Sdelphij * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34285612Sdelphij * POSSIBILITY OF SUCH DAMAGE.
35285612Sdelphij */
36285612Sdelphij/*-
37181834Sroberto * Portions of this code have been derived from software contributed
38285612Sdelphij * to the FreeBSD Project by Mark Newton.
39181834Sroberto *
40181834Sroberto * Copyright (c) 1999 Mark Newton
41181834Sroberto * All rights reserved.
42181834Sroberto *
43181834Sroberto * Redistribution and use in source and binary forms, with or without
44181834Sroberto * modification, are permitted provided that the following conditions
45285612Sdelphij * are met:
46181834Sroberto * 1. Redistributions of source code must retain the above copyright
47181834Sroberto *    notice, this list of conditions and the following disclaimer.
48181834Sroberto * 2. Redistributions in binary form must reproduce the above copyright
49285612Sdelphij *    notice, this list of conditions and the following disclaimer in the
50181834Sroberto *    documentation and/or other materials provided with the distribution.
51181834Sroberto * 3. The name of the author may not be used to endorse or promote products
52181834Sroberto *    derived from this software without specific prior written permission
53181834Sroberto *
54181834Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55181834Sroberto * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56285612Sdelphij * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57181834Sroberto * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58181834Sroberto * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59181834Sroberto * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60181834Sroberto * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61181834Sroberto * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62181834Sroberto * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63285612Sdelphij * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64285612Sdelphij *
65181834Sroberto * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due
66181834Sroberto * to preprocessor conditionals).  A nice project for a kernel hacking
67285612Sdelphij * novice might be to MakeItGo, but I have more important fish to fry
68285612Sdelphij * at present.
69285612Sdelphij *
70285612Sdelphij *	Derived from: $NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $
71285612Sdelphij */
72285612Sdelphij
73285612Sdelphij#include <sys/cdefs.h>
74285612Sdelphij__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_ipc.c 159993 2006-06-27 18:31:36Z jhb $");
75285612Sdelphij
76285612Sdelphij#include "opt_sysvipc.h"
77285612Sdelphij
78285612Sdelphij#include <sys/param.h>
79285612Sdelphij#include <sys/ipc.h>
80285612Sdelphij#include <sys/msg.h>
81285612Sdelphij#include <sys/proc.h>
82285612Sdelphij#include <sys/sem.h>
83285612Sdelphij#include <sys/shm.h>
84285612Sdelphij#include <sys/syscallsubr.h>
85285612Sdelphij#include <sys/sysproto.h>
86285612Sdelphij#include <sys/systm.h>
87285612Sdelphij#include <sys/time.h>
88285612Sdelphij
89285612Sdelphij#include <compat/svr4/svr4.h>
90285612Sdelphij#include <compat/svr4/svr4_types.h>
91285612Sdelphij#include <compat/svr4/svr4_signal.h>
92285612Sdelphij#include <compat/svr4/svr4_proto.h>
93285612Sdelphij#include <compat/svr4/svr4_util.h>
94285612Sdelphij#include <compat/svr4/svr4_ipc.h>
95285612Sdelphij
96285612Sdelphij#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
97285612Sdelphijstatic void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *,
98285612Sdelphij				      struct ipc_perm *);
99285612Sdelphijstatic void bsd_to_svr4_ipc_perm(const struct ipc_perm *,
100285612Sdelphij				      struct svr4_ipc_perm *);
101285612Sdelphij#endif
102285612Sdelphij
103285612Sdelphij#ifdef SYSVSEM
104285612Sdelphijstatic void bsd_to_svr4_semid_ds(const struct semid_ds *,
105181834Sroberto				      struct svr4_semid_ds *);
106285612Sdelphijstatic void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *,
107285612Sdelphij				      struct semid_ds *);
108285612Sdelphijstatic int svr4_semop(struct thread *, void *);
109330567Sgordonstatic int svr4_semget(struct thread *, void *);
110285612Sdelphijstatic int svr4_semctl(struct thread *, void *);
111330567Sgordon#endif
112181834Sroberto
113285612Sdelphij#ifdef SYSVMSG
114181834Srobertostatic void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
115181834Sroberto				      struct svr4_msqid_ds *);
116285612Sdelphijstatic void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
117181834Sroberto				      struct msqid_ds *);
118181834Srobertostatic int svr4_msgsnd(struct thread *, void *);
119285612Sdelphijstatic int svr4_msgrcv(struct thread *, void *);
120181834Srobertostatic int svr4_msgget(struct thread *, void *);
121285612Sdelphijstatic int svr4_msgctl(struct thread *, void *);
122181834Sroberto#endif
123285612Sdelphij
124285612Sdelphij#ifdef SYSVSHM
125285612Sdelphijstatic void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
126285612Sdelphij				      struct svr4_shmid_ds *);
127181834Srobertostatic void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
128285612Sdelphij				      struct shmid_ds *);
129181834Srobertostatic int svr4_shmat(struct thread *, void *);
130285612Sdelphijstatic int svr4_shmdt(struct thread *, void *);
131181834Srobertostatic int svr4_shmget(struct thread *, void *);
132285612Sdelphijstatic int svr4_shmctl(struct thread *, void *);
133181834Sroberto#endif
134285612Sdelphij
135181834Sroberto#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
136285612Sdelphij
137285612Sdelphijstatic void
138181834Srobertosvr4_to_bsd_ipc_perm(spp, bpp)
139285612Sdelphij	const struct svr4_ipc_perm *spp;
140285612Sdelphij	struct ipc_perm *bpp;
141181834Sroberto{
142285612Sdelphij	bpp->key = spp->key;
143181834Sroberto	bpp->uid = spp->uid;
144181834Sroberto	bpp->gid = spp->gid;
145285612Sdelphij	bpp->cuid = spp->cuid;
146181834Sroberto	bpp->cgid = spp->cgid;
147181834Sroberto	bpp->mode = spp->mode;
148285612Sdelphij	bpp->seq = spp->seq;
149285612Sdelphij}
150285612Sdelphij
151285612Sdelphijstatic void
152285612Sdelphijbsd_to_svr4_ipc_perm(bpp, spp)
153285612Sdelphij	const struct ipc_perm *bpp;
154285612Sdelphij	struct svr4_ipc_perm *spp;
155285612Sdelphij{
156285612Sdelphij	spp->key = bpp->key;
157285612Sdelphij	spp->uid = bpp->uid;
158285612Sdelphij	spp->gid = bpp->gid;
159285612Sdelphij	spp->cuid = bpp->cuid;
160181834Sroberto	spp->cgid = bpp->cgid;
161181834Sroberto	spp->mode = bpp->mode;
162181834Sroberto	spp->seq = bpp->seq;
163181834Sroberto}
164181834Sroberto#endif
165181834Sroberto
166181834Sroberto#ifdef SYSVSEM
167181834Srobertostatic void
168181834Srobertobsd_to_svr4_semid_ds(bds, sds)
169181834Sroberto	const struct semid_ds *bds;
170181834Sroberto	struct svr4_semid_ds *sds;
171181834Sroberto{
172181834Sroberto	bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
173181834Sroberto	sds->sem_base = (struct svr4_sem *) bds->sem_base;
174181834Sroberto	sds->sem_nsems = bds->sem_nsems;
175181834Sroberto	sds->sem_otime = bds->sem_otime;
176181834Sroberto	sds->sem_pad1 = bds->sem_pad1;
177181834Sroberto	sds->sem_ctime = bds->sem_ctime;
178181834Sroberto	sds->sem_pad2 = bds->sem_pad2;
179181834Sroberto}
180181834Sroberto
181181834Srobertostatic void
182181834Srobertosvr4_to_bsd_semid_ds(sds, bds)
183181834Sroberto	const struct svr4_semid_ds *sds;
184181834Sroberto	struct semid_ds *bds;
185181834Sroberto{
186181834Sroberto	svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
187181834Sroberto	bds->sem_base = (struct sem *) bds->sem_base;
188181834Sroberto	bds->sem_nsems = sds->sem_nsems;
189181834Sroberto	bds->sem_otime = sds->sem_otime;
190181834Sroberto	bds->sem_pad1 = sds->sem_pad1;
191181834Sroberto	bds->sem_ctime = sds->sem_ctime;
192181834Sroberto	bds->sem_pad2 = sds->sem_pad2;
193181834Sroberto}
194181834Sroberto
195181834Srobertostruct svr4_sys_semctl_args {
196181834Sroberto	int what;
197181834Sroberto	int semid;
198181834Sroberto	int semnum;
199181834Sroberto	int cmd;
200181834Sroberto	union semun arg;
201181834Sroberto};
202181834Sroberto
203285612Sdelphijstatic int
204285612Sdelphijsvr4_semctl(td, v)
205285612Sdelphij	struct thread *td;
206285612Sdelphij	void *v;
207181834Sroberto{
208181834Sroberto	struct svr4_sys_semctl_args *uap = v;
209181834Sroberto	struct svr4_semid_ds ss;
210181834Sroberto	struct semid_ds bs;
211181834Sroberto	union semun semun;
212181834Sroberto	int cmd, error;
213181834Sroberto
214181834Sroberto	switch (uap->cmd) {
215181834Sroberto	case SVR4_SEM_GETZCNT:
216181834Sroberto		cmd = GETZCNT;
217181834Sroberto		break;
218181834Sroberto
219181834Sroberto	case SVR4_SEM_GETNCNT:
220181834Sroberto		cmd = GETNCNT;
221181834Sroberto		break;
222181834Sroberto
223181834Sroberto	case SVR4_SEM_GETPID:
224181834Sroberto		cmd = GETPID;
225181834Sroberto		break;
226181834Sroberto
227181834Sroberto	case SVR4_SEM_GETVAL:
228181834Sroberto		cmd = GETVAL;
229181834Sroberto		break;
230181834Sroberto
231181834Sroberto	case SVR4_SEM_SETVAL:
232181834Sroberto		cmd = SETVAL;
233181834Sroberto		break;
234181834Sroberto
235181834Sroberto	case SVR4_SEM_GETALL:
236181834Sroberto		cmd = GETVAL;
237181834Sroberto		break;
238181834Sroberto
239181834Sroberto	case SVR4_SEM_SETALL:
240181834Sroberto		cmd = SETVAL;
241181834Sroberto		break;
242181834Sroberto
243181834Sroberto	case SVR4_IPC_STAT:
244181834Sroberto		cmd = IPC_STAT;
245181834Sroberto		semun.buf = &bs;
246181834Sroberto		error = kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
247181834Sroberto		    UIO_SYSSPACE);
248181834Sroberto		if (error)
249181834Sroberto                        return error;
250181834Sroberto                bsd_to_svr4_semid_ds(&bs, &ss);
251181834Sroberto		return copyout(&ss, uap->arg.buf, sizeof(ss));
252181834Sroberto
253181834Sroberto	case SVR4_IPC_SET:
254181834Sroberto		cmd = IPC_SET;
255285612Sdelphij		error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
256285612Sdelphij                if (error)
257285612Sdelphij                        return error;
258181834Sroberto                svr4_to_bsd_semid_ds(&ss, &bs);
259181834Sroberto		semun.buf = &bs;
260181834Sroberto		return kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
261181834Sroberto		    UIO_SYSSPACE);
262181834Sroberto
263181834Sroberto	case SVR4_IPC_RMID:
264181834Sroberto		cmd = IPC_RMID;
265181834Sroberto		break;
266181834Sroberto
267181834Sroberto	default:
268181834Sroberto		return EINVAL;
269181834Sroberto	}
270181834Sroberto
271285612Sdelphij	return kern_semctl(td, uap->semid, uap->semnum, cmd, &uap->arg,
272285612Sdelphij	    UIO_USERSPACE);
273285612Sdelphij}
274285612Sdelphij
275181834Srobertostruct svr4_sys_semget_args {
276181834Sroberto	int what;
277181834Sroberto	svr4_key_t key;
278181834Sroberto	int nsems;
279181834Sroberto	int semflg;
280181834Sroberto};
281181834Sroberto
282181834Srobertostatic int
283285612Sdelphijsvr4_semget(td, v)
284285612Sdelphij	struct thread *td;
285285612Sdelphij	void *v;
286285612Sdelphij{
287181834Sroberto	struct svr4_sys_semget_args *uap = v;
288181834Sroberto	struct semget_args ap;
289181834Sroberto
290181834Sroberto	ap.key = uap->key;
291285612Sdelphij	ap.nsems = uap->nsems;
292285612Sdelphij	ap.semflg = uap->semflg;
293285612Sdelphij
294285612Sdelphij	return semget(td, &ap);
295285612Sdelphij}
296285612Sdelphij
297285612Sdelphijstruct svr4_sys_semop_args {
298285612Sdelphij	int what;
299285612Sdelphij	int semid;
300285612Sdelphij	struct svr4_sembuf * sops;
301285612Sdelphij	u_int nsops;
302285612Sdelphij};
303181834Sroberto
304181834Srobertostatic int
305181834Srobertosvr4_semop(td, v)
306181834Sroberto	struct thread *td;
307181834Sroberto	void *v;
308181834Sroberto{
309181834Sroberto	struct svr4_sys_semop_args *uap = v;
310181834Sroberto	struct semop_args ap;
311181834Sroberto
312181834Sroberto	ap.semid = uap->semid;
313181834Sroberto	/* These are the same */
314285612Sdelphij	ap.sops = (struct sembuf *) uap->sops;
315181834Sroberto	ap.nsops = uap->nsops;
316181834Sroberto
317181834Sroberto	return semop(td, &ap);
318181834Sroberto}
319181834Sroberto
320181834Srobertoint
321181834Srobertosvr4_sys_semsys(td, uap)
322181834Sroberto	struct thread *td;
323181834Sroberto	struct svr4_sys_semsys_args *uap;
324181834Sroberto{
325181834Sroberto
326181834Sroberto	DPRINTF(("svr4_semsys(%d)\n", uap->what));
327285612Sdelphij
328181834Sroberto	switch (uap->what) {
329181834Sroberto	case SVR4_semctl:
330181834Sroberto		return svr4_semctl(td, uap);
331285612Sdelphij	case SVR4_semget:
332181834Sroberto		return svr4_semget(td, uap);
333181834Sroberto	case SVR4_semop:
334285612Sdelphij		return svr4_semop(td, uap);
335181834Sroberto	default:
336285612Sdelphij		return EINVAL;
337285612Sdelphij	}
338285612Sdelphij}
339181834Sroberto
340181834SrobertoMODULE_DEPEND(svr4elf, sysvsem, 1, 1, 1);
341285612Sdelphij#endif
342181834Sroberto
343285612Sdelphij#ifdef SYSVMSG
344181834Srobertostatic void
345181834Srobertobsd_to_svr4_msqid_ds(bds, sds)
346181834Sroberto	const struct msqid_ds *bds;
347181834Sroberto	struct svr4_msqid_ds *sds;
348181834Sroberto{
349181834Sroberto	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
350181834Sroberto	sds->msg_first = (struct svr4_msg *) bds->msg_first;
351181834Sroberto	sds->msg_last = (struct svr4_msg *) bds->msg_last;
352181834Sroberto	sds->msg_cbytes = bds->msg_cbytes;
353285612Sdelphij	sds->msg_qnum = bds->msg_qnum;
354285612Sdelphij	sds->msg_qbytes = bds->msg_qbytes;
355181834Sroberto	sds->msg_lspid = bds->msg_lspid;
356181834Sroberto	sds->msg_lrpid = bds->msg_lrpid;
357285612Sdelphij	sds->msg_stime = bds->msg_stime;
358181834Sroberto	sds->msg_pad1 = bds->msg_pad1;
359181834Sroberto	sds->msg_rtime = bds->msg_rtime;
360181834Sroberto	sds->msg_pad2 = bds->msg_pad2;
361181834Sroberto	sds->msg_ctime = bds->msg_ctime;
362181834Sroberto	sds->msg_pad3 = bds->msg_pad3;
363181834Sroberto
364181834Sroberto	/* use the padding for the rest of the fields */
365181834Sroberto	{
366181834Sroberto		const short *pad = (const short *) bds->msg_pad4;
367181834Sroberto		sds->msg_cv = pad[0];
368285612Sdelphij		sds->msg_qnum_cv = pad[1];
369181834Sroberto	}
370181834Sroberto}
371181834Sroberto
372285612Sdelphijstatic void
373181834Srobertosvr4_to_bsd_msqid_ds(sds, bds)
374181834Sroberto	const struct svr4_msqid_ds *sds;
375181834Sroberto	struct msqid_ds *bds;
376285612Sdelphij{
377285612Sdelphij	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
378285612Sdelphij	bds->msg_first = (struct msg *) sds->msg_first;
379285612Sdelphij	bds->msg_last = (struct msg *) sds->msg_last;
380285612Sdelphij	bds->msg_cbytes = sds->msg_cbytes;
381285612Sdelphij	bds->msg_qnum = sds->msg_qnum;
382285612Sdelphij	bds->msg_qbytes = sds->msg_qbytes;
383285612Sdelphij	bds->msg_lspid = sds->msg_lspid;
384285612Sdelphij	bds->msg_lrpid = sds->msg_lrpid;
385181834Sroberto	bds->msg_stime = sds->msg_stime;
386285612Sdelphij	bds->msg_pad1 = sds->msg_pad1;
387285612Sdelphij	bds->msg_rtime = sds->msg_rtime;
388285612Sdelphij	bds->msg_pad2 = sds->msg_pad2;
389285612Sdelphij	bds->msg_ctime = sds->msg_ctime;
390181834Sroberto	bds->msg_pad3 = sds->msg_pad3;
391285612Sdelphij
392181834Sroberto	/* use the padding for the rest of the fields */
393285612Sdelphij	{
394285612Sdelphij		short *pad = (short *) bds->msg_pad4;
395181834Sroberto		pad[0] = sds->msg_cv;
396181834Sroberto		pad[1] = sds->msg_qnum_cv;
397181834Sroberto	}
398285612Sdelphij}
399285612Sdelphij
400181834Srobertostruct svr4_sys_msgsnd_args {
401181834Sroberto	int what;
402181834Sroberto	int msqid;
403181834Sroberto	void * msgp;
404285612Sdelphij	size_t msgsz;
405181834Sroberto	int msgflg;
406285612Sdelphij};
407285612Sdelphij
408285612Sdelphijstatic int
409285612Sdelphijsvr4_msgsnd(td, v)
410285612Sdelphij	struct thread *td;
411181834Sroberto	void *v;
412181834Sroberto{
413181834Sroberto	struct svr4_sys_msgsnd_args *uap = v;
414181834Sroberto	struct msgsnd_args ap;
415285612Sdelphij
416181834Sroberto	ap.msqid = uap->msqid;
417285612Sdelphij	ap.msgp = uap->msgp;
418285612Sdelphij	ap.msgsz = uap->msgsz;
419285612Sdelphij	ap.msgflg = uap->msgflg;
420285612Sdelphij
421285612Sdelphij	return msgsnd(td, &ap);
422285612Sdelphij}
423285612Sdelphij
424285612Sdelphijstruct svr4_sys_msgrcv_args {
425181834Sroberto	int what;
426285612Sdelphij	int msqid;
427285612Sdelphij	void * msgp;
428285612Sdelphij	size_t msgsz;
429181834Sroberto	long msgtyp;
430285612Sdelphij	int msgflg;
431285612Sdelphij};
432285612Sdelphij
433285612Sdelphijstatic int
434285612Sdelphijsvr4_msgrcv(td, v)
435285612Sdelphij	struct thread *td;
436285612Sdelphij	void *v;
437285612Sdelphij{
438285612Sdelphij	struct svr4_sys_msgrcv_args *uap = v;
439285612Sdelphij	struct msgrcv_args ap;
440285612Sdelphij
441285612Sdelphij	ap.msqid = uap->msqid;
442285612Sdelphij	ap.msgp = uap->msgp;
443285612Sdelphij	ap.msgsz = uap->msgsz;
444285612Sdelphij	ap.msgtyp = uap->msgtyp;
445285612Sdelphij	ap.msgflg = uap->msgflg;
446285612Sdelphij
447285612Sdelphij	return msgrcv(td, &ap);
448285612Sdelphij}
449285612Sdelphij
450285612Sdelphijstruct svr4_sys_msgget_args {
451285612Sdelphij	int what;
452285612Sdelphij	svr4_key_t key;
453285612Sdelphij	int msgflg;
454285612Sdelphij};
455285612Sdelphij
456285612Sdelphijstatic int
457285612Sdelphijsvr4_msgget(td, v)
458285612Sdelphij	struct thread *td;
459285612Sdelphij	void *v;
460181834Sroberto{
461181834Sroberto	struct svr4_sys_msgget_args *uap = v;
462181834Sroberto	struct msgget_args ap;
463181834Sroberto
464285612Sdelphij	ap.key = uap->key;
465181834Sroberto	ap.msgflg = uap->msgflg;
466
467	return msgget(td, &ap);
468}
469
470struct svr4_sys_msgctl_args {
471	int what;
472	int msqid;
473	int cmd;
474	struct svr4_msqid_ds * buf;
475};
476
477static int
478svr4_msgctl(td, v)
479	struct thread *td;
480	void *v;
481{
482	struct svr4_sys_msgctl_args *uap = v;
483	struct svr4_msqid_ds ss;
484	struct msqid_ds bs;
485	int error;
486
487	switch (uap->cmd) {
488	case SVR4_IPC_STAT:
489		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
490		if (error)
491			return error;
492		bsd_to_svr4_msqid_ds(&bs, &ss);
493		return copyout(&ss, uap->buf, sizeof ss);
494
495	case SVR4_IPC_SET:
496		error = copyin(uap->buf, &ss, sizeof ss);
497		if (error)
498			return error;
499		svr4_to_bsd_msqid_ds(&ss, &bs);
500		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
501
502	case SVR4_IPC_RMID:
503		error = copyin(uap->buf, &ss, sizeof ss);
504		if (error)
505			return error;
506		svr4_to_bsd_msqid_ds(&ss, &bs);
507		return (kern_msgctl(td, uap->msqid, IPC_RMID, &bs));
508
509	default:
510		return EINVAL;
511	}
512}
513
514int
515svr4_sys_msgsys(td, uap)
516	struct thread *td;
517	struct svr4_sys_msgsys_args *uap;
518{
519
520	DPRINTF(("svr4_msgsys(%d)\n", uap->what));
521
522	switch (uap->what) {
523	case SVR4_msgsnd:
524		return svr4_msgsnd(td, uap);
525	case SVR4_msgrcv:
526		return svr4_msgrcv(td, uap);
527	case SVR4_msgget:
528		return svr4_msgget(td, uap);
529	case SVR4_msgctl:
530		return svr4_msgctl(td, uap);
531	default:
532		return EINVAL;
533	}
534}
535
536MODULE_DEPEND(svr4elf, sysvmsg, 1, 1, 1);
537#endif
538
539#ifdef SYSVSHM
540
541static void
542bsd_to_svr4_shmid_ds(bds, sds)
543	const struct shmid_ds *bds;
544	struct svr4_shmid_ds *sds;
545{
546	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
547	sds->shm_segsz = bds->shm_segsz;
548	sds->shm_lkcnt = 0;
549	sds->shm_lpid = bds->shm_lpid;
550	sds->shm_cpid = bds->shm_cpid;
551	sds->shm_amp = bds->shm_internal;
552	sds->shm_nattch = bds->shm_nattch;
553	sds->shm_cnattch = 0;
554	sds->shm_atime = bds->shm_atime;
555	sds->shm_pad1 = 0;
556	sds->shm_dtime = bds->shm_dtime;
557	sds->shm_pad2 = 0;
558	sds->shm_ctime = bds->shm_ctime;
559	sds->shm_pad3 = 0;
560}
561
562static void
563svr4_to_bsd_shmid_ds(sds, bds)
564	const struct svr4_shmid_ds *sds;
565	struct shmid_ds *bds;
566{
567	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
568	bds->shm_segsz = sds->shm_segsz;
569	bds->shm_lpid = sds->shm_lpid;
570	bds->shm_cpid = sds->shm_cpid;
571	bds->shm_internal = sds->shm_amp;
572	bds->shm_nattch = sds->shm_nattch;
573	bds->shm_atime = sds->shm_atime;
574	bds->shm_dtime = sds->shm_dtime;
575	bds->shm_ctime = sds->shm_ctime;
576}
577
578struct svr4_sys_shmat_args {
579	int what;
580	int shmid;
581	void * shmaddr;
582	int shmflg;
583};
584
585static int
586svr4_shmat(td, v)
587	struct thread *td;
588	void *v;
589{
590	struct svr4_sys_shmat_args *uap = v;
591	struct shmat_args ap;
592
593	ap.shmid = uap->shmid;
594	ap.shmaddr = uap->shmaddr;
595	ap.shmflg = uap->shmflg;
596
597	return shmat(td, &ap);
598}
599
600struct svr4_sys_shmdt_args {
601	int what;
602	void * shmaddr;
603};
604
605static int
606svr4_shmdt(td, v)
607	struct thread *td;
608	void *v;
609{
610	struct svr4_sys_shmdt_args *uap = v;
611	struct shmdt_args ap;
612
613	ap.shmaddr = uap->shmaddr;
614
615	return shmdt(td, &ap);
616}
617
618struct svr4_sys_shmget_args {
619	int what;
620	key_t key;
621	int size;
622	int shmflg;
623};
624
625static int
626svr4_shmget(td, v)
627	struct thread *td;
628	void *v;
629{
630	struct svr4_sys_shmget_args *uap = v;
631	struct shmget_args ap;
632
633	ap.key = uap->key;
634	ap.size = uap->size;
635	ap.shmflg = uap->shmflg;
636
637	return shmget(td, &ap);
638}
639
640struct svr4_sys_shmctl_args {
641	int what;
642	int shmid;
643	int cmd;
644	struct svr4_shmid_ds * buf;
645};
646
647int
648svr4_shmctl(td, v)
649	struct thread *td;
650	void *v;
651{
652	struct svr4_sys_shmctl_args *uap = v;
653	struct shmid_ds bs;
654	struct svr4_shmid_ds ss;
655	size_t bufsize;
656	int cmd, error;
657
658	if (uap->buf != NULL) {
659		switch (uap->cmd) {
660		case SVR4_IPC_SET:
661		case SVR4_IPC_RMID:
662		case SVR4_SHM_LOCK:
663		case SVR4_SHM_UNLOCK:
664			error = copyin(uap->buf, &ss, sizeof(ss));
665			if (error)
666				return (error);
667			svr4_to_bsd_shmid_ds(&ss, &bs);
668			break;
669		default:
670			return (EINVAL);
671		}
672	}
673
674	switch (uap->cmd) {
675	case SVR4_IPC_STAT:
676		cmd = IPC_STAT;
677		break;
678	case SVR4_IPC_SET:
679		cmd = IPC_SET;
680		break;
681	case SVR4_IPC_RMID:
682		cmd = IPC_RMID;
683		break;
684	case SVR4_SHM_LOCK:
685		cmd = SHM_LOCK;
686		break;
687	case SVR4_SHM_UNLOCK:
688		cmd = SHM_UNLOCK;
689		break;
690	default:
691		return (EINVAL);
692	}
693
694	error = kern_shmctl(td, uap->shmid, cmd, &bs, &bufsize);
695	if (error)
696		return (error);
697
698	switch (uap->cmd) {
699	case SVR4_IPC_STAT:
700		if (uap->buf != NULL) {
701			bsd_to_svr4_shmid_ds(&bs, &ss);
702			error = copyout(&ss, uap->buf, sizeof(ss));
703		}
704		break;
705	}
706
707	return (error);
708}
709
710int
711svr4_sys_shmsys(td, uap)
712	struct thread *td;
713	struct svr4_sys_shmsys_args *uap;
714{
715
716	DPRINTF(("svr4_shmsys(%d)\n", uap->what));
717
718	switch (uap->what) {
719	case SVR4_shmat:
720		return svr4_shmat(td, uap);
721	case SVR4_shmdt:
722		return svr4_shmdt(td, uap);
723	case SVR4_shmget:
724		return svr4_shmget(td, uap);
725	case SVR4_shmctl:
726		return svr4_shmctl(td, uap);
727	default:
728		return ENOSYS;
729	}
730}
731
732MODULE_DEPEND(svr4elf, sysvshm, 1, 1, 1);
733#endif /* SYSVSHM */
734