svr4_ipc.c revision 147817
143412Snewton/*-
243412Snewton * Copyright (c) 1995 The NetBSD Foundation, Inc.
343412Snewton * All rights reserved.
443412Snewton *
543412Snewton * This code is derived from software contributed to The NetBSD Foundation
643412Snewton * by Christos Zoulas.
743412Snewton *
843412Snewton * Redistribution and use in source and binary forms, with or without
943412Snewton * modification, are permitted provided that the following conditions
1043412Snewton * are met:
1143412Snewton * 1. Redistributions of source code must retain the above copyright
1243412Snewton *    notice, this list of conditions and the following disclaimer.
1343412Snewton * 2. Redistributions in binary form must reproduce the above copyright
1443412Snewton *    notice, this list of conditions and the following disclaimer in the
1543412Snewton *    documentation and/or other materials provided with the distribution.
1643412Snewton * 3. All advertising materials mentioning features or use of this software
1743412Snewton *    must display the following acknowledgement:
1843412Snewton *        This product includes software developed by the NetBSD
1943412Snewton *        Foundation, Inc. and its contributors.
2043412Snewton * 4. Neither the name of The NetBSD Foundation nor the names of its
2143412Snewton *    contributors may be used to endorse or promote products derived
2243412Snewton *    from this software without specific prior written permission.
2343412Snewton *
2443412Snewton * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2543412Snewton * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2643412Snewton * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2743412Snewton * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2843412Snewton * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2943412Snewton * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3043412Snewton * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3143412Snewton * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3243412Snewton * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3343412Snewton * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3443412Snewton * POSSIBILITY OF SUCH DAMAGE.
3543412Snewton */
36139743Simp/*-
3743412Snewton * Portions of this code have been derived from software contributed
3843412Snewton * to the FreeBSD Project by Mark Newton.
3943412Snewton *
4043412Snewton * Copyright (c) 1999 Mark Newton
4143412Snewton * All rights reserved.
4243412Snewton *
4343412Snewton * Redistribution and use in source and binary forms, with or without
4443412Snewton * modification, are permitted provided that the following conditions
4543412Snewton * are met:
4643412Snewton * 1. Redistributions of source code must retain the above copyright
4743412Snewton *    notice, this list of conditions and the following disclaimer.
4843412Snewton * 2. Redistributions in binary form must reproduce the above copyright
4943412Snewton *    notice, this list of conditions and the following disclaimer in the
5043412Snewton *    documentation and/or other materials provided with the distribution.
5143412Snewton * 3. The name of the author may not be used to endorse or promote products
5243412Snewton *    derived from this software without specific prior written permission
5343412Snewton *
5443412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5543412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5643412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5743412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5843412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5943412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6043412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6143412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6243412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6343412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6443412Snewton *
6543412Snewton * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due
6643412Snewton * to preprocessor conditionals).  A nice project for a kernel hacking
6743412Snewton * novice might be to MakeItGo, but I have more important fish to fry
6843412Snewton * at present.
6943412Snewton *
70116174Sobrien *	Derived from: $NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $
7143412Snewton */
7243412Snewton
73116174Sobrien#include <sys/cdefs.h>
74116174Sobrien__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_ipc.c 147817 2005-07-07 19:25:47Z jhb $");
75116174Sobrien
76147817Sjhb#include "opt_sysvipc.h"
77147817Sjhb
7843412Snewton#include <sys/param.h>
79147817Sjhb#include <sys/ipc.h>
80147817Sjhb#include <sys/msg.h>
8143412Snewton#include <sys/proc.h>
82147817Sjhb#include <sys/sem.h>
83147817Sjhb#include <sys/shm.h>
84147817Sjhb#include <sys/syscallsubr.h>
85147817Sjhb#include <sys/sysproto.h>
86147817Sjhb#include <sys/systm.h>
8743412Snewton#include <sys/time.h>
8843412Snewton
8965302Sobrien#include <compat/svr4/svr4.h>
9065302Sobrien#include <compat/svr4/svr4_types.h>
9165302Sobrien#include <compat/svr4/svr4_signal.h>
9265302Sobrien#include <compat/svr4/svr4_proto.h>
9365302Sobrien#include <compat/svr4/svr4_util.h>
9465302Sobrien#include <compat/svr4/svr4_ipc.h>
9543412Snewton
9643412Snewton#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
9792761Salfredstatic void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *,
9892761Salfred				      struct ipc_perm *);
9992761Salfredstatic void bsd_to_svr4_ipc_perm(const struct ipc_perm *,
10092761Salfred				      struct svr4_ipc_perm *);
10143412Snewton#endif
10243412Snewton
10343412Snewton#ifdef SYSVSEM
10492761Salfredstatic void bsd_to_svr4_semid_ds(const struct semid_ds *,
10592761Salfred				      struct svr4_semid_ds *);
10692761Salfredstatic void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *,
10792761Salfred				      struct semid_ds *);
10892761Salfredstatic int svr4_setsemun(caddr_t *sgp, union semun **argp,
10992761Salfred			      union semun *usp);
110147817Sjhbstatic int svr4_semop(struct thread *, void *);
111147817Sjhbstatic int svr4_semget(struct thread *, void *);
112147817Sjhbstatic int svr4_semctl(struct thread *, void *);
11343412Snewton#endif
11443412Snewton
11543412Snewton#ifdef SYSVMSG
11692761Salfredstatic void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
11792761Salfred				      struct svr4_msqid_ds *);
11892761Salfredstatic void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
11992761Salfred				      struct msqid_ds *);
120147817Sjhbstatic int svr4_msgsnd(struct thread *, void *);
121147817Sjhbstatic int svr4_msgrcv(struct thread *, void *);
122147817Sjhbstatic int svr4_msgget(struct thread *, void *);
123147817Sjhbstatic int svr4_msgctl(struct thread *, void *);
12443412Snewton#endif
12543412Snewton
12643412Snewton#ifdef SYSVSHM
12792761Salfredstatic void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
12892761Salfred				      struct svr4_shmid_ds *);
12992761Salfredstatic void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
13092761Salfred				      struct shmid_ds *);
131147817Sjhbstatic int svr4_shmat(struct thread *, void *);
132147817Sjhbstatic int svr4_shmdt(struct thread *, void *);
133147817Sjhbstatic int svr4_shmget(struct thread *, void *);
134147817Sjhbstatic int svr4_shmctl(struct thread *, void *);
13543412Snewton#endif
13643412Snewton
13743412Snewton#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
13843412Snewton
13943412Snewtonstatic void
14043412Snewtonsvr4_to_bsd_ipc_perm(spp, bpp)
14143412Snewton	const struct svr4_ipc_perm *spp;
14243412Snewton	struct ipc_perm *bpp;
14343412Snewton{
14443412Snewton	bpp->key = spp->key;
14543412Snewton	bpp->uid = spp->uid;
14643412Snewton	bpp->gid = spp->gid;
14743412Snewton	bpp->cuid = spp->cuid;
14843412Snewton	bpp->cgid = spp->cgid;
14943412Snewton	bpp->mode = spp->mode;
15043412Snewton	bpp->seq = spp->seq;
15143412Snewton}
15243412Snewton
15343412Snewtonstatic void
15443412Snewtonbsd_to_svr4_ipc_perm(bpp, spp)
15543412Snewton	const struct ipc_perm *bpp;
15643412Snewton	struct svr4_ipc_perm *spp;
15743412Snewton{
15843412Snewton	spp->key = bpp->key;
15943412Snewton	spp->uid = bpp->uid;
16043412Snewton	spp->gid = bpp->gid;
16143412Snewton	spp->cuid = bpp->cuid;
16243412Snewton	spp->cgid = bpp->cgid;
16343412Snewton	spp->mode = bpp->mode;
16443412Snewton	spp->seq = bpp->seq;
16543412Snewton}
16643412Snewton#endif
16743412Snewton
16843412Snewton#ifdef SYSVSEM
16943412Snewtonstatic void
17043412Snewtonbsd_to_svr4_semid_ds(bds, sds)
17143412Snewton	const struct semid_ds *bds;
17243412Snewton	struct svr4_semid_ds *sds;
17343412Snewton{
17443412Snewton	bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
17543412Snewton	sds->sem_base = (struct svr4_sem *) bds->sem_base;
17643412Snewton	sds->sem_nsems = bds->sem_nsems;
17743412Snewton	sds->sem_otime = bds->sem_otime;
17843412Snewton	sds->sem_pad1 = bds->sem_pad1;
17943412Snewton	sds->sem_ctime = bds->sem_ctime;
18043412Snewton	sds->sem_pad2 = bds->sem_pad2;
18143412Snewton}
18243412Snewton
18343412Snewtonstatic void
18443412Snewtonsvr4_to_bsd_semid_ds(sds, bds)
18543412Snewton	const struct svr4_semid_ds *sds;
18643412Snewton	struct semid_ds *bds;
18743412Snewton{
18843412Snewton	svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
18943412Snewton	bds->sem_base = (struct sem *) bds->sem_base;
19043412Snewton	bds->sem_nsems = sds->sem_nsems;
19143412Snewton	bds->sem_otime = sds->sem_otime;
19243412Snewton	bds->sem_pad1 = sds->sem_pad1;
19343412Snewton	bds->sem_ctime = sds->sem_ctime;
19443412Snewton	bds->sem_pad2 = sds->sem_pad2;
19543412Snewton}
19643412Snewton
19743412Snewtonstatic int
19843412Snewtonsvr4_setsemun(sgp, argp, usp)
19943412Snewton	caddr_t *sgp;
20043412Snewton	union semun **argp;
20143412Snewton	union semun *usp;
20243412Snewton{
20343412Snewton	*argp = stackgap_alloc(sgp, sizeof(union semun));
20443412Snewton	return copyout((caddr_t)usp, *argp, sizeof(union semun));
20543412Snewton}
20643412Snewton
20743412Snewtonstruct svr4_sys_semctl_args {
208147817Sjhb	int what;
209147817Sjhb	int semid;
210147817Sjhb	int semnum;
211147817Sjhb	int cmd;
212147817Sjhb	union semun arg;
21343412Snewton};
21443412Snewton
21543412Snewtonstatic int
216147817Sjhbsvr4_semctl(td, v)
217147817Sjhb	struct thread *td;
21843412Snewton	void *v;
21943412Snewton{
22043412Snewton	int error;
22143412Snewton	struct svr4_sys_semctl_args *uap = v;
222147817Sjhb	struct __semctl_args ap;
22343412Snewton	struct svr4_semid_ds ss;
22443412Snewton	struct semid_ds bs, *bsp;
22571447Sjhb	caddr_t sg = stackgap_init();
22643412Snewton
227107849Salfred	ap.semid = uap->semid;
228107849Salfred	ap.semnum = uap->semnum;
22943412Snewton
230107849Salfred	switch (uap->cmd) {
23143412Snewton	case SVR4_SEM_GETZCNT:
23243412Snewton	case SVR4_SEM_GETNCNT:
23343412Snewton	case SVR4_SEM_GETPID:
23443412Snewton	case SVR4_SEM_GETVAL:
235107849Salfred		switch (uap->cmd) {
23643412Snewton		case SVR4_SEM_GETZCNT:
237107849Salfred			ap.cmd = GETZCNT;
23843412Snewton			break;
23943412Snewton		case SVR4_SEM_GETNCNT:
240107849Salfred			ap.cmd = GETNCNT;
24143412Snewton			break;
24243412Snewton		case SVR4_SEM_GETPID:
243107849Salfred			ap.cmd = GETPID;
24443412Snewton			break;
24543412Snewton		case SVR4_SEM_GETVAL:
246107849Salfred			ap.cmd = GETVAL;
24743412Snewton			break;
24843412Snewton		}
249147817Sjhb		return __semctl(td, &ap);
25043412Snewton
25143412Snewton	case SVR4_SEM_SETVAL:
252107849Salfred		error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
25343412Snewton		if (error)
25443412Snewton			return error;
255107849Salfred		ap.cmd = SETVAL;
256147817Sjhb		return __semctl(td, &ap);
25743412Snewton
25843412Snewton	case SVR4_SEM_GETALL:
259107849Salfred		error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
26043412Snewton		if (error)
26143412Snewton			return error;
262107849Salfred		ap.cmd = GETVAL;
263147817Sjhb		return __semctl(td, &ap);
26443412Snewton
26543412Snewton	case SVR4_SEM_SETALL:
266107849Salfred		error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
26743412Snewton		if (error)
26843412Snewton			return error;
269107849Salfred		ap.cmd = SETVAL;
270147817Sjhb		return __semctl(td, &ap);
27143412Snewton
27243412Snewton	case SVR4_IPC_STAT:
273107849Salfred                ap.cmd = IPC_STAT;
27443412Snewton		bsp = stackgap_alloc(&sg, sizeof(bs));
275107849Salfred		error = svr4_setsemun(&sg, &ap.arg,
27643412Snewton				      (union semun *)&bsp);
27743412Snewton		if (error)
27843412Snewton			return error;
279147817Sjhb                if ((error = __semctl(td, &ap)) != 0)
28043412Snewton                        return error;
28143412Snewton		error = copyin((caddr_t)bsp, (caddr_t)&bs, sizeof(bs));
28243412Snewton                if (error)
28343412Snewton                        return error;
28443412Snewton                bsd_to_svr4_semid_ds(&bs, &ss);
285107849Salfred		return copyout(&ss, uap->arg.buf, sizeof(ss));
28643412Snewton
28743412Snewton	case SVR4_IPC_SET:
288107849Salfred		ap.cmd = IPC_SET;
28943412Snewton		bsp = stackgap_alloc(&sg, sizeof(bs));
290107849Salfred		error = svr4_setsemun(&sg, &ap.arg,
29143412Snewton				      (union semun *)&bsp);
29243412Snewton		if (error)
29343412Snewton			return error;
294107849Salfred		error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
29543412Snewton                if (error)
29643412Snewton                        return error;
29743412Snewton                svr4_to_bsd_semid_ds(&ss, &bs);
29843412Snewton		error = copyout(&bs, bsp, sizeof(bs));
29943412Snewton                if (error)
30043412Snewton                        return error;
301147817Sjhb		return __semctl(td, &ap);
30243412Snewton
30343412Snewton	case SVR4_IPC_RMID:
304107849Salfred		ap.cmd = IPC_RMID;
30543412Snewton		bsp = stackgap_alloc(&sg, sizeof(bs));
306107849Salfred		error = svr4_setsemun(&sg, &ap.arg,
30743412Snewton				      (union semun *)&bsp);
30843412Snewton		if (error)
30943412Snewton			return error;
310107849Salfred		error = copyin(uap->arg.buf, &ss, sizeof ss);
31143412Snewton                if (error)
31243412Snewton                        return error;
31343412Snewton                svr4_to_bsd_semid_ds(&ss, &bs);
31443412Snewton		error = copyout(&bs, bsp, sizeof(bs));
31543412Snewton		if (error)
31643412Snewton			return error;
317147817Sjhb		return __semctl(td, &ap);
31843412Snewton
31943412Snewton	default:
32043412Snewton		return EINVAL;
32143412Snewton	}
32243412Snewton}
32343412Snewton
32443412Snewtonstruct svr4_sys_semget_args {
325147817Sjhb	int what;
326147817Sjhb	svr4_key_t key;
327147817Sjhb	int nsems;
328147817Sjhb	int semflg;
32943412Snewton};
33043412Snewton
33143412Snewtonstatic int
332147817Sjhbsvr4_semget(td, v)
333147817Sjhb	struct thread *td;
33443412Snewton	void *v;
33543412Snewton{
33643412Snewton	struct svr4_sys_semget_args *uap = v;
337147817Sjhb	struct semget_args ap;
33843412Snewton
339107849Salfred	ap.key = uap->key;
340107849Salfred	ap.nsems = uap->nsems;
341107849Salfred	ap.semflg = uap->semflg;
34243412Snewton
343147817Sjhb	return semget(td, &ap);
34443412Snewton}
34543412Snewton
34643412Snewtonstruct svr4_sys_semop_args {
347147817Sjhb	int what;
348147817Sjhb	int semid;
349147817Sjhb	struct svr4_sembuf * sops;
350147817Sjhb	u_int nsops;
35143412Snewton};
35243412Snewton
35343412Snewtonstatic int
354147817Sjhbsvr4_semop(td, v)
355147817Sjhb	struct thread *td;
35643412Snewton	void *v;
35743412Snewton{
35843412Snewton	struct svr4_sys_semop_args *uap = v;
359147817Sjhb	struct semop_args ap;
36043412Snewton
361107849Salfred	ap.semid = uap->semid;
36243412Snewton	/* These are the same */
363107849Salfred	ap.sops = (struct sembuf *) uap->sops;
364107849Salfred	ap.nsops = uap->nsops;
36543412Snewton
366147817Sjhb	return semop(td, &ap);
36743412Snewton}
36843412Snewton
36943412Snewtonint
370147817Sjhbsvr4_sys_semsys(td, uap)
371147817Sjhb	struct thread *td;
372147817Sjhb	struct svr4_sys_semsys_args *uap;
37343412Snewton{
37443412Snewton
375107849Salfred	DPRINTF(("svr4_semsys(%d)\n", uap->what));
37643412Snewton
377107849Salfred	switch (uap->what) {
37843412Snewton	case SVR4_semctl:
379147817Sjhb		return svr4_semctl(td, uap);
38043412Snewton	case SVR4_semget:
381147817Sjhb		return svr4_semget(td, uap);
38243412Snewton	case SVR4_semop:
383147817Sjhb		return svr4_semop(td, uap);
38443412Snewton	default:
38543412Snewton		return EINVAL;
38643412Snewton	}
38743412Snewton}
38843412Snewton#endif
38943412Snewton
39043412Snewton#ifdef SYSVMSG
39143412Snewtonstatic void
39243412Snewtonbsd_to_svr4_msqid_ds(bds, sds)
39343412Snewton	const struct msqid_ds *bds;
39443412Snewton	struct svr4_msqid_ds *sds;
39543412Snewton{
39643412Snewton	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
39743412Snewton	sds->msg_first = (struct svr4_msg *) bds->msg_first;
39843412Snewton	sds->msg_last = (struct svr4_msg *) bds->msg_last;
39943412Snewton	sds->msg_cbytes = bds->msg_cbytes;
40043412Snewton	sds->msg_qnum = bds->msg_qnum;
40143412Snewton	sds->msg_qbytes = bds->msg_qbytes;
40243412Snewton	sds->msg_lspid = bds->msg_lspid;
40343412Snewton	sds->msg_lrpid = bds->msg_lrpid;
40443412Snewton	sds->msg_stime = bds->msg_stime;
40543412Snewton	sds->msg_pad1 = bds->msg_pad1;
40643412Snewton	sds->msg_rtime = bds->msg_rtime;
40743412Snewton	sds->msg_pad2 = bds->msg_pad2;
40843412Snewton	sds->msg_ctime = bds->msg_ctime;
40943412Snewton	sds->msg_pad3 = bds->msg_pad3;
41043412Snewton
41143412Snewton	/* use the padding for the rest of the fields */
41243412Snewton	{
41343412Snewton		const short *pad = (const short *) bds->msg_pad4;
41443412Snewton		sds->msg_cv = pad[0];
41543412Snewton		sds->msg_qnum_cv = pad[1];
41643412Snewton	}
41743412Snewton}
41843412Snewton
41943412Snewtonstatic void
42043412Snewtonsvr4_to_bsd_msqid_ds(sds, bds)
42143412Snewton	const struct svr4_msqid_ds *sds;
42243412Snewton	struct msqid_ds *bds;
42343412Snewton{
42443412Snewton	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
42543412Snewton	bds->msg_first = (struct msg *) sds->msg_first;
42643412Snewton	bds->msg_last = (struct msg *) sds->msg_last;
42743412Snewton	bds->msg_cbytes = sds->msg_cbytes;
42843412Snewton	bds->msg_qnum = sds->msg_qnum;
42943412Snewton	bds->msg_qbytes = sds->msg_qbytes;
43043412Snewton	bds->msg_lspid = sds->msg_lspid;
43143412Snewton	bds->msg_lrpid = sds->msg_lrpid;
43243412Snewton	bds->msg_stime = sds->msg_stime;
43343412Snewton	bds->msg_pad1 = sds->msg_pad1;
43443412Snewton	bds->msg_rtime = sds->msg_rtime;
43543412Snewton	bds->msg_pad2 = sds->msg_pad2;
43643412Snewton	bds->msg_ctime = sds->msg_ctime;
43743412Snewton	bds->msg_pad3 = sds->msg_pad3;
43843412Snewton
43943412Snewton	/* use the padding for the rest of the fields */
44043412Snewton	{
44143412Snewton		short *pad = (short *) bds->msg_pad4;
44243412Snewton		pad[0] = sds->msg_cv;
44343412Snewton		pad[1] = sds->msg_qnum_cv;
44443412Snewton	}
44543412Snewton}
44643412Snewton
44743412Snewtonstruct svr4_sys_msgsnd_args {
448147817Sjhb	int what;
449147817Sjhb	int msqid;
450147817Sjhb	void * msgp;
451147817Sjhb	size_t msgsz;
452147817Sjhb	int msgflg;
45343412Snewton};
45443412Snewton
45543412Snewtonstatic int
456147817Sjhbsvr4_msgsnd(td, v)
457147817Sjhb	struct thread *td;
45843412Snewton	void *v;
45943412Snewton{
46043412Snewton	struct svr4_sys_msgsnd_args *uap = v;
461147817Sjhb	struct msgsnd_args ap;
46243412Snewton
463107849Salfred	ap.msqid = uap->msqid;
464107849Salfred	ap.msgp = uap->msgp;
465107849Salfred	ap.msgsz = uap->msgsz;
466107849Salfred	ap.msgflg = uap->msgflg;
46743412Snewton
468147817Sjhb	return msgsnd(td, &ap);
46943412Snewton}
47043412Snewton
47143412Snewtonstruct svr4_sys_msgrcv_args {
472147817Sjhb	int what;
473147817Sjhb	int msqid;
474147817Sjhb	void * msgp;
475147817Sjhb	size_t msgsz;
476147817Sjhb	long msgtyp;
477147817Sjhb	int msgflg;
47843412Snewton};
47943412Snewton
48043412Snewtonstatic int
481147817Sjhbsvr4_msgrcv(td, v)
482147817Sjhb	struct thread *td;
48343412Snewton	void *v;
48443412Snewton{
48543412Snewton	struct svr4_sys_msgrcv_args *uap = v;
486147817Sjhb	struct msgrcv_args ap;
48743412Snewton
488107849Salfred	ap.msqid = uap->msqid;
489107849Salfred	ap.msgp = uap->msgp;
490107849Salfred	ap.msgsz = uap->msgsz;
491107849Salfred	ap.msgtyp = uap->msgtyp;
492107849Salfred	ap.msgflg = uap->msgflg;
49343412Snewton
494147817Sjhb	return msgrcv(td, &ap);
49543412Snewton}
49643412Snewton
49743412Snewtonstruct svr4_sys_msgget_args {
498147817Sjhb	int what;
499147817Sjhb	svr4_key_t key;
500147817Sjhb	int msgflg;
50143412Snewton};
50243412Snewton
50343412Snewtonstatic int
504147817Sjhbsvr4_msgget(td, v)
505147817Sjhb	struct thread *td;
50643412Snewton	void *v;
50743412Snewton{
50843412Snewton	struct svr4_sys_msgget_args *uap = v;
509147817Sjhb	struct msgget_args ap;
51043412Snewton
511107849Salfred	ap.key = uap->key;
512107849Salfred	ap.msgflg = uap->msgflg;
51343412Snewton
514147817Sjhb	return msgget(td, &ap);
51543412Snewton}
51643412Snewton
51743412Snewtonstruct svr4_sys_msgctl_args {
518147817Sjhb	int what;
519147817Sjhb	int msqid;
520147817Sjhb	int cmd;
521147817Sjhb	struct svr4_msqid_ds * buf;
52243412Snewton};
52343412Snewton
52443412Snewtonstatic int
525147817Sjhbsvr4_msgctl(td, v)
526147817Sjhb	struct thread *td;
52743412Snewton	void *v;
52843412Snewton{
52943412Snewton	struct svr4_sys_msgctl_args *uap = v;
53043412Snewton	struct svr4_msqid_ds ss;
53143412Snewton	struct msqid_ds bs;
532141486Sjhb	int error;
53343412Snewton
534107849Salfred	switch (uap->cmd) {
53543412Snewton	case SVR4_IPC_STAT:
536141486Sjhb		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
53743412Snewton		if (error)
53843412Snewton			return error;
53943412Snewton		bsd_to_svr4_msqid_ds(&bs, &ss);
540107849Salfred		return copyout(&ss, uap->buf, sizeof ss);
54143412Snewton
54243412Snewton	case SVR4_IPC_SET:
543107849Salfred		error = copyin(uap->buf, &ss, sizeof ss);
54443412Snewton		if (error)
54543412Snewton			return error;
54643412Snewton		svr4_to_bsd_msqid_ds(&ss, &bs);
547141486Sjhb		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
54843412Snewton
54943412Snewton	case SVR4_IPC_RMID:
550107849Salfred		error = copyin(uap->buf, &ss, sizeof ss);
55143412Snewton		if (error)
55243412Snewton			return error;
55343412Snewton		svr4_to_bsd_msqid_ds(&ss, &bs);
554141486Sjhb		return (kern_msgctl(td, uap->msqid, IPC_RMID, &bs));
55543412Snewton
55643412Snewton	default:
55743412Snewton		return EINVAL;
55843412Snewton	}
55943412Snewton}
56043412Snewton
56143412Snewtonint
562147817Sjhbsvr4_sys_msgsys(td, uap)
563147817Sjhb	struct thread *td;
564147817Sjhb	struct svr4_sys_msgsys_args *uap;
56543412Snewton{
56643412Snewton
567107849Salfred	DPRINTF(("svr4_msgsys(%d)\n", uap->what));
56843412Snewton
569107849Salfred	switch (uap->what) {
57043412Snewton	case SVR4_msgsnd:
571147817Sjhb		return svr4_msgsnd(td, uap);
57243412Snewton	case SVR4_msgrcv:
573147817Sjhb		return svr4_msgrcv(td, uap);
57443412Snewton	case SVR4_msgget:
575147817Sjhb		return svr4_msgget(td, uap);
57643412Snewton	case SVR4_msgctl:
577147817Sjhb		return svr4_msgctl(td, uap);
57843412Snewton	default:
57943412Snewton		return EINVAL;
58043412Snewton	}
58143412Snewton}
58243412Snewton#endif
58343412Snewton
58443412Snewton#ifdef SYSVSHM
58543412Snewton
58643412Snewtonstatic void
58743412Snewtonbsd_to_svr4_shmid_ds(bds, sds)
58843412Snewton	const struct shmid_ds *bds;
58943412Snewton	struct svr4_shmid_ds *sds;
59043412Snewton{
59143412Snewton	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
59243412Snewton	sds->shm_segsz = bds->shm_segsz;
59343412Snewton	sds->shm_lkcnt = 0;
59443412Snewton	sds->shm_lpid = bds->shm_lpid;
59543412Snewton	sds->shm_cpid = bds->shm_cpid;
59643412Snewton	sds->shm_amp = bds->shm_internal;
59743412Snewton	sds->shm_nattch = bds->shm_nattch;
59843412Snewton	sds->shm_cnattch = 0;
59943412Snewton	sds->shm_atime = bds->shm_atime;
60043412Snewton	sds->shm_pad1 = 0;
60143412Snewton	sds->shm_dtime = bds->shm_dtime;
60243412Snewton	sds->shm_pad2 = 0;
60343412Snewton	sds->shm_ctime = bds->shm_ctime;
60443412Snewton	sds->shm_pad3 = 0;
60543412Snewton}
60643412Snewton
60743412Snewtonstatic void
60843412Snewtonsvr4_to_bsd_shmid_ds(sds, bds)
60943412Snewton	const struct svr4_shmid_ds *sds;
61043412Snewton	struct shmid_ds *bds;
61143412Snewton{
61243412Snewton	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
61343412Snewton	bds->shm_segsz = sds->shm_segsz;
61443412Snewton	bds->shm_lpid = sds->shm_lpid;
61543412Snewton	bds->shm_cpid = sds->shm_cpid;
61643412Snewton	bds->shm_internal = sds->shm_amp;
61743412Snewton	bds->shm_nattch = sds->shm_nattch;
61843412Snewton	bds->shm_atime = sds->shm_atime;
61943412Snewton	bds->shm_dtime = sds->shm_dtime;
62043412Snewton	bds->shm_ctime = sds->shm_ctime;
62143412Snewton}
62243412Snewton
62343412Snewtonstruct svr4_sys_shmat_args {
624147817Sjhb	int what;
625147817Sjhb	int shmid;
626147817Sjhb	void * shmaddr;
627147817Sjhb	int shmflg;
62843412Snewton};
62943412Snewton
63043412Snewtonstatic int
631147817Sjhbsvr4_shmat(td, v)
632147817Sjhb	struct thread *td;
63343412Snewton	void *v;
63443412Snewton{
63543412Snewton	struct svr4_sys_shmat_args *uap = v;
636147817Sjhb	struct shmat_args ap;
63743412Snewton
638107849Salfred	ap.shmid = uap->shmid;
639107849Salfred	ap.shmaddr = uap->shmaddr;
640107849Salfred	ap.shmflg = uap->shmflg;
64143412Snewton
642147817Sjhb	return shmat(td, &ap);
64343412Snewton}
64443412Snewton
64543412Snewtonstruct svr4_sys_shmdt_args {
646147817Sjhb	int what;
647147817Sjhb	void * shmaddr;
64843412Snewton};
64943412Snewton
65043412Snewtonstatic int
651147817Sjhbsvr4_shmdt(td, v)
652147817Sjhb	struct thread *td;
65343412Snewton	void *v;
65443412Snewton{
65543412Snewton	struct svr4_sys_shmdt_args *uap = v;
656147817Sjhb	struct shmdt_args ap;
65743412Snewton
658107849Salfred	ap.shmaddr = uap->shmaddr;
65943412Snewton
660147817Sjhb	return shmdt(td, &ap);
66143412Snewton}
66243412Snewton
66343412Snewtonstruct svr4_sys_shmget_args {
664147817Sjhb	int what;
665147817Sjhb	key_t key;
666147817Sjhb	int size;
667147817Sjhb	int shmflg;
66843412Snewton};
66943412Snewton
67043412Snewtonstatic int
671147817Sjhbsvr4_shmget(td, v)
672147817Sjhb	struct thread *td;
67343412Snewton	void *v;
67443412Snewton{
67543412Snewton	struct svr4_sys_shmget_args *uap = v;
676147817Sjhb	struct shmget_args ap;
67743412Snewton
678107849Salfred	ap.key = uap->key;
679107849Salfred	ap.size = uap->size;
680107849Salfred	ap.shmflg = uap->shmflg;
68143412Snewton
682147817Sjhb	return shmget(td, &ap);
68343412Snewton}
68443412Snewton
68543412Snewtonstruct svr4_sys_shmctl_args {
686147817Sjhb	int what;
687147817Sjhb	int shmid;
688147817Sjhb	int cmd;
689147817Sjhb	struct svr4_shmid_ds * buf;
69043412Snewton};
69143412Snewton
69243412Snewtonint
693147817Sjhbsvr4_shmctl(td, v)
694147817Sjhb	struct thread *td;
69543412Snewton	void *v;
69643412Snewton{
69743412Snewton	struct svr4_sys_shmctl_args *uap = v;
69843412Snewton	int error;
69971447Sjhb	caddr_t sg = stackgap_init();
700147817Sjhb	struct shmctl_args ap;
70143412Snewton	struct shmid_ds bs;
70243412Snewton	struct svr4_shmid_ds ss;
70343412Snewton
704107849Salfred	ap.shmid = uap->shmid;
70543412Snewton
706107849Salfred	if (uap->buf != NULL) {
707107849Salfred		ap.buf = stackgap_alloc(&sg, sizeof (struct shmid_ds));
708107849Salfred		switch (uap->cmd) {
70943412Snewton		case SVR4_IPC_SET:
71043412Snewton		case SVR4_IPC_RMID:
71143412Snewton		case SVR4_SHM_LOCK:
71243412Snewton		case SVR4_SHM_UNLOCK:
713107849Salfred			error = copyin(uap->buf, (caddr_t) &ss,
71443412Snewton			    sizeof ss);
71543412Snewton			if (error)
71643412Snewton				return error;
71743412Snewton			svr4_to_bsd_shmid_ds(&ss, &bs);
718107849Salfred			error = copyout(&bs, ap.buf, sizeof bs);
71943412Snewton			if (error)
72043412Snewton				return error;
72143412Snewton			break;
72243412Snewton		default:
72343412Snewton			break;
72443412Snewton		}
72543412Snewton	}
72643412Snewton	else
727107849Salfred		ap.buf = NULL;
72843412Snewton
72943412Snewton
730107849Salfred	switch (uap->cmd) {
73143412Snewton	case SVR4_IPC_STAT:
732107849Salfred		ap.cmd = IPC_STAT;
733147817Sjhb		if ((error = shmctl(td, &ap)) != 0)
73443412Snewton			return error;
735107849Salfred		if (uap->buf == NULL)
73643412Snewton			return 0;
737107849Salfred		error = copyin(&bs, ap.buf, sizeof bs);
73843412Snewton		if (error)
73943412Snewton			return error;
74043412Snewton		bsd_to_svr4_shmid_ds(&bs, &ss);
741107849Salfred		return copyout(&ss, uap->buf, sizeof ss);
74243412Snewton
74343412Snewton	case SVR4_IPC_SET:
744107849Salfred		ap.cmd = IPC_SET;
745147817Sjhb		return shmctl(td, &ap);
74643412Snewton
74743412Snewton	case SVR4_IPC_RMID:
74843412Snewton	case SVR4_SHM_LOCK:
74943412Snewton	case SVR4_SHM_UNLOCK:
750107849Salfred		switch (uap->cmd) {
75143412Snewton		case SVR4_IPC_RMID:
752107849Salfred			ap.cmd = IPC_RMID;
75343412Snewton			break;
75443412Snewton		case SVR4_SHM_LOCK:
755107849Salfred			ap.cmd = SHM_LOCK;
75643412Snewton			break;
75743412Snewton		case SVR4_SHM_UNLOCK:
758107849Salfred			ap.cmd = SHM_UNLOCK;
75943412Snewton			break;
76043412Snewton		default:
76143412Snewton			return EINVAL;
76243412Snewton		}
763147817Sjhb		return shmctl(td, &ap);
76443412Snewton
76543412Snewton	default:
76643412Snewton		return EINVAL;
76743412Snewton	}
76843412Snewton}
76943412Snewton
77043412Snewtonint
771147817Sjhbsvr4_sys_shmsys(td, uap)
772147817Sjhb	struct thread *td;
773147817Sjhb	struct svr4_sys_shmsys_args *uap;
77443412Snewton{
77543412Snewton
776107849Salfred	DPRINTF(("svr4_shmsys(%d)\n", uap->what));
77743412Snewton
778107849Salfred	switch (uap->what) {
77943412Snewton	case SVR4_shmat:
780147817Sjhb		return svr4_shmat(td, uap);
78143412Snewton	case SVR4_shmdt:
782147817Sjhb		return svr4_shmdt(td, uap);
78343412Snewton	case SVR4_shmget:
784147817Sjhb		return svr4_shmget(td, uap);
78543412Snewton	case SVR4_shmctl:
786147817Sjhb		return svr4_shmctl(td, uap);
78743412Snewton	default:
78843412Snewton		return ENOSYS;
78943412Snewton	}
79043412Snewton}
79143412Snewton#endif /* SYSVSHM */
792