xref: /netbsd-src/sys/compat/netbsd32/netbsd32_ipc.c (revision 001c68bd94f75ce9270b69227c4199fbf34ee396)
1 /*	$NetBSD: netbsd32_ipc.c,v 1.5 2003/01/18 08:28:26 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 2001 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_ipc.c,v 1.5 2003/01/18 08:28:26 thorpej Exp $");
33 
34 #if defined(_KERNEL_OPT)
35 #include "opt_sysv.h"
36 #endif
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/ipc.h>
41 #include <sys/msg.h>
42 #include <sys/sem.h>
43 #include <sys/shm.h>
44 #include <sys/mount.h>
45 
46 #include <sys/sa.h>
47 #include <sys/syscallargs.h>
48 #include <sys/proc.h>
49 
50 #include <compat/netbsd32/netbsd32.h>
51 #include <compat/netbsd32/netbsd32_syscallargs.h>
52 #include <compat/netbsd32/netbsd32_conv.h>
53 
54 #if defined(SYSVSEM)
55 /*
56  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
57  *
58  * This is BSD.  We won't support System V IPC.
59  * Too much work.
60  *
61  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
62  */
63 int
64 netbsd32___semctl14(l, v, retval)
65 	struct lwp *l;
66 	void *v;
67 	register_t *retval;
68 {
69 #if 0
70 	struct netbsd32___semctl_args /* {
71 		syscallarg(int) semid;
72 		syscallarg(int) semnum;
73 		syscallarg(int) cmd;
74 		syscallarg(netbsd32_semunu_t *) arg;
75 	} */ *uap = v;
76 	union netbsd32_semun sem32;
77 	int semid = SCARG(uap, semid);
78 	int semnum = SCARG(uap, semnum);
79 	int cmd = SCARG(uap, cmd);
80 	union netbsd32_semun *arg = (void*)NETBSD32PTR64(SCARG(uap, arg));
81 	union netbsd32_semun real_arg;
82 	struct ucred *cred = p->p_ucred;
83 	int i, rval, eval;
84 	struct netbsd32_semid_ds sbuf;
85 	struct semid_ds *semaptr;
86 
87 	semlock(p);
88 
89 	semid = IPCID_TO_IX(semid);
90 	if (semid < 0 || semid >= seminfo.semmsl)
91 		return(EINVAL);
92 
93 	semaptr = &sema[semid];
94 	if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
95 	    semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
96 		return(EINVAL);
97 
98 	eval = 0;
99 	rval = 0;
100 
101 	switch (cmd) {
102 	case IPC_RMID:
103 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
104 			return(eval);
105 		semaptr->sem_perm.cuid = cred->cr_uid;
106 		semaptr->sem_perm.uid = cred->cr_uid;
107 		semtot -= semaptr->sem_nsems;
108 		for (i = semaptr->_sem_base - sem; i < semtot; i++)
109 			sem[i] = sem[i + semaptr->sem_nsems];
110 		for (i = 0; i < seminfo.semmni; i++) {
111 			if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
112 			    sema[i]._sem_base > semaptr->_sem_base)
113 				sema[i]._sem_base -= semaptr->sem_nsems;
114 		}
115 		semaptr->sem_perm.mode = 0;
116 		semundo_clear(semid, -1);
117 		wakeup((caddr_t)semaptr);
118 		break;
119 
120 	case IPC_SET:
121 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
122 			return(eval);
123 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
124 			return(eval);
125 		if ((eval = copyin((caddr_t)NETBSD32PTR64(real_arg.buf),
126 		    (caddr_t)&sbuf, sizeof(sbuf))) != 0)
127 			return(eval);
128 		semaptr->sem_perm.uid = sbuf.sem_perm.uid;
129 		semaptr->sem_perm.gid = sbuf.sem_perm.gid;
130 		semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
131 		    (sbuf.sem_perm.mode & 0777);
132 		semaptr->sem_ctime = time.tv_sec;
133 		break;
134 
135 	case IPC_STAT:
136 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
137 			return(eval);
138 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
139 			return(eval);
140 		eval = copyout((caddr_t)semaptr,
141 		    (caddr_t)NETBSD32PTR64(real_arg.buf),
142 		    sizeof(struct semid_ds));
143 		break;
144 
145 	case GETNCNT:
146 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
147 			return(eval);
148 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
149 			return(EINVAL);
150 		rval = semaptr->_sem_base[semnum].semncnt;
151 		break;
152 
153 	case GETPID:
154 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
155 			return(eval);
156 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
157 			return(EINVAL);
158 		rval = semaptr->_sem_base[semnum].sempid;
159 		break;
160 
161 	case GETVAL:
162 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
163 			return(eval);
164 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
165 			return(EINVAL);
166 		rval = semaptr->_sem_base[semnum].semval;
167 		break;
168 
169 	case GETALL:
170 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
171 			return(eval);
172 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
173 			return(eval);
174 		for (i = 0; i < semaptr->sem_nsems; i++) {
175 			eval = copyout((caddr_t)&semaptr->_sem_base[i].semval,
176 			    &real_arg.array[i], sizeof(real_arg.array[0]));
177 			if (eval != 0)
178 				break;
179 		}
180 		break;
181 
182 	case GETZCNT:
183 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
184 			return(eval);
185 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
186 			return(EINVAL);
187 		rval = semaptr->_sem_base[semnum].semzcnt;
188 		break;
189 
190 	case SETVAL:
191 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
192 			return(eval);
193 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
194 			return(EINVAL);
195 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
196 			return(eval);
197 		semaptr->_sem_base[semnum].semval = real_arg.val;
198 		semundo_clear(semid, semnum);
199 		wakeup((caddr_t)semaptr);
200 		break;
201 
202 	case SETALL:
203 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
204 			return(eval);
205 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
206 			return(eval);
207 		for (i = 0; i < semaptr->sem_nsems; i++) {
208 			eval = copyin(&real_arg.array[i],
209 			    (caddr_t)&semaptr->_sem_base[i].semval,
210 			    sizeof(real_arg.array[0]));
211 			if (eval != 0)
212 				break;
213 		}
214 		semundo_clear(semid, -1);
215 		wakeup((caddr_t)semaptr);
216 		break;
217 
218 	default:
219 		return(EINVAL);
220 	}
221 
222 	if (eval == 0)
223 		*retval = rval;
224 	return(eval);
225 #else
226 	return (ENOSYS);
227 #endif
228 }
229 
230 int
231 netbsd32_semget(l, v, retval)
232 	struct lwp *l;
233 	void *v;
234 	register_t *retval;
235 {
236 	struct netbsd32_semget_args /* {
237 		syscallarg(netbsd32_key_t) key;
238 		syscallarg(int) nsems;
239 		syscallarg(int) semflg;
240 	} */ *uap = v;
241 	struct sys_semget_args ua;
242 
243 	NETBSD32TOX_UAP(key, key_t);
244 	NETBSD32TO64_UAP(nsems);
245 	NETBSD32TO64_UAP(semflg);
246 	return (sys_semget(l, &ua, retval));
247 }
248 
249 int
250 netbsd32_semop(l, v, retval)
251 	struct lwp *l;
252 	void *v;
253 	register_t *retval;
254 {
255 	struct netbsd32_semop_args /* {
256 		syscallarg(int) semid;
257 		syscallarg(netbsd32_sembufp_t) sops;
258 		syscallarg(netbsd32_size_t) nsops;
259 	} */ *uap = v;
260 	struct sys_semop_args ua;
261 
262 	NETBSD32TO64_UAP(semid);
263 	NETBSD32TOP_UAP(sops, struct sembuf);
264 	NETBSD32TOX_UAP(nsops, size_t);
265 	return (sys_semop(l, &ua, retval));
266 }
267 
268 int
269 netbsd32_semconfig(l, v, retval)
270 	struct lwp *l;
271 	void *v;
272 	register_t *retval;
273 {
274 	struct netbsd32_semconfig_args /* {
275 		syscallarg(int) flag;
276 	} */ *uap = v;
277 	struct sys_semconfig_args ua;
278 
279 	NETBSD32TO64_UAP(flag);
280 	return (sys_semconfig(l, &ua, retval));
281 }
282 #endif /* SYSVSEM */
283 
284 #if defined(SYSVMSG)
285 
286 int
287 netbsd32___msgctl13(l, v, retval)
288 	struct lwp *l;
289 	void *v;
290 	register_t *retval;
291 {
292 #if 0
293 	struct netbsd32_msgctl_args /* {
294 		syscallarg(int) msqid;
295 		syscallarg(int) cmd;
296 		syscallarg(netbsd32_msqid_dsp_t) buf;
297 	} */ *uap = v;
298 	struct sys_msgctl_args ua;
299 	struct msqid_ds ds;
300 	struct netbsd32_msqid_ds *ds32p;
301 	int error;
302 
303 	NETBSD32TO64_UAP(msqid);
304 	NETBSD32TO64_UAP(cmd);
305 	ds32p = (struct netbsd32_msqid_ds *)NETBSD32PTR64(SCARG(uap, buf));
306 	if (ds32p) {
307 		SCARG(&ua, buf) = NULL;
308 		netbsd32_to_msqid_ds(ds32p, &ds);
309 	} else
310 		SCARG(&ua, buf) = NULL;
311 	error = sys_msgctl(p, &ua, retval);
312 	if (error)
313 		return (error);
314 
315 	if (ds32p)
316 		netbsd32_from_msqid_ds(&ds, ds32p);
317 	return (0);
318 #else
319 	return (ENOSYS);
320 #endif
321 }
322 
323 int
324 netbsd32_msgget(l, v, retval)
325 	struct lwp *l;
326 	void *v;
327 	register_t *retval;
328 {
329 #if 0
330 	struct netbsd32_msgget_args /* {
331 		syscallarg(netbsd32_key_t) key;
332 		syscallarg(int) msgflg;
333 	} */ *uap = v;
334 	struct sys_msgget_args ua;
335 
336 	NETBSD32TOX_UAP(key, key_t);
337 	NETBSD32TO64_UAP(msgflg);
338 	return (sys_msgget(l, &ua, retval));
339 #else
340 	return (ENOSYS);
341 #endif
342 }
343 
344 int
345 netbsd32_msgsnd(l, v, retval)
346 	struct lwp *l;
347 	void *v;
348 	register_t *retval;
349 {
350 #if 0
351 	struct netbsd32_msgsnd_args /* {
352 		syscallarg(int) msqid;
353 		syscallarg(const netbsd32_voidp) msgp;
354 		syscallarg(netbsd32_size_t) msgsz;
355 		syscallarg(int) msgflg;
356 	} */ *uap = v;
357 	struct sys_msgsnd_args ua;
358 
359 	NETBSD32TO64_UAP(msqid);
360 	NETBSD32TOP_UAP(msgp, void);
361 	NETBSD32TOX_UAP(msgsz, size_t);
362 	NETBSD32TO64_UAP(msgflg);
363 	return (sys_msgsnd(l, &ua, retval));
364 #else
365 	return (ENOSYS);
366 #endif
367 }
368 
369 int
370 netbsd32_msgrcv(l, v, retval)
371 	struct lwp *l;
372 	void *v;
373 	register_t *retval;
374 {
375 #if 0
376 	struct netbsd32_msgrcv_args /* {
377 		syscallarg(int) msqid;
378 		syscallarg(netbsd32_voidp) msgp;
379 		syscallarg(netbsd32_size_t) msgsz;
380 		syscallarg(netbsd32_long) msgtyp;
381 		syscallarg(int) msgflg;
382 	} */ *uap = v;
383 	struct sys_msgrcv_args ua;
384 	ssize_t rt;
385 	int error;
386 
387 	NETBSD32TO64_UAP(msqid);
388 	NETBSD32TOP_UAP(msgp, void);
389 	NETBSD32TOX_UAP(msgsz, size_t);
390 	NETBSD32TOX_UAP(msgtyp, long);
391 	NETBSD32TO64_UAP(msgflg);
392 	error = sys_msgrcv(l, &ua, (register_t *)&rt);
393 	*retval = rt;
394 	return (error);
395 #else
396 	return (ENOSYS);
397 #endif
398 }
399 #endif /* SYSVMSG */
400 
401 #if defined(SYSVSHM)
402 
403 int
404 netbsd32_shmat(l, v, retval)
405 	struct lwp *l;
406 	void *v;
407 	register_t *retval;
408 {
409 #if 0
410 	struct netbsd32_shmat_args /* {
411 		syscallarg(int) shmid;
412 		syscallarg(const netbsd32_voidp) shmaddr;
413 		syscallarg(int) shmflg;
414 	} */ *uap = v;
415 	struct sys_shmat_args ua;
416 	void *rt;
417 	int error;
418 
419 	NETBSD32TO64_UAP(shmid);
420 	NETBSD32TOP_UAP(shmaddr, void);
421 	NETBSD32TO64_UAP(shmflg);
422 	error = sys_shmat(l, &ua, (register_t *)&rt);
423 	*retval = rt;
424 	return (error);
425 #else
426 	return (ENOSYS);
427 #endif
428 }
429 
430 int
431 netbsd32___shmctl13(l, v, retval)
432 	struct lwp *l;
433 	void *v;
434 	register_t *retval;
435 {
436 #if 0
437 	struct netbsd32_shmctl_args /* {
438 		syscallarg(int) shmid;
439 		syscallarg(int) cmd;
440 		syscallarg(netbsd32_shmid_dsp_t) buf;
441 	} */ *uap = v;
442 	struct sys_shmctl_args ua;
443 	struct shmid_ds ds;
444 	struct netbsd32_shmid_ds *ds32p;
445 	int error;
446 
447 	NETBSD32TO64_UAP(shmid);
448 	NETBSD32TO64_UAP(cmd);
449 	ds32p = (struct netbsd32_shmid_ds *)NETBSD32PTR64(SCARG(uap, buf));
450 	if (ds32p) {
451 		SCARG(&ua, buf) = NULL;
452 		netbsd32_to_shmid_ds(ds32p, &ds);
453 	} else
454 		SCARG(&ua, buf) = NULL;
455 	error = sys_shmctl(p, &ua, retval);
456 	if (error)
457 		return (error);
458 
459 	if (ds32p)
460 		netbsd32_from_shmid_ds(&ds, ds32p);
461 	return (0);
462 #else
463 	return (ENOSYS);
464 #endif
465 }
466 
467 int
468 netbsd32_shmdt(l, v, retval)
469 	struct lwp *l;
470 	void *v;
471 	register_t *retval;
472 {
473 #if 0
474 	struct netbsd32_shmdt_args /* {
475 		syscallarg(const netbsd32_voidp) shmaddr;
476 	} */ *uap = v;
477 	struct sys_shmdt_args ua;
478 
479 	NETBSD32TOP_UAP(shmaddr, const char);
480 	return (sys_shmdt(l, &ua, retval));
481 #else
482 	return (ENOSYS);
483 #endif
484 }
485 
486 int
487 netbsd32_shmget(l, v, retval)
488 	struct lwp *l;
489 	void *v;
490 	register_t *retval;
491 {
492 #if 0
493 	struct netbsd32_shmget_args /* {
494 		syscallarg(netbsd32_key_t) key;
495 		syscallarg(netbsd32_size_t) size;
496 		syscallarg(int) shmflg;
497 	} */ *uap = v;
498 	struct sys_shmget_args ua;
499 
500 	NETBSD32TOX_UAP(key, key_t)
501 	NETBSD32TOX_UAP(size, size_t)
502 	NETBSD32TO64_UAP(shmflg);
503 	return (sys_shmget(l, &ua, retval));
504 #else
505 	return (ENOSYS);
506 #endif
507 }
508 #endif /* SYSVSHM */
509