svr4_ipc.c revision 263687
1169695Skan/*-
2169695Skan * Copyright (c) 1995 The NetBSD Foundation, Inc.
3169695Skan * All rights reserved.
4169695Skan *
5169695Skan * This code is derived from software contributed to The NetBSD Foundation
6169695Skan * by Christos Zoulas.
7169695Skan *
8169695Skan * Redistribution and use in source and binary forms, with or without
9169695Skan * modification, are permitted provided that the following conditions
10169695Skan * are met:
11169695Skan * 1. Redistributions of source code must retain the above copyright
12169695Skan *    notice, this list of conditions and the following disclaimer.
13169695Skan * 2. Redistributions in binary form must reproduce the above copyright
14169695Skan *    notice, this list of conditions and the following disclaimer in the
15169695Skan *    documentation and/or other materials provided with the distribution.
16169695Skan *
17169695Skan * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18169695Skan * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19169695Skan * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20169695Skan * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21169695Skan * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22169695Skan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23169695Skan * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24169695Skan * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25169695Skan * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26169695Skan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27169695Skan * POSSIBILITY OF SUCH DAMAGE.
28169695Skan */
29169695Skan/*-
30169695Skan * Portions of this code have been derived from software contributed
31169695Skan * to the FreeBSD Project by Mark Newton.
32169695Skan *
33169695Skan * Copyright (c) 1999 Mark Newton
34169695Skan * All rights reserved.
35169695Skan *
36169695Skan * Redistribution and use in source and binary forms, with or without
37169695Skan * modification, are permitted provided that the following conditions
38169695Skan * are met:
39169695Skan * 1. Redistributions of source code must retain the above copyright
40169695Skan *    notice, this list of conditions and the following disclaimer.
41169695Skan * 2. Redistributions in binary form must reproduce the above copyright
42169695Skan *    notice, this list of conditions and the following disclaimer in the
43169695Skan *    documentation and/or other materials provided with the distribution.
44169695Skan * 3. The name of the author may not be used to endorse or promote products
45169695Skan *    derived from this software without specific prior written permission
46169695Skan *
47169695Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48169695Skan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49169695Skan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50169695Skan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
51169695Skan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52169695Skan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53169695Skan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54169695Skan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55169695Skan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56169695Skan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57169695Skan *
58169695Skan * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due
59169695Skan * to preprocessor conditionals).  A nice project for a kernel hacking
60169695Skan * novice might be to MakeItGo, but I have more important fish to fry
61169695Skan * at present.
62169695Skan *
63169695Skan *	Derived from: $NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $
64169695Skan */
65169695Skan
66169695Skan#include <sys/cdefs.h>
67169695Skan__FBSDID("$FreeBSD: stable/10/sys/compat/svr4/svr4_ipc.c 263687 2014-03-24 13:48:04Z emaste $");
68169695Skan
69169695Skan#include "opt_sysvipc.h"
70169695Skan
71169695Skan#include <sys/param.h>
72169695Skan#include <sys/ipc.h>
73169695Skan#include <sys/msg.h>
74169695Skan#include <sys/proc.h>
75169695Skan#include <sys/sem.h>
76169695Skan#include <sys/shm.h>
77169695Skan#include <sys/syscallsubr.h>
78169695Skan#include <sys/sysproto.h>
79169695Skan#include <sys/systm.h>
80169695Skan#include <sys/time.h>
81169695Skan
82169695Skan#include <compat/svr4/svr4.h>
83169695Skan#include <compat/svr4/svr4_types.h>
84169695Skan#include <compat/svr4/svr4_signal.h>
85169695Skan#include <compat/svr4/svr4_proto.h>
86169695Skan#include <compat/svr4/svr4_util.h>
87169695Skan#include <compat/svr4/svr4_ipc.h>
88169695Skan
89#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
90static void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *,
91				      struct ipc_perm *);
92static void bsd_to_svr4_ipc_perm(const struct ipc_perm *,
93				      struct svr4_ipc_perm *);
94#endif
95
96#ifdef SYSVSEM
97static void bsd_to_svr4_semid_ds(const struct semid_ds *,
98				      struct svr4_semid_ds *);
99static void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *,
100				      struct semid_ds *);
101static int svr4_semop(struct thread *, void *);
102static int svr4_semget(struct thread *, void *);
103static int svr4_semctl(struct thread *, void *);
104#endif
105
106#ifdef SYSVMSG
107static void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
108				      struct svr4_msqid_ds *);
109static void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
110				      struct msqid_ds *);
111static int svr4_msgsnd(struct thread *, void *);
112static int svr4_msgrcv(struct thread *, void *);
113static int svr4_msgget(struct thread *, void *);
114static int svr4_msgctl(struct thread *, void *);
115#endif
116
117#ifdef SYSVSHM
118static void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
119				      struct svr4_shmid_ds *);
120static void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
121				      struct shmid_ds *);
122static int svr4_shmat(struct thread *, void *);
123static int svr4_shmdt(struct thread *, void *);
124static int svr4_shmget(struct thread *, void *);
125static int svr4_shmctl(struct thread *, void *);
126#endif
127
128#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
129
130static void
131svr4_to_bsd_ipc_perm(spp, bpp)
132	const struct svr4_ipc_perm *spp;
133	struct ipc_perm *bpp;
134{
135	bpp->key = spp->key;
136	bpp->uid = spp->uid;
137	bpp->gid = spp->gid;
138	bpp->cuid = spp->cuid;
139	bpp->cgid = spp->cgid;
140	bpp->mode = spp->mode;
141	bpp->seq = spp->seq;
142}
143
144static void
145bsd_to_svr4_ipc_perm(bpp, spp)
146	const struct ipc_perm *bpp;
147	struct svr4_ipc_perm *spp;
148{
149	spp->key = bpp->key;
150	spp->uid = bpp->uid;
151	spp->gid = bpp->gid;
152	spp->cuid = bpp->cuid;
153	spp->cgid = bpp->cgid;
154	spp->mode = bpp->mode;
155	spp->seq = bpp->seq;
156}
157#endif
158
159#ifdef SYSVSEM
160static void
161bsd_to_svr4_semid_ds(bds, sds)
162	const struct semid_ds *bds;
163	struct svr4_semid_ds *sds;
164{
165	bzero(sds, sizeof(*sds));
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_ctime = bds->sem_ctime;
171}
172
173static void
174svr4_to_bsd_semid_ds(sds, bds)
175	const struct svr4_semid_ds *sds;
176	struct semid_ds *bds;
177{
178	svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
179	bds->sem_base = (struct sem *) bds->sem_base;
180	bds->sem_nsems = sds->sem_nsems;
181	bds->sem_otime = sds->sem_otime;
182	bds->sem_ctime = sds->sem_ctime;
183}
184
185struct svr4_sys_semctl_args {
186	int what;
187	int semid;
188	int semnum;
189	int cmd;
190	union semun arg;
191};
192
193static int
194svr4_semctl(td, v)
195	struct thread *td;
196	void *v;
197{
198	struct svr4_sys_semctl_args *uap = v;
199	struct svr4_semid_ds ss;
200	struct semid_ds bs;
201	union semun semun;
202	register_t rval;
203	int cmd, error;
204
205	switch (uap->cmd) {
206	case SVR4_SEM_GETZCNT:
207		cmd = GETZCNT;
208		break;
209
210	case SVR4_SEM_GETNCNT:
211		cmd = GETNCNT;
212		break;
213
214	case SVR4_SEM_GETPID:
215		cmd = GETPID;
216		break;
217
218	case SVR4_SEM_GETVAL:
219		cmd = GETVAL;
220		break;
221
222	case SVR4_SEM_SETVAL:
223		cmd = SETVAL;
224		break;
225
226	case SVR4_SEM_GETALL:
227		cmd = GETVAL;
228		break;
229
230	case SVR4_SEM_SETALL:
231		cmd = SETVAL;
232		break;
233
234	case SVR4_IPC_STAT:
235		cmd = IPC_STAT;
236		semun.buf = &bs;
237		error = kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
238		    &rval);
239		if (error)
240                        return (error);
241                bsd_to_svr4_semid_ds(&bs, &ss);
242		error = copyout(&ss, uap->arg.buf, sizeof(ss));
243		if (error == 0)
244			td->td_retval[0] = rval;
245		return (error);
246
247	case SVR4_IPC_SET:
248		cmd = IPC_SET;
249		error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
250                if (error)
251                        return (error);
252                svr4_to_bsd_semid_ds(&ss, &bs);
253		semun.buf = &bs;
254		return (kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
255		    td->td_retval));
256
257	case SVR4_IPC_RMID:
258		cmd = IPC_RMID;
259		break;
260
261	default:
262		return EINVAL;
263	}
264
265	return (kern_semctl(td, uap->semid, uap->semnum, cmd, &uap->arg,
266	    td->td_retval));
267}
268
269struct svr4_sys_semget_args {
270	int what;
271	svr4_key_t key;
272	int nsems;
273	int semflg;
274};
275
276static int
277svr4_semget(td, v)
278	struct thread *td;
279	void *v;
280{
281	struct svr4_sys_semget_args *uap = v;
282	struct semget_args ap;
283
284	ap.key = uap->key;
285	ap.nsems = uap->nsems;
286	ap.semflg = uap->semflg;
287
288	return sys_semget(td, &ap);
289}
290
291struct svr4_sys_semop_args {
292	int what;
293	int semid;
294	struct svr4_sembuf * sops;
295	u_int nsops;
296};
297
298static int
299svr4_semop(td, v)
300	struct thread *td;
301	void *v;
302{
303	struct svr4_sys_semop_args *uap = v;
304	struct semop_args ap;
305
306	ap.semid = uap->semid;
307	/* These are the same */
308	ap.sops = (struct sembuf *) uap->sops;
309	ap.nsops = uap->nsops;
310
311	return sys_semop(td, &ap);
312}
313
314int
315svr4_sys_semsys(td, uap)
316	struct thread *td;
317	struct svr4_sys_semsys_args *uap;
318{
319
320	DPRINTF(("svr4_semsys(%d)\n", uap->what));
321
322	switch (uap->what) {
323	case SVR4_semctl:
324		return svr4_semctl(td, uap);
325	case SVR4_semget:
326		return svr4_semget(td, uap);
327	case SVR4_semop:
328		return svr4_semop(td, uap);
329	default:
330		return EINVAL;
331	}
332}
333
334MODULE_DEPEND(svr4elf, sysvsem, 1, 1, 1);
335#endif
336
337#ifdef SYSVMSG
338static void
339bsd_to_svr4_msqid_ds(bds, sds)
340	const struct msqid_ds *bds;
341	struct svr4_msqid_ds *sds;
342{
343	bzero(sds, sizeof(*sds));
344	bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
345	sds->msg_first = (struct svr4_msg *) bds->msg_first;
346	sds->msg_last = (struct svr4_msg *) bds->msg_last;
347	sds->msg_cbytes = bds->msg_cbytes;
348	sds->msg_qnum = bds->msg_qnum;
349	sds->msg_qbytes = bds->msg_qbytes;
350	sds->msg_lspid = bds->msg_lspid;
351	sds->msg_lrpid = bds->msg_lrpid;
352	sds->msg_stime = bds->msg_stime;
353	sds->msg_rtime = bds->msg_rtime;
354	sds->msg_ctime = bds->msg_ctime;
355}
356
357static void
358svr4_to_bsd_msqid_ds(sds, bds)
359	const struct svr4_msqid_ds *sds;
360	struct msqid_ds *bds;
361{
362	svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
363	bds->msg_first = (struct msg *) sds->msg_first;
364	bds->msg_last = (struct msg *) sds->msg_last;
365	bds->msg_cbytes = sds->msg_cbytes;
366	bds->msg_qnum = sds->msg_qnum;
367	bds->msg_qbytes = sds->msg_qbytes;
368	bds->msg_lspid = sds->msg_lspid;
369	bds->msg_lrpid = sds->msg_lrpid;
370	bds->msg_stime = sds->msg_stime;
371	bds->msg_rtime = sds->msg_rtime;
372	bds->msg_ctime = sds->msg_ctime;
373}
374
375struct svr4_sys_msgsnd_args {
376	int what;
377	int msqid;
378	void * msgp;
379	size_t msgsz;
380	int msgflg;
381};
382
383static int
384svr4_msgsnd(td, v)
385	struct thread *td;
386	void *v;
387{
388	struct svr4_sys_msgsnd_args *uap = v;
389	struct msgsnd_args ap;
390
391	ap.msqid = uap->msqid;
392	ap.msgp = uap->msgp;
393	ap.msgsz = uap->msgsz;
394	ap.msgflg = uap->msgflg;
395
396	return sys_msgsnd(td, &ap);
397}
398
399struct svr4_sys_msgrcv_args {
400	int what;
401	int msqid;
402	void * msgp;
403	size_t msgsz;
404	long msgtyp;
405	int msgflg;
406};
407
408static int
409svr4_msgrcv(td, v)
410	struct thread *td;
411	void *v;
412{
413	struct svr4_sys_msgrcv_args *uap = v;
414	struct msgrcv_args ap;
415
416	ap.msqid = uap->msqid;
417	ap.msgp = uap->msgp;
418	ap.msgsz = uap->msgsz;
419	ap.msgtyp = uap->msgtyp;
420	ap.msgflg = uap->msgflg;
421
422	return sys_msgrcv(td, &ap);
423}
424
425struct svr4_sys_msgget_args {
426	int what;
427	svr4_key_t key;
428	int msgflg;
429};
430
431static int
432svr4_msgget(td, v)
433	struct thread *td;
434	void *v;
435{
436	struct svr4_sys_msgget_args *uap = v;
437	struct msgget_args ap;
438
439	ap.key = uap->key;
440	ap.msgflg = uap->msgflg;
441
442	return sys_msgget(td, &ap);
443}
444
445struct svr4_sys_msgctl_args {
446	int what;
447	int msqid;
448	int cmd;
449	struct svr4_msqid_ds * buf;
450};
451
452static int
453svr4_msgctl(td, v)
454	struct thread *td;
455	void *v;
456{
457	struct svr4_sys_msgctl_args *uap = v;
458	struct svr4_msqid_ds ss;
459	struct msqid_ds bs;
460	int error;
461
462	switch (uap->cmd) {
463	case SVR4_IPC_STAT:
464		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
465		if (error)
466			return error;
467		bsd_to_svr4_msqid_ds(&bs, &ss);
468		return copyout(&ss, uap->buf, sizeof ss);
469
470	case SVR4_IPC_SET:
471		error = copyin(uap->buf, &ss, sizeof ss);
472		if (error)
473			return error;
474		svr4_to_bsd_msqid_ds(&ss, &bs);
475		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
476
477	case SVR4_IPC_RMID:
478		return (kern_msgctl(td, uap->msqid, IPC_RMID, NULL));
479
480	default:
481		return EINVAL;
482	}
483}
484
485int
486svr4_sys_msgsys(td, uap)
487	struct thread *td;
488	struct svr4_sys_msgsys_args *uap;
489{
490
491	DPRINTF(("svr4_msgsys(%d)\n", uap->what));
492
493	switch (uap->what) {
494	case SVR4_msgsnd:
495		return svr4_msgsnd(td, uap);
496	case SVR4_msgrcv:
497		return svr4_msgrcv(td, uap);
498	case SVR4_msgget:
499		return svr4_msgget(td, uap);
500	case SVR4_msgctl:
501		return svr4_msgctl(td, uap);
502	default:
503		return EINVAL;
504	}
505}
506
507MODULE_DEPEND(svr4elf, sysvmsg, 1, 1, 1);
508#endif
509
510#ifdef SYSVSHM
511
512static void
513bsd_to_svr4_shmid_ds(bds, sds)
514	const struct shmid_ds *bds;
515	struct svr4_shmid_ds *sds;
516{
517	bzero(sds, sizeof(*sds));
518	bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
519	sds->shm_segsz = bds->shm_segsz;
520	sds->shm_lkcnt = 0;
521	sds->shm_lpid = bds->shm_lpid;
522	sds->shm_cpid = bds->shm_cpid;
523	sds->shm_amp = 0;
524	sds->shm_nattch = bds->shm_nattch;
525	sds->shm_cnattch = 0;
526	sds->shm_atime = bds->shm_atime;
527	sds->shm_dtime = bds->shm_dtime;
528	sds->shm_ctime = bds->shm_ctime;
529}
530
531static void
532svr4_to_bsd_shmid_ds(sds, bds)
533	const struct svr4_shmid_ds *sds;
534	struct shmid_ds *bds;
535{
536	svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
537	bds->shm_segsz = sds->shm_segsz;
538	bds->shm_lpid = sds->shm_lpid;
539	bds->shm_cpid = sds->shm_cpid;
540	bds->shm_nattch = sds->shm_nattch;
541	bds->shm_atime = sds->shm_atime;
542	bds->shm_dtime = sds->shm_dtime;
543	bds->shm_ctime = sds->shm_ctime;
544}
545
546struct svr4_sys_shmat_args {
547	int what;
548	int shmid;
549	void * shmaddr;
550	int shmflg;
551};
552
553static int
554svr4_shmat(td, v)
555	struct thread *td;
556	void *v;
557{
558	struct svr4_sys_shmat_args *uap = v;
559	struct shmat_args ap;
560
561	ap.shmid = uap->shmid;
562	ap.shmaddr = uap->shmaddr;
563	ap.shmflg = uap->shmflg;
564
565	return sys_shmat(td, &ap);
566}
567
568struct svr4_sys_shmdt_args {
569	int what;
570	void * shmaddr;
571};
572
573static int
574svr4_shmdt(td, v)
575	struct thread *td;
576	void *v;
577{
578	struct svr4_sys_shmdt_args *uap = v;
579	struct shmdt_args ap;
580
581	ap.shmaddr = uap->shmaddr;
582
583	return sys_shmdt(td, &ap);
584}
585
586struct svr4_sys_shmget_args {
587	int what;
588	key_t key;
589	int size;
590	int shmflg;
591};
592
593static int
594svr4_shmget(td, v)
595	struct thread *td;
596	void *v;
597{
598	struct svr4_sys_shmget_args *uap = v;
599	struct shmget_args ap;
600
601	ap.key = uap->key;
602	ap.size = uap->size;
603	ap.shmflg = uap->shmflg;
604
605	return sys_shmget(td, &ap);
606}
607
608struct svr4_sys_shmctl_args {
609	int what;
610	int shmid;
611	int cmd;
612	struct svr4_shmid_ds * buf;
613};
614
615int
616svr4_shmctl(td, v)
617	struct thread *td;
618	void *v;
619{
620	struct svr4_sys_shmctl_args *uap = v;
621	struct shmid_ds bs;
622	struct svr4_shmid_ds ss;
623	size_t bufsize;
624	int cmd, error;
625
626	if (uap->buf != NULL) {
627		switch (uap->cmd) {
628		case SVR4_IPC_SET:
629		case SVR4_SHM_LOCK:
630		case SVR4_SHM_UNLOCK:
631			error = copyin(uap->buf, &ss, sizeof(ss));
632			if (error)
633				return (error);
634			svr4_to_bsd_shmid_ds(&ss, &bs);
635			break;
636		default:
637			return (EINVAL);
638		}
639	}
640
641	switch (uap->cmd) {
642	case SVR4_IPC_STAT:
643		cmd = IPC_STAT;
644		break;
645	case SVR4_IPC_SET:
646		cmd = IPC_SET;
647		break;
648	case SVR4_IPC_RMID:
649		cmd = IPC_RMID;
650		break;
651	case SVR4_SHM_LOCK:
652		cmd = SHM_LOCK;
653		break;
654	case SVR4_SHM_UNLOCK:
655		cmd = SHM_UNLOCK;
656		break;
657	default:
658		return (EINVAL);
659	}
660
661	error = kern_shmctl(td, uap->shmid, cmd, &bs, &bufsize);
662	if (error)
663		return (error);
664
665	switch (uap->cmd) {
666	case SVR4_IPC_STAT:
667		if (uap->buf != NULL) {
668			bsd_to_svr4_shmid_ds(&bs, &ss);
669			error = copyout(&ss, uap->buf, sizeof(ss));
670		}
671		break;
672	}
673
674	return (error);
675}
676
677int
678svr4_sys_shmsys(td, uap)
679	struct thread *td;
680	struct svr4_sys_shmsys_args *uap;
681{
682
683	DPRINTF(("svr4_shmsys(%d)\n", uap->what));
684
685	switch (uap->what) {
686	case SVR4_shmat:
687		return svr4_shmat(td, uap);
688	case SVR4_shmdt:
689		return svr4_shmdt(td, uap);
690	case SVR4_shmget:
691		return svr4_shmget(td, uap);
692	case SVR4_shmctl:
693		return svr4_shmctl(td, uap);
694	default:
695		return ENOSYS;
696	}
697}
698
699MODULE_DEPEND(svr4elf, sysvshm, 1, 1, 1);
700#endif /* SYSVSHM */
701