svr4_ipc.c revision 159991
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 159991 2006-06-27 18:28:50Z jhb $");
75
76#include "opt_sysvipc.h"
77
78#include <sys/param.h>
79#include <sys/ipc.h>
80#include <sys/msg.h>
81#include <sys/proc.h>
82#include <sys/sem.h>
83#include <sys/shm.h>
84#include <sys/syscallsubr.h>
85#include <sys/sysproto.h>
86#include <sys/systm.h>
87#include <sys/time.h>
88
89#include <compat/svr4/svr4.h>
90#include <compat/svr4/svr4_types.h>
91#include <compat/svr4/svr4_signal.h>
92#include <compat/svr4/svr4_proto.h>
93#include <compat/svr4/svr4_util.h>
94#include <compat/svr4/svr4_ipc.h>
95
96#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
97static void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *,
98				      struct ipc_perm *);
99static void bsd_to_svr4_ipc_perm(const struct ipc_perm *,
100				      struct svr4_ipc_perm *);
101#endif
102
103#ifdef SYSVSEM
104static void bsd_to_svr4_semid_ds(const struct semid_ds *,
105				      struct svr4_semid_ds *);
106static void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *,
107				      struct semid_ds *);
108static int svr4_semop(struct thread *, void *);
109static int svr4_semget(struct thread *, void *);
110static int svr4_semctl(struct thread *, void *);
111#endif
112
113#ifdef SYSVMSG
114static void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
115				      struct svr4_msqid_ds *);
116static void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
117				      struct msqid_ds *);
118static int svr4_msgsnd(struct thread *, void *);
119static int svr4_msgrcv(struct thread *, void *);
120static int svr4_msgget(struct thread *, void *);
121static int svr4_msgctl(struct thread *, void *);
122#endif
123
124#ifdef SYSVSHM
125static void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
126				      struct svr4_shmid_ds *);
127static void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
128				      struct shmid_ds *);
129static int svr4_shmat(struct thread *, void *);
130static int svr4_shmdt(struct thread *, void *);
131static int svr4_shmget(struct thread *, void *);
132static int svr4_shmctl(struct thread *, void *);
133#endif
134
135#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
136
137static void
138svr4_to_bsd_ipc_perm(spp, bpp)
139	const struct svr4_ipc_perm *spp;
140	struct ipc_perm *bpp;
141{
142	bpp->key = spp->key;
143	bpp->uid = spp->uid;
144	bpp->gid = spp->gid;
145	bpp->cuid = spp->cuid;
146	bpp->cgid = spp->cgid;
147	bpp->mode = spp->mode;
148	bpp->seq = spp->seq;
149}
150
151static void
152bsd_to_svr4_ipc_perm(bpp, spp)
153	const struct ipc_perm *bpp;
154	struct svr4_ipc_perm *spp;
155{
156	spp->key = bpp->key;
157	spp->uid = bpp->uid;
158	spp->gid = bpp->gid;
159	spp->cuid = bpp->cuid;
160	spp->cgid = bpp->cgid;
161	spp->mode = bpp->mode;
162	spp->seq = bpp->seq;
163}
164#endif
165
166#ifdef SYSVSEM
167static void
168bsd_to_svr4_semid_ds(bds, sds)
169	const struct semid_ds *bds;
170	struct svr4_semid_ds *sds;
171{
172	bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
173	sds->sem_base = (struct svr4_sem *) bds->sem_base;
174	sds->sem_nsems = bds->sem_nsems;
175	sds->sem_otime = bds->sem_otime;
176	sds->sem_pad1 = bds->sem_pad1;
177	sds->sem_ctime = bds->sem_ctime;
178	sds->sem_pad2 = bds->sem_pad2;
179}
180
181static void
182svr4_to_bsd_semid_ds(sds, bds)
183	const struct svr4_semid_ds *sds;
184	struct semid_ds *bds;
185{
186	svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
187	bds->sem_base = (struct sem *) bds->sem_base;
188	bds->sem_nsems = sds->sem_nsems;
189	bds->sem_otime = sds->sem_otime;
190	bds->sem_pad1 = sds->sem_pad1;
191	bds->sem_ctime = sds->sem_ctime;
192	bds->sem_pad2 = sds->sem_pad2;
193}
194
195struct svr4_sys_semctl_args {
196	int what;
197	int semid;
198	int semnum;
199	int cmd;
200	union semun arg;
201};
202
203static int
204svr4_semctl(td, v)
205	struct thread *td;
206	void *v;
207{
208	struct svr4_sys_semctl_args *uap = v;
209	struct svr4_semid_ds ss;
210	struct semid_ds bs;
211	union semun semun;
212	int cmd, error;
213
214	switch (uap->cmd) {
215	case SVR4_SEM_GETZCNT:
216		cmd = GETZCNT;
217		break;
218
219	case SVR4_SEM_GETNCNT:
220		cmd = GETNCNT;
221		break;
222
223	case SVR4_SEM_GETPID:
224		cmd = GETPID;
225		break;
226
227	case SVR4_SEM_GETVAL:
228		cmd = GETVAL;
229		break;
230
231	case SVR4_SEM_SETVAL:
232		cmd = SETVAL;
233		break;
234
235	case SVR4_SEM_GETALL:
236		cmd = GETVAL;
237		break;
238
239	case SVR4_SEM_SETALL:
240		cmd = SETVAL;
241		break;
242
243	case SVR4_IPC_STAT:
244		cmd = IPC_STAT;
245		semun.buf = &bs;
246		error = kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
247		    UIO_SYSSPACE);
248		if (error)
249                        return error;
250                bsd_to_svr4_semid_ds(&bs, &ss);
251		return copyout(&ss, uap->arg.buf, sizeof(ss));
252
253	case SVR4_IPC_SET:
254		cmd = IPC_SET;
255		error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
256                if (error)
257                        return error;
258                svr4_to_bsd_semid_ds(&ss, &bs);
259		semun.buf = &bs;
260		return kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
261		    UIO_SYSSPACE);
262
263	case SVR4_IPC_RMID:
264		cmd = IPC_RMID;
265		break;
266
267	default:
268		return EINVAL;
269	}
270
271	return kern_semctl(td, uap->semid, uap->semnum, cmd, &uap->arg,
272	    UIO_USERSPACE);
273}
274
275struct svr4_sys_semget_args {
276	int what;
277	svr4_key_t key;
278	int nsems;
279	int semflg;
280};
281
282static int
283svr4_semget(td, v)
284	struct thread *td;
285	void *v;
286{
287	struct svr4_sys_semget_args *uap = v;
288	struct semget_args ap;
289
290	ap.key = uap->key;
291	ap.nsems = uap->nsems;
292	ap.semflg = uap->semflg;
293
294	return semget(td, &ap);
295}
296
297struct svr4_sys_semop_args {
298	int what;
299	int semid;
300	struct svr4_sembuf * sops;
301	u_int nsops;
302};
303
304static int
305svr4_semop(td, v)
306	struct thread *td;
307	void *v;
308{
309	struct svr4_sys_semop_args *uap = v;
310	struct semop_args ap;
311
312	ap.semid = uap->semid;
313	/* These are the same */
314	ap.sops = (struct sembuf *) uap->sops;
315	ap.nsops = uap->nsops;
316
317	return semop(td, &ap);
318}
319
320int
321svr4_sys_semsys(td, uap)
322	struct thread *td;
323	struct svr4_sys_semsys_args *uap;
324{
325
326	DPRINTF(("svr4_semsys(%d)\n", uap->what));
327
328	switch (uap->what) {
329	case SVR4_semctl:
330		return svr4_semctl(td, uap);
331	case SVR4_semget:
332		return svr4_semget(td, uap);
333	case SVR4_semop:
334		return svr4_semop(td, uap);
335	default:
336		return EINVAL;
337	}
338}
339
340MODULE_DEPEND(svr4elf, sysvsem, 1, 1, 1);
341#endif
342
343#ifdef SYSVMSG
344static void
345bsd_to_svr4_msqid_ds(bds, sds)
346	const struct msqid_ds *bds;
347	struct svr4_msqid_ds *sds;
348{
349	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
350	sds->msg_first = (struct svr4_msg *) bds->msg_first;
351	sds->msg_last = (struct svr4_msg *) bds->msg_last;
352	sds->msg_cbytes = bds->msg_cbytes;
353	sds->msg_qnum = bds->msg_qnum;
354	sds->msg_qbytes = bds->msg_qbytes;
355	sds->msg_lspid = bds->msg_lspid;
356	sds->msg_lrpid = bds->msg_lrpid;
357	sds->msg_stime = bds->msg_stime;
358	sds->msg_pad1 = bds->msg_pad1;
359	sds->msg_rtime = bds->msg_rtime;
360	sds->msg_pad2 = bds->msg_pad2;
361	sds->msg_ctime = bds->msg_ctime;
362	sds->msg_pad3 = bds->msg_pad3;
363
364	/* use the padding for the rest of the fields */
365	{
366		const short *pad = (const short *) bds->msg_pad4;
367		sds->msg_cv = pad[0];
368		sds->msg_qnum_cv = pad[1];
369	}
370}
371
372static void
373svr4_to_bsd_msqid_ds(sds, bds)
374	const struct svr4_msqid_ds *sds;
375	struct msqid_ds *bds;
376{
377	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
378	bds->msg_first = (struct msg *) sds->msg_first;
379	bds->msg_last = (struct msg *) sds->msg_last;
380	bds->msg_cbytes = sds->msg_cbytes;
381	bds->msg_qnum = sds->msg_qnum;
382	bds->msg_qbytes = sds->msg_qbytes;
383	bds->msg_lspid = sds->msg_lspid;
384	bds->msg_lrpid = sds->msg_lrpid;
385	bds->msg_stime = sds->msg_stime;
386	bds->msg_pad1 = sds->msg_pad1;
387	bds->msg_rtime = sds->msg_rtime;
388	bds->msg_pad2 = sds->msg_pad2;
389	bds->msg_ctime = sds->msg_ctime;
390	bds->msg_pad3 = sds->msg_pad3;
391
392	/* use the padding for the rest of the fields */
393	{
394		short *pad = (short *) bds->msg_pad4;
395		pad[0] = sds->msg_cv;
396		pad[1] = sds->msg_qnum_cv;
397	}
398}
399
400struct svr4_sys_msgsnd_args {
401	int what;
402	int msqid;
403	void * msgp;
404	size_t msgsz;
405	int msgflg;
406};
407
408static int
409svr4_msgsnd(td, v)
410	struct thread *td;
411	void *v;
412{
413	struct svr4_sys_msgsnd_args *uap = v;
414	struct msgsnd_args ap;
415
416	ap.msqid = uap->msqid;
417	ap.msgp = uap->msgp;
418	ap.msgsz = uap->msgsz;
419	ap.msgflg = uap->msgflg;
420
421	return msgsnd(td, &ap);
422}
423
424struct svr4_sys_msgrcv_args {
425	int what;
426	int msqid;
427	void * msgp;
428	size_t msgsz;
429	long msgtyp;
430	int msgflg;
431};
432
433static int
434svr4_msgrcv(td, v)
435	struct thread *td;
436	void *v;
437{
438	struct svr4_sys_msgrcv_args *uap = v;
439	struct msgrcv_args ap;
440
441	ap.msqid = uap->msqid;
442	ap.msgp = uap->msgp;
443	ap.msgsz = uap->msgsz;
444	ap.msgtyp = uap->msgtyp;
445	ap.msgflg = uap->msgflg;
446
447	return msgrcv(td, &ap);
448}
449
450struct svr4_sys_msgget_args {
451	int what;
452	svr4_key_t key;
453	int msgflg;
454};
455
456static int
457svr4_msgget(td, v)
458	struct thread *td;
459	void *v;
460{
461	struct svr4_sys_msgget_args *uap = v;
462	struct msgget_args ap;
463
464	ap.key = uap->key;
465	ap.msgflg = uap->msgflg;
466
467	return msgget(td, &ap);
468}
469
470struct svr4_sys_msgctl_args {
471	int what;
472	int msqid;
473	int cmd;
474	struct svr4_msqid_ds * buf;
475};
476
477static int
478svr4_msgctl(td, v)
479	struct thread *td;
480	void *v;
481{
482	struct svr4_sys_msgctl_args *uap = v;
483	struct svr4_msqid_ds ss;
484	struct msqid_ds bs;
485	int error;
486
487	switch (uap->cmd) {
488	case SVR4_IPC_STAT:
489		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
490		if (error)
491			return error;
492		bsd_to_svr4_msqid_ds(&bs, &ss);
493		return copyout(&ss, uap->buf, sizeof ss);
494
495	case SVR4_IPC_SET:
496		error = copyin(uap->buf, &ss, sizeof ss);
497		if (error)
498			return error;
499		svr4_to_bsd_msqid_ds(&ss, &bs);
500		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
501
502	case SVR4_IPC_RMID:
503		error = copyin(uap->buf, &ss, sizeof ss);
504		if (error)
505			return error;
506		svr4_to_bsd_msqid_ds(&ss, &bs);
507		return (kern_msgctl(td, uap->msqid, IPC_RMID, &bs));
508
509	default:
510		return EINVAL;
511	}
512}
513
514int
515svr4_sys_msgsys(td, uap)
516	struct thread *td;
517	struct svr4_sys_msgsys_args *uap;
518{
519
520	DPRINTF(("svr4_msgsys(%d)\n", uap->what));
521
522	switch (uap->what) {
523	case SVR4_msgsnd:
524		return svr4_msgsnd(td, uap);
525	case SVR4_msgrcv:
526		return svr4_msgrcv(td, uap);
527	case SVR4_msgget:
528		return svr4_msgget(td, uap);
529	case SVR4_msgctl:
530		return svr4_msgctl(td, uap);
531	default:
532		return EINVAL;
533	}
534}
535
536MODULE_DEPEND(svr4elf, sysvmsg, 1, 1, 1);
537#endif
538
539#ifdef SYSVSHM
540
541static void
542bsd_to_svr4_shmid_ds(bds, sds)
543	const struct shmid_ds *bds;
544	struct svr4_shmid_ds *sds;
545{
546	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
547	sds->shm_segsz = bds->shm_segsz;
548	sds->shm_lkcnt = 0;
549	sds->shm_lpid = bds->shm_lpid;
550	sds->shm_cpid = bds->shm_cpid;
551	sds->shm_amp = bds->shm_internal;
552	sds->shm_nattch = bds->shm_nattch;
553	sds->shm_cnattch = 0;
554	sds->shm_atime = bds->shm_atime;
555	sds->shm_pad1 = 0;
556	sds->shm_dtime = bds->shm_dtime;
557	sds->shm_pad2 = 0;
558	sds->shm_ctime = bds->shm_ctime;
559	sds->shm_pad3 = 0;
560}
561
562static void
563svr4_to_bsd_shmid_ds(sds, bds)
564	const struct svr4_shmid_ds *sds;
565	struct shmid_ds *bds;
566{
567	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
568	bds->shm_segsz = sds->shm_segsz;
569	bds->shm_lpid = sds->shm_lpid;
570	bds->shm_cpid = sds->shm_cpid;
571	bds->shm_internal = sds->shm_amp;
572	bds->shm_nattch = sds->shm_nattch;
573	bds->shm_atime = sds->shm_atime;
574	bds->shm_dtime = sds->shm_dtime;
575	bds->shm_ctime = sds->shm_ctime;
576}
577
578struct svr4_sys_shmat_args {
579	int what;
580	int shmid;
581	void * shmaddr;
582	int shmflg;
583};
584
585static int
586svr4_shmat(td, v)
587	struct thread *td;
588	void *v;
589{
590	struct svr4_sys_shmat_args *uap = v;
591	struct shmat_args ap;
592
593	ap.shmid = uap->shmid;
594	ap.shmaddr = uap->shmaddr;
595	ap.shmflg = uap->shmflg;
596
597	return shmat(td, &ap);
598}
599
600struct svr4_sys_shmdt_args {
601	int what;
602	void * shmaddr;
603};
604
605static int
606svr4_shmdt(td, v)
607	struct thread *td;
608	void *v;
609{
610	struct svr4_sys_shmdt_args *uap = v;
611	struct shmdt_args ap;
612
613	ap.shmaddr = uap->shmaddr;
614
615	return shmdt(td, &ap);
616}
617
618struct svr4_sys_shmget_args {
619	int what;
620	key_t key;
621	int size;
622	int shmflg;
623};
624
625static int
626svr4_shmget(td, v)
627	struct thread *td;
628	void *v;
629{
630	struct svr4_sys_shmget_args *uap = v;
631	struct shmget_args ap;
632
633	ap.key = uap->key;
634	ap.size = uap->size;
635	ap.shmflg = uap->shmflg;
636
637	return shmget(td, &ap);
638}
639
640struct svr4_sys_shmctl_args {
641	int what;
642	int shmid;
643	int cmd;
644	struct svr4_shmid_ds * buf;
645};
646
647int
648svr4_shmctl(td, v)
649	struct thread *td;
650	void *v;
651{
652	struct svr4_sys_shmctl_args *uap = v;
653	int error;
654	caddr_t sg = stackgap_init();
655	struct shmctl_args ap;
656	struct shmid_ds bs;
657	struct svr4_shmid_ds ss;
658
659	ap.shmid = uap->shmid;
660
661	if (uap->buf != NULL) {
662		ap.buf = stackgap_alloc(&sg, sizeof (struct shmid_ds));
663		switch (uap->cmd) {
664		case SVR4_IPC_SET:
665		case SVR4_IPC_RMID:
666		case SVR4_SHM_LOCK:
667		case SVR4_SHM_UNLOCK:
668			error = copyin(uap->buf, (caddr_t) &ss,
669			    sizeof ss);
670			if (error)
671				return error;
672			svr4_to_bsd_shmid_ds(&ss, &bs);
673			error = copyout(&bs, ap.buf, sizeof bs);
674			if (error)
675				return error;
676			break;
677		default:
678			break;
679		}
680	}
681	else
682		ap.buf = NULL;
683
684
685	switch (uap->cmd) {
686	case SVR4_IPC_STAT:
687		ap.cmd = IPC_STAT;
688		if ((error = shmctl(td, &ap)) != 0)
689			return error;
690		if (uap->buf == NULL)
691			return 0;
692		error = copyin(&bs, ap.buf, sizeof bs);
693		if (error)
694			return error;
695		bsd_to_svr4_shmid_ds(&bs, &ss);
696		return copyout(&ss, uap->buf, sizeof ss);
697
698	case SVR4_IPC_SET:
699		ap.cmd = IPC_SET;
700		return shmctl(td, &ap);
701
702	case SVR4_IPC_RMID:
703	case SVR4_SHM_LOCK:
704	case SVR4_SHM_UNLOCK:
705		switch (uap->cmd) {
706		case SVR4_IPC_RMID:
707			ap.cmd = IPC_RMID;
708			break;
709		case SVR4_SHM_LOCK:
710			ap.cmd = SHM_LOCK;
711			break;
712		case SVR4_SHM_UNLOCK:
713			ap.cmd = SHM_UNLOCK;
714			break;
715		default:
716			return EINVAL;
717		}
718		return shmctl(td, &ap);
719
720	default:
721		return EINVAL;
722	}
723}
724
725int
726svr4_sys_shmsys(td, uap)
727	struct thread *td;
728	struct svr4_sys_shmsys_args *uap;
729{
730
731	DPRINTF(("svr4_shmsys(%d)\n", uap->what));
732
733	switch (uap->what) {
734	case SVR4_shmat:
735		return svr4_shmat(td, uap);
736	case SVR4_shmdt:
737		return svr4_shmdt(td, uap);
738	case SVR4_shmget:
739		return svr4_shmget(td, uap);
740	case SVR4_shmctl:
741		return svr4_shmctl(td, uap);
742	default:
743		return ENOSYS;
744	}
745}
746
747MODULE_DEPEND(svr4elf, sysvshm, 1, 1, 1);
748#endif /* SYSVSHM */
749