svr4_ipc.c revision 54300
1152251Srwatson/*
2152251Srwatson * $FreeBSD: head/sys/compat/svr4/svr4_ipc.c 54300 1999-12-08 10:51:17Z newton $
3152251Srwatson *	Derived from:
4152251Srwatson *	$NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $	*/
5152251Srwatson
6152251Srwatson/*-
7152251Srwatson * Original copyright:
8152251Srwatson *
9152251Srwatson * Copyright (c) 1995 The NetBSD Foundation, Inc.
10152251Srwatson * All rights reserved.
11152251Srwatson *
12152251Srwatson * This code is derived from software contributed to The NetBSD Foundation
13152251Srwatson * by Christos Zoulas.
14152251Srwatson *
15152251Srwatson * Redistribution and use in source and binary forms, with or without
16152251Srwatson * modification, are permitted provided that the following conditions
17152251Srwatson * are met:
18152251Srwatson * 1. Redistributions of source code must retain the above copyright
19152251Srwatson *    notice, this list of conditions and the following disclaimer.
20152251Srwatson * 2. Redistributions in binary form must reproduce the above copyright
21152251Srwatson *    notice, this list of conditions and the following disclaimer in the
22152251Srwatson *    documentation and/or other materials provided with the distribution.
23152251Srwatson * 3. All advertising materials mentioning features or use of this software
24152251Srwatson *    must display the following acknowledgement:
25152251Srwatson *        This product includes software developed by the NetBSD
26152251Srwatson *        Foundation, Inc. and its contributors.
27152251Srwatson * 4. Neither the name of The NetBSD Foundation nor the names of its
28152251Srwatson *    contributors may be used to endorse or promote products derived
29152251Srwatson *    from this software without specific prior written permission.
30152251Srwatson *
31152251Srwatson * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
32152251Srwatson * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
33152251Srwatson * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34152251Srwatson * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
35152251Srwatson * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36152251Srwatson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37152251Srwatson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38152251Srwatson * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39152251Srwatson * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40152251Srwatson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41152251Srwatson * POSSIBILITY OF SUCH DAMAGE.
42152251Srwatson */
43152251Srwatson
44152251Srwatson/*
45152251Srwatson * Portions of this code have been derived from software contributed
46152251Srwatson * to the FreeBSD Project by Mark Newton.
47152251Srwatson *
48152251Srwatson * Copyright (c) 1999 Mark Newton
49152251Srwatson * All rights reserved.
50152251Srwatson *
51152251Srwatson * Redistribution and use in source and binary forms, with or without
52152251Srwatson * modification, are permitted provided that the following conditions
53152251Srwatson * are met:
54152251Srwatson * 1. Redistributions of source code must retain the above copyright
55152251Srwatson *    notice, this list of conditions and the following disclaimer.
56152251Srwatson * 2. Redistributions in binary form must reproduce the above copyright
57152251Srwatson *    notice, this list of conditions and the following disclaimer in the
58152251Srwatson *    documentation and/or other materials provided with the distribution.
59152251Srwatson * 3. The name of the author may not be used to endorse or promote products
60152251Srwatson *    derived from this software without specific prior written permission
61152251Srwatson *
62152251Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
63152251Srwatson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
64152251Srwatson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
65152251Srwatson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
66152251Srwatson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
67152251Srwatson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
68152251Srwatson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
69152251Srwatson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70152251Srwatson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
71152251Srwatson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72152251Srwatson *
73152251Srwatson * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due
74152251Srwatson * to preprocessor conditionals).  A nice project for a kernel hacking
75152251Srwatson * novice might be to MakeItGo, but I have more important fish to fry
76152251Srwatson * at present.
77152251Srwatson *
78152251Srwatson */
79152251Srwatson
80152251Srwatson#include <sys/types.h>
81152251Srwatson#include <sys/param.h>
82152251Srwatson#include <sys/kernel.h>
83152251Srwatson#include <sys/proc.h>
84152251Srwatson#include <sys/time.h>
85152251Srwatson
86152251Srwatson#include <svr4/svr4.h>
87152251Srwatson#include <svr4/svr4_types.h>
88152251Srwatson#include <svr4/svr4_signal.h>
89152251Srwatson#include <svr4/svr4_proto.h>
90152251Srwatson#include <svr4/svr4_util.h>
91152251Srwatson#include <svr4/svr4_ipc.h>
92152251Srwatson
93152251Srwatson#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
94152251Srwatsonstatic void svr4_to_bsd_ipc_perm __P((const struct svr4_ipc_perm *,
95152251Srwatson				      struct ipc_perm *));
96152251Srwatsonstatic void bsd_to_svr4_ipc_perm __P((const struct ipc_perm *,
97152251Srwatson				      struct svr4_ipc_perm *));
98152251Srwatson#endif
99152251Srwatson
100152251Srwatson#ifdef SYSVSEM
101152251Srwatsonstatic void bsd_to_svr4_semid_ds __P((const struct semid_ds *,
102152251Srwatson				      struct svr4_semid_ds *));
103152251Srwatsonstatic void svr4_to_bsd_semid_ds __P((const struct svr4_semid_ds *,
104152251Srwatson				      struct semid_ds *));
105152251Srwatsonstatic int svr4_setsemun __P((caddr_t *sgp, union semun **argp,
106152251Srwatson			      union semun *usp));
107152251Srwatsonstatic int svr4_semop __P((struct proc *, void *, register_t *));
108152251Srwatsonstatic int svr4_semget __P((struct proc *, void *, register_t *));
109152251Srwatsonstatic int svr4_semctl __P((struct proc *, void *, register_t *));
110152251Srwatson#endif
111152251Srwatson
112152251Srwatson#ifdef SYSVMSG
113152251Srwatsonstatic void bsd_to_svr4_msqid_ds __P((const struct msqid_ds *,
114152251Srwatson				      struct svr4_msqid_ds *));
115152251Srwatsonstatic void svr4_to_bsd_msqid_ds __P((const struct svr4_msqid_ds *,
116152251Srwatson				      struct msqid_ds *));
117152251Srwatsonstatic int svr4_msgsnd __P((struct proc *, void *, register_t *));
118152251Srwatsonstatic int svr4_msgrcv __P((struct proc *, void *, register_t *));
119152251Srwatsonstatic int svr4_msgget __P((struct proc *, void *, register_t *));
120152251Srwatsonstatic int svr4_msgctl __P((struct proc *, void *, register_t *));
121152251Srwatson#endif
122152251Srwatson
123152251Srwatson#ifdef SYSVSHM
124152251Srwatsonstatic void bsd_to_svr4_shmid_ds __P((const struct shmid_ds *,
125152251Srwatson				      struct svr4_shmid_ds *));
126152251Srwatsonstatic void svr4_to_bsd_shmid_ds __P((const struct svr4_shmid_ds *,
127152251Srwatson				      struct shmid_ds *));
128152251Srwatsonstatic int svr4_shmat __P((struct proc *, void *, register_t *));
129152251Srwatsonstatic int svr4_shmdt __P((struct proc *, void *, register_t *));
130152251Srwatsonstatic int svr4_shmget __P((struct proc *, void *, register_t *));
131152251Srwatsonstatic int svr4_shmctl __P((struct proc *, void *, register_t *));
132152251Srwatson#endif
133152251Srwatson
134152251Srwatson#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
135152251Srwatson
136152251Srwatsonstatic void
137152251Srwatsonsvr4_to_bsd_ipc_perm(spp, bpp)
138152251Srwatson	const struct svr4_ipc_perm *spp;
139152251Srwatson	struct ipc_perm *bpp;
140152251Srwatson{
141152251Srwatson	bpp->key = spp->key;
142152251Srwatson	bpp->uid = spp->uid;
143152251Srwatson	bpp->gid = spp->gid;
144152251Srwatson	bpp->cuid = spp->cuid;
145152251Srwatson	bpp->cgid = spp->cgid;
146152251Srwatson	bpp->mode = spp->mode;
147152251Srwatson	bpp->seq = spp->seq;
148152251Srwatson}
149152251Srwatson
150152251Srwatsonstatic void
151152251Srwatsonbsd_to_svr4_ipc_perm(bpp, spp)
152152251Srwatson	const struct ipc_perm *bpp;
153152251Srwatson	struct svr4_ipc_perm *spp;
154152251Srwatson{
155152251Srwatson	spp->key = bpp->key;
156152251Srwatson	spp->uid = bpp->uid;
157152251Srwatson	spp->gid = bpp->gid;
158152251Srwatson	spp->cuid = bpp->cuid;
159152251Srwatson	spp->cgid = bpp->cgid;
160152251Srwatson	spp->mode = bpp->mode;
161152251Srwatson	spp->seq = bpp->seq;
162152251Srwatson}
163152251Srwatson#endif
164152251Srwatson
165152251Srwatson#ifdef SYSVSEM
166152251Srwatsonstatic void
167152251Srwatsonbsd_to_svr4_semid_ds(bds, sds)
168152251Srwatson	const struct semid_ds *bds;
169152251Srwatson	struct svr4_semid_ds *sds;
170152251Srwatson{
171152251Srwatson	bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
172152251Srwatson	sds->sem_base = (struct svr4_sem *) bds->sem_base;
173152251Srwatson	sds->sem_nsems = bds->sem_nsems;
174152251Srwatson	sds->sem_otime = bds->sem_otime;
175152251Srwatson	sds->sem_pad1 = bds->sem_pad1;
176152251Srwatson	sds->sem_ctime = bds->sem_ctime;
177152251Srwatson	sds->sem_pad2 = bds->sem_pad2;
178152251Srwatson}
179152251Srwatson
180152251Srwatsonstatic void
181152251Srwatsonsvr4_to_bsd_semid_ds(sds, bds)
182152251Srwatson	const struct svr4_semid_ds *sds;
183152251Srwatson	struct semid_ds *bds;
184152251Srwatson{
185152251Srwatson	svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
186152251Srwatson	bds->sem_base = (struct sem *) bds->sem_base;
187152251Srwatson	bds->sem_nsems = sds->sem_nsems;
188152251Srwatson	bds->sem_otime = sds->sem_otime;
189152251Srwatson	bds->sem_pad1 = sds->sem_pad1;
190152251Srwatson	bds->sem_ctime = sds->sem_ctime;
191152251Srwatson	bds->sem_pad2 = sds->sem_pad2;
192152251Srwatson}
193152251Srwatson
194152251Srwatsonstatic int
195152251Srwatsonsvr4_setsemun(sgp, argp, usp)
196152251Srwatson	caddr_t *sgp;
197152251Srwatson	union semun **argp;
198152251Srwatson	union semun *usp;
199152251Srwatson{
200152251Srwatson	*argp = stackgap_alloc(sgp, sizeof(union semun));
201152251Srwatson	return copyout((caddr_t)usp, *argp, sizeof(union semun));
202152251Srwatson}
203152251Srwatson
204152251Srwatsonstruct svr4_sys_semctl_args {
205152251Srwatson	syscallarg(int) what;
206152251Srwatson	syscallarg(int) semid;
207152251Srwatson	syscallarg(int) semnum;
208152251Srwatson	syscallarg(int) cmd;
209152251Srwatson	syscallarg(union semun) arg;
210152251Srwatson};
211152251Srwatson
212152251Srwatsonstatic int
213152251Srwatsonsvr4_semctl(p, v, retval)
214152251Srwatson	struct proc *p;
215152251Srwatson	void *v;
216152251Srwatson	register_t *retval;
217152251Srwatson{
218152251Srwatson	int error;
219152251Srwatson	struct svr4_sys_semctl_args *uap = v;
220152251Srwatson	struct sys___semctl_args ap;
221152251Srwatson	struct svr4_semid_ds ss;
222152251Srwatson	struct semid_ds bs, *bsp;
223152251Srwatson	caddr_t sg = stackgap_init(p->p_emul);
224152251Srwatson
225152251Srwatson	SCARG(&ap, semid) = SCARG(uap, semid);
226152251Srwatson	SCARG(&ap, semnum) = SCARG(uap, semnum);
227152251Srwatson
228152251Srwatson	switch (SCARG(uap, cmd)) {
229152251Srwatson	case SVR4_SEM_GETZCNT:
230152251Srwatson	case SVR4_SEM_GETNCNT:
231152251Srwatson	case SVR4_SEM_GETPID:
232152251Srwatson	case SVR4_SEM_GETVAL:
233152251Srwatson		switch (SCARG(uap, cmd)) {
234152251Srwatson		case SVR4_SEM_GETZCNT:
235152251Srwatson			SCARG(&ap, cmd) = GETZCNT;
236152251Srwatson			break;
237152251Srwatson		case SVR4_SEM_GETNCNT:
238152251Srwatson			SCARG(&ap, cmd) = GETNCNT;
239152251Srwatson			break;
240152251Srwatson		case SVR4_SEM_GETPID:
241152251Srwatson			SCARG(&ap, cmd) = GETPID;
242152251Srwatson			break;
243152251Srwatson		case SVR4_SEM_GETVAL:
244152251Srwatson			SCARG(&ap, cmd) = GETVAL;
245152251Srwatson			break;
246152251Srwatson		}
247152251Srwatson		return sys___semctl(p, &ap, retval);
248152251Srwatson
249152251Srwatson	case SVR4_SEM_SETVAL:
250152251Srwatson		error = svr4_setsemun(&sg, &SCARG(&ap, arg), &SCARG(uap, arg));
251152251Srwatson		if (error)
252152251Srwatson			return error;
253152251Srwatson		SCARG(&ap, cmd) = SETVAL;
254152251Srwatson		return sys___semctl(p, &ap, retval);
255152251Srwatson
256152251Srwatson	case SVR4_SEM_GETALL:
257152251Srwatson		error = svr4_setsemun(&sg, &SCARG(&ap, arg), &SCARG(uap, arg));
258152251Srwatson		if (error)
259152251Srwatson			return error;
260152251Srwatson		SCARG(&ap, cmd) = GETVAL;
261152251Srwatson		return sys___semctl(p, &ap, retval);
262152251Srwatson
263152251Srwatson	case SVR4_SEM_SETALL:
264152251Srwatson		error = svr4_setsemun(&sg, &SCARG(&ap, arg), &SCARG(uap, arg));
265152251Srwatson		if (error)
266152251Srwatson			return error;
267152251Srwatson		SCARG(&ap, cmd) = SETVAL;
268152251Srwatson		return sys___semctl(p, &ap, retval);
269152251Srwatson
270152251Srwatson	case SVR4_IPC_STAT:
271152251Srwatson                SCARG(&ap, cmd) = IPC_STAT;
272152251Srwatson		bsp = stackgap_alloc(&sg, sizeof(bs));
273152251Srwatson		error = svr4_setsemun(&sg, &SCARG(&ap, arg),
274152251Srwatson				      (union semun *)&bsp);
275152251Srwatson		if (error)
276152251Srwatson			return error;
277152251Srwatson                if ((error = sys___semctl(p, &ap, retval)) != 0)
278152251Srwatson                        return error;
279152251Srwatson		error = copyin((caddr_t)bsp, (caddr_t)&bs, sizeof(bs));
280152251Srwatson                if (error)
281152251Srwatson                        return error;
282152251Srwatson                bsd_to_svr4_semid_ds(&bs, &ss);
283152251Srwatson		return copyout(&ss, SCARG(uap, arg).buf, sizeof(ss));
284152251Srwatson
285152251Srwatson	case SVR4_IPC_SET:
286152251Srwatson		SCARG(&ap, cmd) = IPC_SET;
287152251Srwatson		bsp = stackgap_alloc(&sg, sizeof(bs));
288152251Srwatson		error = svr4_setsemun(&sg, &SCARG(&ap, arg),
289152251Srwatson				      (union semun *)&bsp);
290152251Srwatson		if (error)
291152251Srwatson			return error;
292152251Srwatson		error = copyin(SCARG(uap, arg).buf, (caddr_t) &ss, sizeof ss);
293152251Srwatson                if (error)
294152251Srwatson                        return error;
295152251Srwatson                svr4_to_bsd_semid_ds(&ss, &bs);
296152251Srwatson		error = copyout(&bs, bsp, sizeof(bs));
297152251Srwatson                if (error)
298152251Srwatson                        return error;
299152251Srwatson		return sys___semctl(p, &ap, retval);
300152251Srwatson
301152251Srwatson	case SVR4_IPC_RMID:
302152251Srwatson		SCARG(&ap, cmd) = IPC_RMID;
303152251Srwatson		bsp = stackgap_alloc(&sg, sizeof(bs));
304152251Srwatson		error = svr4_setsemun(&sg, &SCARG(&ap, arg),
305152251Srwatson				      (union semun *)&bsp);
306152251Srwatson		if (error)
307152251Srwatson			return error;
308		error = copyin(SCARG(uap, arg).buf, &ss, sizeof ss);
309                if (error)
310                        return error;
311                svr4_to_bsd_semid_ds(&ss, &bs);
312		error = copyout(&bs, bsp, sizeof(bs));
313		if (error)
314			return error;
315		return sys___semctl(p, &ap, retval);
316
317	default:
318		return EINVAL;
319	}
320}
321
322struct svr4_sys_semget_args {
323	syscallarg(int) what;
324	syscallarg(svr4_key_t) key;
325	syscallarg(int) nsems;
326	syscallarg(int) semflg;
327};
328
329static int
330svr4_semget(p, v, retval)
331	struct proc *p;
332	void *v;
333	register_t *retval;
334{
335	struct svr4_sys_semget_args *uap = v;
336	struct sys_semget_args ap;
337
338	SCARG(&ap, key) = SCARG(uap, key);
339	SCARG(&ap, nsems) = SCARG(uap, nsems);
340	SCARG(&ap, semflg) = SCARG(uap, semflg);
341
342	return sys_semget(p, &ap, retval);
343}
344
345struct svr4_sys_semop_args {
346	syscallarg(int) what;
347	syscallarg(int) semid;
348	syscallarg(struct svr4_sembuf *) sops;
349	syscallarg(u_int) nsops;
350};
351
352static int
353svr4_semop(p, v, retval)
354	struct proc *p;
355	void *v;
356	register_t *retval;
357{
358	struct svr4_sys_semop_args *uap = v;
359	struct sys_semop_args ap;
360
361	SCARG(&ap, semid) = SCARG(uap, semid);
362	/* These are the same */
363	SCARG(&ap, sops) = (struct sembuf *) SCARG(uap, sops);
364	SCARG(&ap, nsops) = SCARG(uap, nsops);
365
366	return sys_semop(p, &ap, retval);
367}
368
369int
370svr4_sys_semsys(p, v, retval)
371	struct proc *p;
372	void *v;
373	register_t *retval;
374{
375	struct svr4_sys_semsys_args *uap = v;
376
377	DPRINTF(("svr4_semsys(%d)\n", SCARG(uap, what)));
378
379	switch (SCARG(uap, what)) {
380	case SVR4_semctl:
381		return svr4_semctl(p, v, retval);
382	case SVR4_semget:
383		return svr4_semget(p, v, retval);
384	case SVR4_semop:
385		return svr4_semop(p, v, retval);
386	default:
387		return EINVAL;
388	}
389}
390#endif
391
392#ifdef SYSVMSG
393static void
394bsd_to_svr4_msqid_ds(bds, sds)
395	const struct msqid_ds *bds;
396	struct svr4_msqid_ds *sds;
397{
398	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
399	sds->msg_first = (struct svr4_msg *) bds->msg_first;
400	sds->msg_last = (struct svr4_msg *) bds->msg_last;
401	sds->msg_cbytes = bds->msg_cbytes;
402	sds->msg_qnum = bds->msg_qnum;
403	sds->msg_qbytes = bds->msg_qbytes;
404	sds->msg_lspid = bds->msg_lspid;
405	sds->msg_lrpid = bds->msg_lrpid;
406	sds->msg_stime = bds->msg_stime;
407	sds->msg_pad1 = bds->msg_pad1;
408	sds->msg_rtime = bds->msg_rtime;
409	sds->msg_pad2 = bds->msg_pad2;
410	sds->msg_ctime = bds->msg_ctime;
411	sds->msg_pad3 = bds->msg_pad3;
412
413	/* use the padding for the rest of the fields */
414	{
415		const short *pad = (const short *) bds->msg_pad4;
416		sds->msg_cv = pad[0];
417		sds->msg_qnum_cv = pad[1];
418	}
419}
420
421static void
422svr4_to_bsd_msqid_ds(sds, bds)
423	const struct svr4_msqid_ds *sds;
424	struct msqid_ds *bds;
425{
426	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
427	bds->msg_first = (struct msg *) sds->msg_first;
428	bds->msg_last = (struct msg *) sds->msg_last;
429	bds->msg_cbytes = sds->msg_cbytes;
430	bds->msg_qnum = sds->msg_qnum;
431	bds->msg_qbytes = sds->msg_qbytes;
432	bds->msg_lspid = sds->msg_lspid;
433	bds->msg_lrpid = sds->msg_lrpid;
434	bds->msg_stime = sds->msg_stime;
435	bds->msg_pad1 = sds->msg_pad1;
436	bds->msg_rtime = sds->msg_rtime;
437	bds->msg_pad2 = sds->msg_pad2;
438	bds->msg_ctime = sds->msg_ctime;
439	bds->msg_pad3 = sds->msg_pad3;
440
441	/* use the padding for the rest of the fields */
442	{
443		short *pad = (short *) bds->msg_pad4;
444		pad[0] = sds->msg_cv;
445		pad[1] = sds->msg_qnum_cv;
446	}
447}
448
449struct svr4_sys_msgsnd_args {
450	syscallarg(int) what;
451	syscallarg(int) msqid;
452	syscallarg(void *) msgp;
453	syscallarg(size_t) msgsz;
454	syscallarg(int) msgflg;
455};
456
457static int
458svr4_msgsnd(p, v, retval)
459	struct proc *p;
460	void *v;
461	register_t *retval;
462{
463	struct svr4_sys_msgsnd_args *uap = v;
464	struct sys_msgsnd_args ap;
465
466	SCARG(&ap, msqid) = SCARG(uap, msqid);
467	SCARG(&ap, msgp) = SCARG(uap, msgp);
468	SCARG(&ap, msgsz) = SCARG(uap, msgsz);
469	SCARG(&ap, msgflg) = SCARG(uap, msgflg);
470
471	return sys_msgsnd(p, &ap, retval);
472}
473
474struct svr4_sys_msgrcv_args {
475	syscallarg(int) what;
476	syscallarg(int) msqid;
477	syscallarg(void *) msgp;
478	syscallarg(size_t) msgsz;
479	syscallarg(long) msgtyp;
480	syscallarg(int) msgflg;
481};
482
483static int
484svr4_msgrcv(p, v, retval)
485	struct proc *p;
486	void *v;
487	register_t *retval;
488{
489	struct svr4_sys_msgrcv_args *uap = v;
490	struct sys_msgrcv_args ap;
491
492	SCARG(&ap, msqid) = SCARG(uap, msqid);
493	SCARG(&ap, msgp) = SCARG(uap, msgp);
494	SCARG(&ap, msgsz) = SCARG(uap, msgsz);
495	SCARG(&ap, msgtyp) = SCARG(uap, msgtyp);
496	SCARG(&ap, msgflg) = SCARG(uap, msgflg);
497
498	return sys_msgrcv(p, &ap, retval);
499}
500
501struct svr4_sys_msgget_args {
502	syscallarg(int) what;
503	syscallarg(svr4_key_t) key;
504	syscallarg(int) msgflg;
505};
506
507static int
508svr4_msgget(p, v, retval)
509	struct proc *p;
510	void *v;
511	register_t *retval;
512{
513	struct svr4_sys_msgget_args *uap = v;
514	struct sys_msgget_args ap;
515
516	SCARG(&ap, key) = SCARG(uap, key);
517	SCARG(&ap, msgflg) = SCARG(uap, msgflg);
518
519	return sys_msgget(p, &ap, retval);
520}
521
522struct svr4_sys_msgctl_args {
523	syscallarg(int) what;
524	syscallarg(int) msqid;
525	syscallarg(int) cmd;
526	syscallarg(struct svr4_msqid_ds *) buf;
527};
528
529static int
530svr4_msgctl(p, v, retval)
531	struct proc *p;
532	void *v;
533	register_t *retval;
534{
535	int error;
536	struct svr4_sys_msgctl_args *uap = v;
537	struct sys_msgctl_args ap;
538	struct svr4_msqid_ds ss;
539	struct msqid_ds bs;
540	caddr_t sg = stackgap_init(p->p_emul);
541
542	SCARG(&ap, msqid) = SCARG(uap, msqid);
543	SCARG(&ap, cmd) = SCARG(uap, cmd);
544	SCARG(&ap, buf) = stackgap_alloc(&sg, sizeof(bs));
545
546	switch (SCARG(uap, cmd)) {
547	case SVR4_IPC_STAT:
548		SCARG(&ap, cmd) = IPC_STAT;
549		if ((error = sys_msgctl(p, &ap, retval)) != 0)
550			return error;
551		error = copyin(&bs, SCARG(&ap, buf), sizeof bs);
552		if (error)
553			return error;
554		bsd_to_svr4_msqid_ds(&bs, &ss);
555		return copyout(&ss, SCARG(uap, buf), sizeof ss);
556
557	case SVR4_IPC_SET:
558		SCARG(&ap, cmd) = IPC_SET;
559		error = copyin(SCARG(uap, buf), &ss, sizeof ss);
560		if (error)
561			return error;
562		svr4_to_bsd_msqid_ds(&ss, &bs);
563		error = copyout(&bs, SCARG(&ap, buf), sizeof bs);
564		if (error)
565			return error;
566		return sys_msgctl(p, &ap, retval);
567
568	case SVR4_IPC_RMID:
569		SCARG(&ap, cmd) = IPC_RMID;
570		error = copyin(SCARG(uap, buf), &ss, sizeof ss);
571		if (error)
572			return error;
573		svr4_to_bsd_msqid_ds(&ss, &bs);
574		error = copyout(&bs, SCARG(&ap, buf), sizeof bs);
575		if (error)
576			return error;
577		return sys_msgctl(p, &ap, retval);
578
579	default:
580		return EINVAL;
581	}
582}
583
584int
585svr4_sys_msgsys(p, v, retval)
586	struct proc *p;
587	void *v;
588	register_t *retval;
589{
590	struct svr4_sys_msgsys_args *uap = v;
591
592	DPRINTF(("svr4_msgsys(%d)\n", SCARG(uap, what)));
593
594	switch (SCARG(uap, what)) {
595	case SVR4_msgsnd:
596		return svr4_msgsnd(p, v, retval);
597	case SVR4_msgrcv:
598		return svr4_msgrcv(p, v, retval);
599	case SVR4_msgget:
600		return svr4_msgget(p, v, retval);
601	case SVR4_msgctl:
602		return svr4_msgctl(p, v, retval);
603	default:
604		return EINVAL;
605	}
606}
607#endif
608
609#ifdef SYSVSHM
610
611static void
612bsd_to_svr4_shmid_ds(bds, sds)
613	const struct shmid_ds *bds;
614	struct svr4_shmid_ds *sds;
615{
616	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
617	sds->shm_segsz = bds->shm_segsz;
618	sds->shm_lkcnt = 0;
619	sds->shm_lpid = bds->shm_lpid;
620	sds->shm_cpid = bds->shm_cpid;
621	sds->shm_amp = bds->shm_internal;
622	sds->shm_nattch = bds->shm_nattch;
623	sds->shm_cnattch = 0;
624	sds->shm_atime = bds->shm_atime;
625	sds->shm_pad1 = 0;
626	sds->shm_dtime = bds->shm_dtime;
627	sds->shm_pad2 = 0;
628	sds->shm_ctime = bds->shm_ctime;
629	sds->shm_pad3 = 0;
630}
631
632static void
633svr4_to_bsd_shmid_ds(sds, bds)
634	const struct svr4_shmid_ds *sds;
635	struct shmid_ds *bds;
636{
637	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
638	bds->shm_segsz = sds->shm_segsz;
639	bds->shm_lpid = sds->shm_lpid;
640	bds->shm_cpid = sds->shm_cpid;
641	bds->shm_internal = sds->shm_amp;
642	bds->shm_nattch = sds->shm_nattch;
643	bds->shm_atime = sds->shm_atime;
644	bds->shm_dtime = sds->shm_dtime;
645	bds->shm_ctime = sds->shm_ctime;
646}
647
648struct svr4_sys_shmat_args {
649	syscallarg(int) what;
650	syscallarg(int) shmid;
651	syscallarg(void *) shmaddr;
652	syscallarg(int) shmflg;
653};
654
655static int
656svr4_shmat(p, v, retval)
657	struct proc *p;
658	void *v;
659	register_t *retval;
660{
661	struct svr4_sys_shmat_args *uap = v;
662	struct sys_shmat_args ap;
663
664	SCARG(&ap, shmid) = SCARG(uap, shmid);
665	SCARG(&ap, shmaddr) = SCARG(uap, shmaddr);
666	SCARG(&ap, shmflg) = SCARG(uap, shmflg);
667
668	return sys_shmat(p, &ap, retval);
669}
670
671struct svr4_sys_shmdt_args {
672	syscallarg(int) what;
673	syscallarg(void *) shmaddr;
674};
675
676static int
677svr4_shmdt(p, v, retval)
678	struct proc *p;
679	void *v;
680	register_t *retval;
681{
682	struct svr4_sys_shmdt_args *uap = v;
683	struct sys_shmdt_args ap;
684
685	SCARG(&ap, shmaddr) = SCARG(uap, shmaddr);
686
687	return sys_shmdt(p, &ap, retval);
688}
689
690struct svr4_sys_shmget_args {
691	syscallarg(int) what;
692	syscallarg(key_t) key;
693	syscallarg(int) size;
694	syscallarg(int) shmflg;
695};
696
697static int
698svr4_shmget(p, v, retval)
699	struct proc *p;
700	void *v;
701	register_t *retval;
702{
703	struct svr4_sys_shmget_args *uap = v;
704	struct sys_shmget_args ap;
705
706	SCARG(&ap, key) = SCARG(uap, key);
707	SCARG(&ap, size) = SCARG(uap, size);
708	SCARG(&ap, shmflg) = SCARG(uap, shmflg);
709
710	return sys_shmget(p, &ap, retval);
711}
712
713struct svr4_sys_shmctl_args {
714	syscallarg(int) what;
715	syscallarg(int) shmid;
716	syscallarg(int) cmd;
717	syscallarg(struct svr4_shmid_ds *) buf;
718};
719
720int
721svr4_shmctl(p, v, retval)
722	struct proc *p;
723	void *v;
724	register_t *retval;
725{
726	struct svr4_sys_shmctl_args *uap = v;
727	int error;
728	caddr_t sg = stackgap_init(p->p_emul);
729	struct sys_shmctl_args ap;
730	struct shmid_ds bs;
731	struct svr4_shmid_ds ss;
732
733	SCARG(&ap, shmid) = SCARG(uap, shmid);
734
735	if (SCARG(uap, buf) != NULL) {
736		SCARG(&ap, buf) = stackgap_alloc(&sg, sizeof (struct shmid_ds));
737		switch (SCARG(uap, cmd)) {
738		case SVR4_IPC_SET:
739		case SVR4_IPC_RMID:
740		case SVR4_SHM_LOCK:
741		case SVR4_SHM_UNLOCK:
742			error = copyin(SCARG(uap, buf), (caddr_t) &ss,
743			    sizeof ss);
744			if (error)
745				return error;
746			svr4_to_bsd_shmid_ds(&ss, &bs);
747			error = copyout(&bs, SCARG(&ap, buf), sizeof bs);
748			if (error)
749				return error;
750			break;
751		default:
752			break;
753		}
754	}
755	else
756		SCARG(&ap, buf) = NULL;
757
758
759	switch (SCARG(uap, cmd)) {
760	case SVR4_IPC_STAT:
761		SCARG(&ap, cmd) = IPC_STAT;
762		if ((error = sys_shmctl(p, &ap, retval)) != 0)
763			return error;
764		if (SCARG(uap, buf) == NULL)
765			return 0;
766		error = copyin(&bs, SCARG(&ap, buf), sizeof bs);
767		if (error)
768			return error;
769		bsd_to_svr4_shmid_ds(&bs, &ss);
770		return copyout(&ss, SCARG(uap, buf), sizeof ss);
771
772	case SVR4_IPC_SET:
773		SCARG(&ap, cmd) = IPC_SET;
774		return sys_shmctl(p, &ap, retval);
775
776	case SVR4_IPC_RMID:
777	case SVR4_SHM_LOCK:
778	case SVR4_SHM_UNLOCK:
779		switch (SCARG(uap, cmd)) {
780		case SVR4_IPC_RMID:
781			SCARG(&ap, cmd) = IPC_RMID;
782			break;
783		case SVR4_SHM_LOCK:
784			SCARG(&ap, cmd) = SHM_LOCK;
785			break;
786		case SVR4_SHM_UNLOCK:
787			SCARG(&ap, cmd) = SHM_UNLOCK;
788			break;
789		default:
790			return EINVAL;
791		}
792		return sys_shmctl(p, &ap, retval);
793
794	default:
795		return EINVAL;
796	}
797}
798
799int
800svr4_sys_shmsys(p, v, retval)
801	struct proc *p;
802	void *v;
803	register_t *retval;
804{
805	struct svr4_sys_shmsys_args *uap = v;
806
807	DPRINTF(("svr4_shmsys(%d)\n", SCARG(uap, what)));
808
809	switch (SCARG(uap, what)) {
810	case SVR4_shmat:
811		return svr4_shmat(p, v, retval);
812	case SVR4_shmdt:
813		return svr4_shmdt(p, v, retval);
814	case SVR4_shmget:
815		return svr4_shmget(p, v, retval);
816	case SVR4_shmctl:
817		return svr4_shmctl(p, v, retval);
818	default:
819		return ENOSYS;
820	}
821}
822#endif /* SYSVSHM */
823