svr4_ipc.c revision 148541
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 148541 2005-07-29 19:41:04Z 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}
388148541Sjhb
389148541SjhbMODULE_DEPEND(svr4elf, sysvsem, 1, 1, 1);
39043412Snewton#endif
39143412Snewton
39243412Snewton#ifdef SYSVMSG
39343412Snewtonstatic void
39443412Snewtonbsd_to_svr4_msqid_ds(bds, sds)
39543412Snewton	const struct msqid_ds *bds;
39643412Snewton	struct svr4_msqid_ds *sds;
39743412Snewton{
39843412Snewton	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
39943412Snewton	sds->msg_first = (struct svr4_msg *) bds->msg_first;
40043412Snewton	sds->msg_last = (struct svr4_msg *) bds->msg_last;
40143412Snewton	sds->msg_cbytes = bds->msg_cbytes;
40243412Snewton	sds->msg_qnum = bds->msg_qnum;
40343412Snewton	sds->msg_qbytes = bds->msg_qbytes;
40443412Snewton	sds->msg_lspid = bds->msg_lspid;
40543412Snewton	sds->msg_lrpid = bds->msg_lrpid;
40643412Snewton	sds->msg_stime = bds->msg_stime;
40743412Snewton	sds->msg_pad1 = bds->msg_pad1;
40843412Snewton	sds->msg_rtime = bds->msg_rtime;
40943412Snewton	sds->msg_pad2 = bds->msg_pad2;
41043412Snewton	sds->msg_ctime = bds->msg_ctime;
41143412Snewton	sds->msg_pad3 = bds->msg_pad3;
41243412Snewton
41343412Snewton	/* use the padding for the rest of the fields */
41443412Snewton	{
41543412Snewton		const short *pad = (const short *) bds->msg_pad4;
41643412Snewton		sds->msg_cv = pad[0];
41743412Snewton		sds->msg_qnum_cv = pad[1];
41843412Snewton	}
41943412Snewton}
42043412Snewton
42143412Snewtonstatic void
42243412Snewtonsvr4_to_bsd_msqid_ds(sds, bds)
42343412Snewton	const struct svr4_msqid_ds *sds;
42443412Snewton	struct msqid_ds *bds;
42543412Snewton{
42643412Snewton	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
42743412Snewton	bds->msg_first = (struct msg *) sds->msg_first;
42843412Snewton	bds->msg_last = (struct msg *) sds->msg_last;
42943412Snewton	bds->msg_cbytes = sds->msg_cbytes;
43043412Snewton	bds->msg_qnum = sds->msg_qnum;
43143412Snewton	bds->msg_qbytes = sds->msg_qbytes;
43243412Snewton	bds->msg_lspid = sds->msg_lspid;
43343412Snewton	bds->msg_lrpid = sds->msg_lrpid;
43443412Snewton	bds->msg_stime = sds->msg_stime;
43543412Snewton	bds->msg_pad1 = sds->msg_pad1;
43643412Snewton	bds->msg_rtime = sds->msg_rtime;
43743412Snewton	bds->msg_pad2 = sds->msg_pad2;
43843412Snewton	bds->msg_ctime = sds->msg_ctime;
43943412Snewton	bds->msg_pad3 = sds->msg_pad3;
44043412Snewton
44143412Snewton	/* use the padding for the rest of the fields */
44243412Snewton	{
44343412Snewton		short *pad = (short *) bds->msg_pad4;
44443412Snewton		pad[0] = sds->msg_cv;
44543412Snewton		pad[1] = sds->msg_qnum_cv;
44643412Snewton	}
44743412Snewton}
44843412Snewton
44943412Snewtonstruct svr4_sys_msgsnd_args {
450147817Sjhb	int what;
451147817Sjhb	int msqid;
452147817Sjhb	void * msgp;
453147817Sjhb	size_t msgsz;
454147817Sjhb	int msgflg;
45543412Snewton};
45643412Snewton
45743412Snewtonstatic int
458147817Sjhbsvr4_msgsnd(td, v)
459147817Sjhb	struct thread *td;
46043412Snewton	void *v;
46143412Snewton{
46243412Snewton	struct svr4_sys_msgsnd_args *uap = v;
463147817Sjhb	struct msgsnd_args ap;
46443412Snewton
465107849Salfred	ap.msqid = uap->msqid;
466107849Salfred	ap.msgp = uap->msgp;
467107849Salfred	ap.msgsz = uap->msgsz;
468107849Salfred	ap.msgflg = uap->msgflg;
46943412Snewton
470147817Sjhb	return msgsnd(td, &ap);
47143412Snewton}
47243412Snewton
47343412Snewtonstruct svr4_sys_msgrcv_args {
474147817Sjhb	int what;
475147817Sjhb	int msqid;
476147817Sjhb	void * msgp;
477147817Sjhb	size_t msgsz;
478147817Sjhb	long msgtyp;
479147817Sjhb	int msgflg;
48043412Snewton};
48143412Snewton
48243412Snewtonstatic int
483147817Sjhbsvr4_msgrcv(td, v)
484147817Sjhb	struct thread *td;
48543412Snewton	void *v;
48643412Snewton{
48743412Snewton	struct svr4_sys_msgrcv_args *uap = v;
488147817Sjhb	struct msgrcv_args ap;
48943412Snewton
490107849Salfred	ap.msqid = uap->msqid;
491107849Salfred	ap.msgp = uap->msgp;
492107849Salfred	ap.msgsz = uap->msgsz;
493107849Salfred	ap.msgtyp = uap->msgtyp;
494107849Salfred	ap.msgflg = uap->msgflg;
49543412Snewton
496147817Sjhb	return msgrcv(td, &ap);
49743412Snewton}
49843412Snewton
49943412Snewtonstruct svr4_sys_msgget_args {
500147817Sjhb	int what;
501147817Sjhb	svr4_key_t key;
502147817Sjhb	int msgflg;
50343412Snewton};
50443412Snewton
50543412Snewtonstatic int
506147817Sjhbsvr4_msgget(td, v)
507147817Sjhb	struct thread *td;
50843412Snewton	void *v;
50943412Snewton{
51043412Snewton	struct svr4_sys_msgget_args *uap = v;
511147817Sjhb	struct msgget_args ap;
51243412Snewton
513107849Salfred	ap.key = uap->key;
514107849Salfred	ap.msgflg = uap->msgflg;
51543412Snewton
516147817Sjhb	return msgget(td, &ap);
51743412Snewton}
51843412Snewton
51943412Snewtonstruct svr4_sys_msgctl_args {
520147817Sjhb	int what;
521147817Sjhb	int msqid;
522147817Sjhb	int cmd;
523147817Sjhb	struct svr4_msqid_ds * buf;
52443412Snewton};
52543412Snewton
52643412Snewtonstatic int
527147817Sjhbsvr4_msgctl(td, v)
528147817Sjhb	struct thread *td;
52943412Snewton	void *v;
53043412Snewton{
53143412Snewton	struct svr4_sys_msgctl_args *uap = v;
53243412Snewton	struct svr4_msqid_ds ss;
53343412Snewton	struct msqid_ds bs;
534141486Sjhb	int error;
53543412Snewton
536107849Salfred	switch (uap->cmd) {
53743412Snewton	case SVR4_IPC_STAT:
538141486Sjhb		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
53943412Snewton		if (error)
54043412Snewton			return error;
54143412Snewton		bsd_to_svr4_msqid_ds(&bs, &ss);
542107849Salfred		return copyout(&ss, uap->buf, sizeof ss);
54343412Snewton
54443412Snewton	case SVR4_IPC_SET:
545107849Salfred		error = copyin(uap->buf, &ss, sizeof ss);
54643412Snewton		if (error)
54743412Snewton			return error;
54843412Snewton		svr4_to_bsd_msqid_ds(&ss, &bs);
549141486Sjhb		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
55043412Snewton
55143412Snewton	case SVR4_IPC_RMID:
552107849Salfred		error = copyin(uap->buf, &ss, sizeof ss);
55343412Snewton		if (error)
55443412Snewton			return error;
55543412Snewton		svr4_to_bsd_msqid_ds(&ss, &bs);
556141486Sjhb		return (kern_msgctl(td, uap->msqid, IPC_RMID, &bs));
55743412Snewton
55843412Snewton	default:
55943412Snewton		return EINVAL;
56043412Snewton	}
56143412Snewton}
56243412Snewton
56343412Snewtonint
564147817Sjhbsvr4_sys_msgsys(td, uap)
565147817Sjhb	struct thread *td;
566147817Sjhb	struct svr4_sys_msgsys_args *uap;
56743412Snewton{
56843412Snewton
569107849Salfred	DPRINTF(("svr4_msgsys(%d)\n", uap->what));
57043412Snewton
571107849Salfred	switch (uap->what) {
57243412Snewton	case SVR4_msgsnd:
573147817Sjhb		return svr4_msgsnd(td, uap);
57443412Snewton	case SVR4_msgrcv:
575147817Sjhb		return svr4_msgrcv(td, uap);
57643412Snewton	case SVR4_msgget:
577147817Sjhb		return svr4_msgget(td, uap);
57843412Snewton	case SVR4_msgctl:
579147817Sjhb		return svr4_msgctl(td, uap);
58043412Snewton	default:
58143412Snewton		return EINVAL;
58243412Snewton	}
58343412Snewton}
584148541Sjhb
585148541SjhbMODULE_DEPEND(svr4elf, sysvmsg, 1, 1, 1);
58643412Snewton#endif
58743412Snewton
58843412Snewton#ifdef SYSVSHM
58943412Snewton
59043412Snewtonstatic void
59143412Snewtonbsd_to_svr4_shmid_ds(bds, sds)
59243412Snewton	const struct shmid_ds *bds;
59343412Snewton	struct svr4_shmid_ds *sds;
59443412Snewton{
59543412Snewton	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
59643412Snewton	sds->shm_segsz = bds->shm_segsz;
59743412Snewton	sds->shm_lkcnt = 0;
59843412Snewton	sds->shm_lpid = bds->shm_lpid;
59943412Snewton	sds->shm_cpid = bds->shm_cpid;
60043412Snewton	sds->shm_amp = bds->shm_internal;
60143412Snewton	sds->shm_nattch = bds->shm_nattch;
60243412Snewton	sds->shm_cnattch = 0;
60343412Snewton	sds->shm_atime = bds->shm_atime;
60443412Snewton	sds->shm_pad1 = 0;
60543412Snewton	sds->shm_dtime = bds->shm_dtime;
60643412Snewton	sds->shm_pad2 = 0;
60743412Snewton	sds->shm_ctime = bds->shm_ctime;
60843412Snewton	sds->shm_pad3 = 0;
60943412Snewton}
61043412Snewton
61143412Snewtonstatic void
61243412Snewtonsvr4_to_bsd_shmid_ds(sds, bds)
61343412Snewton	const struct svr4_shmid_ds *sds;
61443412Snewton	struct shmid_ds *bds;
61543412Snewton{
61643412Snewton	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
61743412Snewton	bds->shm_segsz = sds->shm_segsz;
61843412Snewton	bds->shm_lpid = sds->shm_lpid;
61943412Snewton	bds->shm_cpid = sds->shm_cpid;
62043412Snewton	bds->shm_internal = sds->shm_amp;
62143412Snewton	bds->shm_nattch = sds->shm_nattch;
62243412Snewton	bds->shm_atime = sds->shm_atime;
62343412Snewton	bds->shm_dtime = sds->shm_dtime;
62443412Snewton	bds->shm_ctime = sds->shm_ctime;
62543412Snewton}
62643412Snewton
62743412Snewtonstruct svr4_sys_shmat_args {
628147817Sjhb	int what;
629147817Sjhb	int shmid;
630147817Sjhb	void * shmaddr;
631147817Sjhb	int shmflg;
63243412Snewton};
63343412Snewton
63443412Snewtonstatic int
635147817Sjhbsvr4_shmat(td, v)
636147817Sjhb	struct thread *td;
63743412Snewton	void *v;
63843412Snewton{
63943412Snewton	struct svr4_sys_shmat_args *uap = v;
640147817Sjhb	struct shmat_args ap;
64143412Snewton
642107849Salfred	ap.shmid = uap->shmid;
643107849Salfred	ap.shmaddr = uap->shmaddr;
644107849Salfred	ap.shmflg = uap->shmflg;
64543412Snewton
646147817Sjhb	return shmat(td, &ap);
64743412Snewton}
64843412Snewton
64943412Snewtonstruct svr4_sys_shmdt_args {
650147817Sjhb	int what;
651147817Sjhb	void * shmaddr;
65243412Snewton};
65343412Snewton
65443412Snewtonstatic int
655147817Sjhbsvr4_shmdt(td, v)
656147817Sjhb	struct thread *td;
65743412Snewton	void *v;
65843412Snewton{
65943412Snewton	struct svr4_sys_shmdt_args *uap = v;
660147817Sjhb	struct shmdt_args ap;
66143412Snewton
662107849Salfred	ap.shmaddr = uap->shmaddr;
66343412Snewton
664147817Sjhb	return shmdt(td, &ap);
66543412Snewton}
66643412Snewton
66743412Snewtonstruct svr4_sys_shmget_args {
668147817Sjhb	int what;
669147817Sjhb	key_t key;
670147817Sjhb	int size;
671147817Sjhb	int shmflg;
67243412Snewton};
67343412Snewton
67443412Snewtonstatic int
675147817Sjhbsvr4_shmget(td, v)
676147817Sjhb	struct thread *td;
67743412Snewton	void *v;
67843412Snewton{
67943412Snewton	struct svr4_sys_shmget_args *uap = v;
680147817Sjhb	struct shmget_args ap;
68143412Snewton
682107849Salfred	ap.key = uap->key;
683107849Salfred	ap.size = uap->size;
684107849Salfred	ap.shmflg = uap->shmflg;
68543412Snewton
686147817Sjhb	return shmget(td, &ap);
68743412Snewton}
68843412Snewton
68943412Snewtonstruct svr4_sys_shmctl_args {
690147817Sjhb	int what;
691147817Sjhb	int shmid;
692147817Sjhb	int cmd;
693147817Sjhb	struct svr4_shmid_ds * buf;
69443412Snewton};
69543412Snewton
69643412Snewtonint
697147817Sjhbsvr4_shmctl(td, v)
698147817Sjhb	struct thread *td;
69943412Snewton	void *v;
70043412Snewton{
70143412Snewton	struct svr4_sys_shmctl_args *uap = v;
70243412Snewton	int error;
70371447Sjhb	caddr_t sg = stackgap_init();
704147817Sjhb	struct shmctl_args ap;
70543412Snewton	struct shmid_ds bs;
70643412Snewton	struct svr4_shmid_ds ss;
70743412Snewton
708107849Salfred	ap.shmid = uap->shmid;
70943412Snewton
710107849Salfred	if (uap->buf != NULL) {
711107849Salfred		ap.buf = stackgap_alloc(&sg, sizeof (struct shmid_ds));
712107849Salfred		switch (uap->cmd) {
71343412Snewton		case SVR4_IPC_SET:
71443412Snewton		case SVR4_IPC_RMID:
71543412Snewton		case SVR4_SHM_LOCK:
71643412Snewton		case SVR4_SHM_UNLOCK:
717107849Salfred			error = copyin(uap->buf, (caddr_t) &ss,
71843412Snewton			    sizeof ss);
71943412Snewton			if (error)
72043412Snewton				return error;
72143412Snewton			svr4_to_bsd_shmid_ds(&ss, &bs);
722107849Salfred			error = copyout(&bs, ap.buf, sizeof bs);
72343412Snewton			if (error)
72443412Snewton				return error;
72543412Snewton			break;
72643412Snewton		default:
72743412Snewton			break;
72843412Snewton		}
72943412Snewton	}
73043412Snewton	else
731107849Salfred		ap.buf = NULL;
73243412Snewton
73343412Snewton
734107849Salfred	switch (uap->cmd) {
73543412Snewton	case SVR4_IPC_STAT:
736107849Salfred		ap.cmd = IPC_STAT;
737147817Sjhb		if ((error = shmctl(td, &ap)) != 0)
73843412Snewton			return error;
739107849Salfred		if (uap->buf == NULL)
74043412Snewton			return 0;
741107849Salfred		error = copyin(&bs, ap.buf, sizeof bs);
74243412Snewton		if (error)
74343412Snewton			return error;
74443412Snewton		bsd_to_svr4_shmid_ds(&bs, &ss);
745107849Salfred		return copyout(&ss, uap->buf, sizeof ss);
74643412Snewton
74743412Snewton	case SVR4_IPC_SET:
748107849Salfred		ap.cmd = IPC_SET;
749147817Sjhb		return shmctl(td, &ap);
75043412Snewton
75143412Snewton	case SVR4_IPC_RMID:
75243412Snewton	case SVR4_SHM_LOCK:
75343412Snewton	case SVR4_SHM_UNLOCK:
754107849Salfred		switch (uap->cmd) {
75543412Snewton		case SVR4_IPC_RMID:
756107849Salfred			ap.cmd = IPC_RMID;
75743412Snewton			break;
75843412Snewton		case SVR4_SHM_LOCK:
759107849Salfred			ap.cmd = SHM_LOCK;
76043412Snewton			break;
76143412Snewton		case SVR4_SHM_UNLOCK:
762107849Salfred			ap.cmd = SHM_UNLOCK;
76343412Snewton			break;
76443412Snewton		default:
76543412Snewton			return EINVAL;
76643412Snewton		}
767147817Sjhb		return shmctl(td, &ap);
76843412Snewton
76943412Snewton	default:
77043412Snewton		return EINVAL;
77143412Snewton	}
77243412Snewton}
77343412Snewton
77443412Snewtonint
775147817Sjhbsvr4_sys_shmsys(td, uap)
776147817Sjhb	struct thread *td;
777147817Sjhb	struct svr4_sys_shmsys_args *uap;
77843412Snewton{
77943412Snewton
780107849Salfred	DPRINTF(("svr4_shmsys(%d)\n", uap->what));
78143412Snewton
782107849Salfred	switch (uap->what) {
78343412Snewton	case SVR4_shmat:
784147817Sjhb		return svr4_shmat(td, uap);
78543412Snewton	case SVR4_shmdt:
786147817Sjhb		return svr4_shmdt(td, uap);
78743412Snewton	case SVR4_shmget:
788147817Sjhb		return svr4_shmget(td, uap);
78943412Snewton	case SVR4_shmctl:
790147817Sjhb		return svr4_shmctl(td, uap);
79143412Snewton	default:
79243412Snewton		return ENOSYS;
79343412Snewton	}
79443412Snewton}
795148541Sjhb
796148541SjhbMODULE_DEPEND(svr4elf, sysvshm, 1, 1, 1);
79743412Snewton#endif /* SYSVSHM */
798