svr4_ipc.c revision 139743
1/*-
2 * Copyright (c) 1995 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Christos Zoulas.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *        This product includes software developed by the NetBSD
19 *        Foundation, Inc. and its contributors.
20 * 4. Neither the name of The NetBSD Foundation nor the names of its
21 *    contributors may be used to endorse or promote products derived
22 *    from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36/*-
37 * Portions of this code have been derived from software contributed
38 * to the FreeBSD Project by Mark Newton.
39 *
40 * Copyright (c) 1999 Mark Newton
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 *    notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 *    notice, this list of conditions and the following disclaimer in the
50 *    documentation and/or other materials provided with the distribution.
51 * 3. The name of the author may not be used to endorse or promote products
52 *    derived from this software without specific prior written permission
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due
66 * to preprocessor conditionals).  A nice project for a kernel hacking
67 * novice might be to MakeItGo, but I have more important fish to fry
68 * at present.
69 *
70 *	Derived from: $NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $
71 */
72
73#include <sys/cdefs.h>
74__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_ipc.c 139743 2005-01-05 22:34:37Z imp $");
75
76#include <sys/types.h>
77#include <sys/param.h>
78#include <sys/proc.h>
79#include <sys/time.h>
80
81#include <compat/svr4/svr4.h>
82#include <compat/svr4/svr4_types.h>
83#include <compat/svr4/svr4_signal.h>
84#include <compat/svr4/svr4_proto.h>
85#include <compat/svr4/svr4_util.h>
86#include <compat/svr4/svr4_ipc.h>
87
88#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
89static void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *,
90				      struct ipc_perm *);
91static void bsd_to_svr4_ipc_perm(const struct ipc_perm *,
92				      struct svr4_ipc_perm *);
93#endif
94
95#ifdef SYSVSEM
96static void bsd_to_svr4_semid_ds(const struct semid_ds *,
97				      struct svr4_semid_ds *);
98static void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *,
99				      struct semid_ds *);
100static int svr4_setsemun(caddr_t *sgp, union semun **argp,
101			      union semun *usp);
102static int svr4_semop(struct proc *, void *, register_t *);
103static int svr4_semget(struct proc *, void *, register_t *);
104static int svr4_semctl(struct proc *, void *, register_t *);
105#endif
106
107#ifdef SYSVMSG
108static void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
109				      struct svr4_msqid_ds *);
110static void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
111				      struct msqid_ds *);
112static int svr4_msgsnd(struct proc *, void *, register_t *);
113static int svr4_msgrcv(struct proc *, void *, register_t *);
114static int svr4_msgget(struct proc *, void *, register_t *);
115static int svr4_msgctl(struct proc *, void *, register_t *);
116#endif
117
118#ifdef SYSVSHM
119static void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
120				      struct svr4_shmid_ds *);
121static void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
122				      struct shmid_ds *);
123static int svr4_shmat(struct proc *, void *, register_t *);
124static int svr4_shmdt(struct proc *, void *, register_t *);
125static int svr4_shmget(struct proc *, void *, register_t *);
126static int svr4_shmctl(struct proc *, void *, register_t *);
127#endif
128
129#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
130
131static void
132svr4_to_bsd_ipc_perm(spp, bpp)
133	const struct svr4_ipc_perm *spp;
134	struct ipc_perm *bpp;
135{
136	bpp->key = spp->key;
137	bpp->uid = spp->uid;
138	bpp->gid = spp->gid;
139	bpp->cuid = spp->cuid;
140	bpp->cgid = spp->cgid;
141	bpp->mode = spp->mode;
142	bpp->seq = spp->seq;
143}
144
145static void
146bsd_to_svr4_ipc_perm(bpp, spp)
147	const struct ipc_perm *bpp;
148	struct svr4_ipc_perm *spp;
149{
150	spp->key = bpp->key;
151	spp->uid = bpp->uid;
152	spp->gid = bpp->gid;
153	spp->cuid = bpp->cuid;
154	spp->cgid = bpp->cgid;
155	spp->mode = bpp->mode;
156	spp->seq = bpp->seq;
157}
158#endif
159
160#ifdef SYSVSEM
161static void
162bsd_to_svr4_semid_ds(bds, sds)
163	const struct semid_ds *bds;
164	struct svr4_semid_ds *sds;
165{
166	bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
167	sds->sem_base = (struct svr4_sem *) bds->sem_base;
168	sds->sem_nsems = bds->sem_nsems;
169	sds->sem_otime = bds->sem_otime;
170	sds->sem_pad1 = bds->sem_pad1;
171	sds->sem_ctime = bds->sem_ctime;
172	sds->sem_pad2 = bds->sem_pad2;
173}
174
175static void
176svr4_to_bsd_semid_ds(sds, bds)
177	const struct svr4_semid_ds *sds;
178	struct semid_ds *bds;
179{
180	svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
181	bds->sem_base = (struct sem *) bds->sem_base;
182	bds->sem_nsems = sds->sem_nsems;
183	bds->sem_otime = sds->sem_otime;
184	bds->sem_pad1 = sds->sem_pad1;
185	bds->sem_ctime = sds->sem_ctime;
186	bds->sem_pad2 = sds->sem_pad2;
187}
188
189static int
190svr4_setsemun(sgp, argp, usp)
191	caddr_t *sgp;
192	union semun **argp;
193	union semun *usp;
194{
195	*argp = stackgap_alloc(sgp, sizeof(union semun));
196	return copyout((caddr_t)usp, *argp, sizeof(union semun));
197}
198
199struct svr4_sys_semctl_args {
200	syscallarg(int) what;
201	syscallarg(int) semid;
202	syscallarg(int) semnum;
203	syscallarg(int) cmd;
204	syscallarg(union semun) arg;
205};
206
207static int
208svr4_semctl(p, v, retval)
209	struct proc *p;
210	void *v;
211	register_t *retval;
212{
213	int error;
214	struct svr4_sys_semctl_args *uap = v;
215	struct sys___semctl_args ap;
216	struct svr4_semid_ds ss;
217	struct semid_ds bs, *bsp;
218	caddr_t sg = stackgap_init();
219
220	ap.semid = uap->semid;
221	ap.semnum = uap->semnum;
222
223	switch (uap->cmd) {
224	case SVR4_SEM_GETZCNT:
225	case SVR4_SEM_GETNCNT:
226	case SVR4_SEM_GETPID:
227	case SVR4_SEM_GETVAL:
228		switch (uap->cmd) {
229		case SVR4_SEM_GETZCNT:
230			ap.cmd = GETZCNT;
231			break;
232		case SVR4_SEM_GETNCNT:
233			ap.cmd = GETNCNT;
234			break;
235		case SVR4_SEM_GETPID:
236			ap.cmd = GETPID;
237			break;
238		case SVR4_SEM_GETVAL:
239			ap.cmd = GETVAL;
240			break;
241		}
242		return sys___semctl(p, &ap, retval);
243
244	case SVR4_SEM_SETVAL:
245		error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
246		if (error)
247			return error;
248		ap.cmd = SETVAL;
249		return sys___semctl(p, &ap, retval);
250
251	case SVR4_SEM_GETALL:
252		error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
253		if (error)
254			return error;
255		ap.cmd = GETVAL;
256		return sys___semctl(p, &ap, retval);
257
258	case SVR4_SEM_SETALL:
259		error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
260		if (error)
261			return error;
262		ap.cmd = SETVAL;
263		return sys___semctl(p, &ap, retval);
264
265	case SVR4_IPC_STAT:
266                ap.cmd = IPC_STAT;
267		bsp = stackgap_alloc(&sg, sizeof(bs));
268		error = svr4_setsemun(&sg, &ap.arg,
269				      (union semun *)&bsp);
270		if (error)
271			return error;
272                if ((error = sys___semctl(p, &ap, retval)) != 0)
273                        return error;
274		error = copyin((caddr_t)bsp, (caddr_t)&bs, sizeof(bs));
275                if (error)
276                        return error;
277                bsd_to_svr4_semid_ds(&bs, &ss);
278		return copyout(&ss, uap->arg.buf, sizeof(ss));
279
280	case SVR4_IPC_SET:
281		ap.cmd = IPC_SET;
282		bsp = stackgap_alloc(&sg, sizeof(bs));
283		error = svr4_setsemun(&sg, &ap.arg,
284				      (union semun *)&bsp);
285		if (error)
286			return error;
287		error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
288                if (error)
289                        return error;
290                svr4_to_bsd_semid_ds(&ss, &bs);
291		error = copyout(&bs, bsp, sizeof(bs));
292                if (error)
293                        return error;
294		return sys___semctl(p, &ap, retval);
295
296	case SVR4_IPC_RMID:
297		ap.cmd = IPC_RMID;
298		bsp = stackgap_alloc(&sg, sizeof(bs));
299		error = svr4_setsemun(&sg, &ap.arg,
300				      (union semun *)&bsp);
301		if (error)
302			return error;
303		error = copyin(uap->arg.buf, &ss, sizeof ss);
304                if (error)
305                        return error;
306                svr4_to_bsd_semid_ds(&ss, &bs);
307		error = copyout(&bs, bsp, sizeof(bs));
308		if (error)
309			return error;
310		return sys___semctl(p, &ap, retval);
311
312	default:
313		return EINVAL;
314	}
315}
316
317struct svr4_sys_semget_args {
318	syscallarg(int) what;
319	syscallarg(svr4_key_t) key;
320	syscallarg(int) nsems;
321	syscallarg(int) semflg;
322};
323
324static int
325svr4_semget(p, v, retval)
326	struct proc *p;
327	void *v;
328	register_t *retval;
329{
330	struct svr4_sys_semget_args *uap = v;
331	struct sys_semget_args ap;
332
333	ap.key = uap->key;
334	ap.nsems = uap->nsems;
335	ap.semflg = uap->semflg;
336
337	return sys_semget(p, &ap, retval);
338}
339
340struct svr4_sys_semop_args {
341	syscallarg(int) what;
342	syscallarg(int) semid;
343	syscallarg(struct svr4_sembuf *) sops;
344	syscallarg(u_int) nsops;
345};
346
347static int
348svr4_semop(p, v, retval)
349	struct proc *p;
350	void *v;
351	register_t *retval;
352{
353	struct svr4_sys_semop_args *uap = v;
354	struct sys_semop_args ap;
355
356	ap.semid = uap->semid;
357	/* These are the same */
358	ap.sops = (struct sembuf *) uap->sops;
359	ap.nsops = uap->nsops;
360
361	return sys_semop(p, &ap, retval);
362}
363
364int
365svr4_sys_semsys(p, v, retval)
366	struct proc *p;
367	void *v;
368	register_t *retval;
369{
370	struct svr4_sys_semsys_args *uap = v;
371
372	DPRINTF(("svr4_semsys(%d)\n", uap->what));
373
374	switch (uap->what) {
375	case SVR4_semctl:
376		return svr4_semctl(p, v, retval);
377	case SVR4_semget:
378		return svr4_semget(p, v, retval);
379	case SVR4_semop:
380		return svr4_semop(p, v, retval);
381	default:
382		return EINVAL;
383	}
384}
385#endif
386
387#ifdef SYSVMSG
388static void
389bsd_to_svr4_msqid_ds(bds, sds)
390	const struct msqid_ds *bds;
391	struct svr4_msqid_ds *sds;
392{
393	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
394	sds->msg_first = (struct svr4_msg *) bds->msg_first;
395	sds->msg_last = (struct svr4_msg *) bds->msg_last;
396	sds->msg_cbytes = bds->msg_cbytes;
397	sds->msg_qnum = bds->msg_qnum;
398	sds->msg_qbytes = bds->msg_qbytes;
399	sds->msg_lspid = bds->msg_lspid;
400	sds->msg_lrpid = bds->msg_lrpid;
401	sds->msg_stime = bds->msg_stime;
402	sds->msg_pad1 = bds->msg_pad1;
403	sds->msg_rtime = bds->msg_rtime;
404	sds->msg_pad2 = bds->msg_pad2;
405	sds->msg_ctime = bds->msg_ctime;
406	sds->msg_pad3 = bds->msg_pad3;
407
408	/* use the padding for the rest of the fields */
409	{
410		const short *pad = (const short *) bds->msg_pad4;
411		sds->msg_cv = pad[0];
412		sds->msg_qnum_cv = pad[1];
413	}
414}
415
416static void
417svr4_to_bsd_msqid_ds(sds, bds)
418	const struct svr4_msqid_ds *sds;
419	struct msqid_ds *bds;
420{
421	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
422	bds->msg_first = (struct msg *) sds->msg_first;
423	bds->msg_last = (struct msg *) sds->msg_last;
424	bds->msg_cbytes = sds->msg_cbytes;
425	bds->msg_qnum = sds->msg_qnum;
426	bds->msg_qbytes = sds->msg_qbytes;
427	bds->msg_lspid = sds->msg_lspid;
428	bds->msg_lrpid = sds->msg_lrpid;
429	bds->msg_stime = sds->msg_stime;
430	bds->msg_pad1 = sds->msg_pad1;
431	bds->msg_rtime = sds->msg_rtime;
432	bds->msg_pad2 = sds->msg_pad2;
433	bds->msg_ctime = sds->msg_ctime;
434	bds->msg_pad3 = sds->msg_pad3;
435
436	/* use the padding for the rest of the fields */
437	{
438		short *pad = (short *) bds->msg_pad4;
439		pad[0] = sds->msg_cv;
440		pad[1] = sds->msg_qnum_cv;
441	}
442}
443
444struct svr4_sys_msgsnd_args {
445	syscallarg(int) what;
446	syscallarg(int) msqid;
447	syscallarg(void *) msgp;
448	syscallarg(size_t) msgsz;
449	syscallarg(int) msgflg;
450};
451
452static int
453svr4_msgsnd(p, v, retval)
454	struct proc *p;
455	void *v;
456	register_t *retval;
457{
458	struct svr4_sys_msgsnd_args *uap = v;
459	struct sys_msgsnd_args ap;
460
461	ap.msqid = uap->msqid;
462	ap.msgp = uap->msgp;
463	ap.msgsz = uap->msgsz;
464	ap.msgflg = uap->msgflg;
465
466	return sys_msgsnd(p, &ap, retval);
467}
468
469struct svr4_sys_msgrcv_args {
470	syscallarg(int) what;
471	syscallarg(int) msqid;
472	syscallarg(void *) msgp;
473	syscallarg(size_t) msgsz;
474	syscallarg(long) msgtyp;
475	syscallarg(int) msgflg;
476};
477
478static int
479svr4_msgrcv(p, v, retval)
480	struct proc *p;
481	void *v;
482	register_t *retval;
483{
484	struct svr4_sys_msgrcv_args *uap = v;
485	struct sys_msgrcv_args ap;
486
487	ap.msqid = uap->msqid;
488	ap.msgp = uap->msgp;
489	ap.msgsz = uap->msgsz;
490	ap.msgtyp = uap->msgtyp;
491	ap.msgflg = uap->msgflg;
492
493	return sys_msgrcv(p, &ap, retval);
494}
495
496struct svr4_sys_msgget_args {
497	syscallarg(int) what;
498	syscallarg(svr4_key_t) key;
499	syscallarg(int) msgflg;
500};
501
502static int
503svr4_msgget(p, v, retval)
504	struct proc *p;
505	void *v;
506	register_t *retval;
507{
508	struct svr4_sys_msgget_args *uap = v;
509	struct sys_msgget_args ap;
510
511	ap.key = uap->key;
512	ap.msgflg = uap->msgflg;
513
514	return sys_msgget(p, &ap, retval);
515}
516
517struct svr4_sys_msgctl_args {
518	syscallarg(int) what;
519	syscallarg(int) msqid;
520	syscallarg(int) cmd;
521	syscallarg(struct svr4_msqid_ds *) buf;
522};
523
524static int
525svr4_msgctl(p, v, retval)
526	struct proc *p;
527	void *v;
528	register_t *retval;
529{
530	int error;
531	struct svr4_sys_msgctl_args *uap = v;
532	struct sys_msgctl_args ap;
533	struct svr4_msqid_ds ss;
534	struct msqid_ds bs;
535	caddr_t sg = stackgap_init();
536
537	ap.msqid = uap->msqid;
538	ap.cmd = uap->cmd;
539	ap.buf = stackgap_alloc(&sg, sizeof(bs));
540
541	switch (uap->cmd) {
542	case SVR4_IPC_STAT:
543		ap.cmd = IPC_STAT;
544		if ((error = sys_msgctl(p, &ap, retval)) != 0)
545			return error;
546		error = copyin(&bs, ap.buf, sizeof bs);
547		if (error)
548			return error;
549		bsd_to_svr4_msqid_ds(&bs, &ss);
550		return copyout(&ss, uap->buf, sizeof ss);
551
552	case SVR4_IPC_SET:
553		ap.cmd = IPC_SET;
554		error = copyin(uap->buf, &ss, sizeof ss);
555		if (error)
556			return error;
557		svr4_to_bsd_msqid_ds(&ss, &bs);
558		error = copyout(&bs, ap.buf, sizeof bs);
559		if (error)
560			return error;
561		return sys_msgctl(p, &ap, retval);
562
563	case SVR4_IPC_RMID:
564		ap.cmd = IPC_RMID;
565		error = copyin(uap->buf, &ss, sizeof ss);
566		if (error)
567			return error;
568		svr4_to_bsd_msqid_ds(&ss, &bs);
569		error = copyout(&bs, ap.buf, sizeof bs);
570		if (error)
571			return error;
572		return sys_msgctl(p, &ap, retval);
573
574	default:
575		return EINVAL;
576	}
577}
578
579int
580svr4_sys_msgsys(p, v, retval)
581	struct proc *p;
582	void *v;
583	register_t *retval;
584{
585	struct svr4_sys_msgsys_args *uap = v;
586
587	DPRINTF(("svr4_msgsys(%d)\n", uap->what));
588
589	switch (uap->what) {
590	case SVR4_msgsnd:
591		return svr4_msgsnd(p, v, retval);
592	case SVR4_msgrcv:
593		return svr4_msgrcv(p, v, retval);
594	case SVR4_msgget:
595		return svr4_msgget(p, v, retval);
596	case SVR4_msgctl:
597		return svr4_msgctl(p, v, retval);
598	default:
599		return EINVAL;
600	}
601}
602#endif
603
604#ifdef SYSVSHM
605
606static void
607bsd_to_svr4_shmid_ds(bds, sds)
608	const struct shmid_ds *bds;
609	struct svr4_shmid_ds *sds;
610{
611	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
612	sds->shm_segsz = bds->shm_segsz;
613	sds->shm_lkcnt = 0;
614	sds->shm_lpid = bds->shm_lpid;
615	sds->shm_cpid = bds->shm_cpid;
616	sds->shm_amp = bds->shm_internal;
617	sds->shm_nattch = bds->shm_nattch;
618	sds->shm_cnattch = 0;
619	sds->shm_atime = bds->shm_atime;
620	sds->shm_pad1 = 0;
621	sds->shm_dtime = bds->shm_dtime;
622	sds->shm_pad2 = 0;
623	sds->shm_ctime = bds->shm_ctime;
624	sds->shm_pad3 = 0;
625}
626
627static void
628svr4_to_bsd_shmid_ds(sds, bds)
629	const struct svr4_shmid_ds *sds;
630	struct shmid_ds *bds;
631{
632	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
633	bds->shm_segsz = sds->shm_segsz;
634	bds->shm_lpid = sds->shm_lpid;
635	bds->shm_cpid = sds->shm_cpid;
636	bds->shm_internal = sds->shm_amp;
637	bds->shm_nattch = sds->shm_nattch;
638	bds->shm_atime = sds->shm_atime;
639	bds->shm_dtime = sds->shm_dtime;
640	bds->shm_ctime = sds->shm_ctime;
641}
642
643struct svr4_sys_shmat_args {
644	syscallarg(int) what;
645	syscallarg(int) shmid;
646	syscallarg(void *) shmaddr;
647	syscallarg(int) shmflg;
648};
649
650static int
651svr4_shmat(p, v, retval)
652	struct proc *p;
653	void *v;
654	register_t *retval;
655{
656	struct svr4_sys_shmat_args *uap = v;
657	struct sys_shmat_args ap;
658
659	ap.shmid = uap->shmid;
660	ap.shmaddr = uap->shmaddr;
661	ap.shmflg = uap->shmflg;
662
663	return sys_shmat(p, &ap, retval);
664}
665
666struct svr4_sys_shmdt_args {
667	syscallarg(int) what;
668	syscallarg(void *) shmaddr;
669};
670
671static int
672svr4_shmdt(p, v, retval)
673	struct proc *p;
674	void *v;
675	register_t *retval;
676{
677	struct svr4_sys_shmdt_args *uap = v;
678	struct sys_shmdt_args ap;
679
680	ap.shmaddr = uap->shmaddr;
681
682	return sys_shmdt(p, &ap, retval);
683}
684
685struct svr4_sys_shmget_args {
686	syscallarg(int) what;
687	syscallarg(key_t) key;
688	syscallarg(int) size;
689	syscallarg(int) shmflg;
690};
691
692static int
693svr4_shmget(p, v, retval)
694	struct proc *p;
695	void *v;
696	register_t *retval;
697{
698	struct svr4_sys_shmget_args *uap = v;
699	struct sys_shmget_args ap;
700
701	ap.key = uap->key;
702	ap.size = uap->size;
703	ap.shmflg = uap->shmflg;
704
705	return sys_shmget(p, &ap, retval);
706}
707
708struct svr4_sys_shmctl_args {
709	syscallarg(int) what;
710	syscallarg(int) shmid;
711	syscallarg(int) cmd;
712	syscallarg(struct svr4_shmid_ds *) buf;
713};
714
715int
716svr4_shmctl(p, v, retval)
717	struct proc *p;
718	void *v;
719	register_t *retval;
720{
721	struct svr4_sys_shmctl_args *uap = v;
722	int error;
723	caddr_t sg = stackgap_init();
724	struct sys_shmctl_args ap;
725	struct shmid_ds bs;
726	struct svr4_shmid_ds ss;
727
728	ap.shmid = uap->shmid;
729
730	if (uap->buf != NULL) {
731		ap.buf = stackgap_alloc(&sg, sizeof (struct shmid_ds));
732		switch (uap->cmd) {
733		case SVR4_IPC_SET:
734		case SVR4_IPC_RMID:
735		case SVR4_SHM_LOCK:
736		case SVR4_SHM_UNLOCK:
737			error = copyin(uap->buf, (caddr_t) &ss,
738			    sizeof ss);
739			if (error)
740				return error;
741			svr4_to_bsd_shmid_ds(&ss, &bs);
742			error = copyout(&bs, ap.buf, sizeof bs);
743			if (error)
744				return error;
745			break;
746		default:
747			break;
748		}
749	}
750	else
751		ap.buf = NULL;
752
753
754	switch (uap->cmd) {
755	case SVR4_IPC_STAT:
756		ap.cmd = IPC_STAT;
757		if ((error = sys_shmctl(p, &ap, retval)) != 0)
758			return error;
759		if (uap->buf == NULL)
760			return 0;
761		error = copyin(&bs, ap.buf, sizeof bs);
762		if (error)
763			return error;
764		bsd_to_svr4_shmid_ds(&bs, &ss);
765		return copyout(&ss, uap->buf, sizeof ss);
766
767	case SVR4_IPC_SET:
768		ap.cmd = IPC_SET;
769		return sys_shmctl(p, &ap, retval);
770
771	case SVR4_IPC_RMID:
772	case SVR4_SHM_LOCK:
773	case SVR4_SHM_UNLOCK:
774		switch (uap->cmd) {
775		case SVR4_IPC_RMID:
776			ap.cmd = IPC_RMID;
777			break;
778		case SVR4_SHM_LOCK:
779			ap.cmd = SHM_LOCK;
780			break;
781		case SVR4_SHM_UNLOCK:
782			ap.cmd = SHM_UNLOCK;
783			break;
784		default:
785			return EINVAL;
786		}
787		return sys_shmctl(p, &ap, retval);
788
789	default:
790		return EINVAL;
791	}
792}
793
794int
795svr4_sys_shmsys(p, v, retval)
796	struct proc *p;
797	void *v;
798	register_t *retval;
799{
800	struct svr4_sys_shmsys_args *uap = v;
801
802	DPRINTF(("svr4_shmsys(%d)\n", uap->what));
803
804	switch (uap->what) {
805	case SVR4_shmat:
806		return svr4_shmat(p, v, retval);
807	case SVR4_shmdt:
808		return svr4_shmdt(p, v, retval);
809	case SVR4_shmget:
810		return svr4_shmget(p, v, retval);
811	case SVR4_shmctl:
812		return svr4_shmctl(p, v, retval);
813	default:
814		return ENOSYS;
815	}
816}
817#endif /* SYSVSHM */
818