xref: /netbsd-src/sys/compat/netbsd32/netbsd32_ipc.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: netbsd32_ipc.c,v 1.7 2005/12/11 12:20:22 christos 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.7 2005/12/11 12:20:22 christos 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 #include <sys/dirent.h>
46 
47 #include <sys/sa.h>
48 #include <sys/syscallargs.h>
49 #include <sys/proc.h>
50 
51 #include <compat/netbsd32/netbsd32.h>
52 #include <compat/netbsd32/netbsd32_syscallargs.h>
53 #include <compat/netbsd32/netbsd32_conv.h>
54 
55 #if defined(SYSVSEM)
56 /*
57  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
58  *
59  * This is BSD.  We won't support System V IPC.
60  * Too much work.
61  *
62  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
63  */
64 int
65 netbsd32___semctl14(l, v, retval)
66 	struct lwp *l;
67 	void *v;
68 	register_t *retval;
69 {
70 #if 0
71 	struct netbsd32___semctl_args /* {
72 		syscallarg(int) semid;
73 		syscallarg(int) semnum;
74 		syscallarg(int) cmd;
75 		syscallarg(netbsd32_semunu_t *) arg;
76 	} */ *uap = v;
77 	union netbsd32_semun sem32;
78 	int semid = SCARG(uap, semid);
79 	int semnum = SCARG(uap, semnum);
80 	int cmd = SCARG(uap, cmd);
81 	union netbsd32_semun *arg = (void*)NETBSD32PTR64(SCARG(uap, arg));
82 	union netbsd32_semun real_arg;
83 	struct ucred *cred = p->p_ucred;
84 	int i, rval, eval;
85 	struct netbsd32_semid_ds sbuf;
86 	struct semid_ds *semaptr;
87 
88 	semlock(p);
89 
90 	semid = IPCID_TO_IX(semid);
91 	if (semid < 0 || semid >= seminfo.semmsl)
92 		return(EINVAL);
93 
94 	semaptr = &sema[semid];
95 	if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
96 	    semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
97 		return(EINVAL);
98 
99 	eval = 0;
100 	rval = 0;
101 
102 	switch (cmd) {
103 	case IPC_RMID:
104 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
105 			return(eval);
106 		semaptr->sem_perm.cuid = cred->cr_uid;
107 		semaptr->sem_perm.uid = cred->cr_uid;
108 		semtot -= semaptr->sem_nsems;
109 		for (i = semaptr->_sem_base - sem; i < semtot; i++)
110 			sem[i] = sem[i + semaptr->sem_nsems];
111 		for (i = 0; i < seminfo.semmni; i++) {
112 			if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
113 			    sema[i]._sem_base > semaptr->_sem_base)
114 				sema[i]._sem_base -= semaptr->sem_nsems;
115 		}
116 		semaptr->sem_perm.mode = 0;
117 		semundo_clear(semid, -1);
118 		wakeup((caddr_t)semaptr);
119 		break;
120 
121 	case IPC_SET:
122 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
123 			return(eval);
124 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
125 			return(eval);
126 		if ((eval = copyin((caddr_t)NETBSD32PTR64(real_arg.buf),
127 		    (caddr_t)&sbuf, sizeof(sbuf))) != 0)
128 			return(eval);
129 		semaptr->sem_perm.uid = sbuf.sem_perm.uid;
130 		semaptr->sem_perm.gid = sbuf.sem_perm.gid;
131 		semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
132 		    (sbuf.sem_perm.mode & 0777);
133 		semaptr->sem_ctime = time.tv_sec;
134 		break;
135 
136 	case IPC_STAT:
137 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
138 			return(eval);
139 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
140 			return(eval);
141 		eval = copyout((caddr_t)semaptr,
142 		    (caddr_t)NETBSD32PTR64(real_arg.buf),
143 		    sizeof(struct semid_ds));
144 		break;
145 
146 	case GETNCNT:
147 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
148 			return(eval);
149 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
150 			return(EINVAL);
151 		rval = semaptr->_sem_base[semnum].semncnt;
152 		break;
153 
154 	case GETPID:
155 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
156 			return(eval);
157 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
158 			return(EINVAL);
159 		rval = semaptr->_sem_base[semnum].sempid;
160 		break;
161 
162 	case GETVAL:
163 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
164 			return(eval);
165 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
166 			return(EINVAL);
167 		rval = semaptr->_sem_base[semnum].semval;
168 		break;
169 
170 	case GETALL:
171 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
172 			return(eval);
173 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
174 			return(eval);
175 		for (i = 0; i < semaptr->sem_nsems; i++) {
176 			eval = copyout((caddr_t)&semaptr->_sem_base[i].semval,
177 			    &real_arg.array[i], sizeof(real_arg.array[0]));
178 			if (eval != 0)
179 				break;
180 		}
181 		break;
182 
183 	case GETZCNT:
184 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
185 			return(eval);
186 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
187 			return(EINVAL);
188 		rval = semaptr->_sem_base[semnum].semzcnt;
189 		break;
190 
191 	case SETVAL:
192 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
193 			return(eval);
194 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
195 			return(EINVAL);
196 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
197 			return(eval);
198 		semaptr->_sem_base[semnum].semval = real_arg.val;
199 		semundo_clear(semid, semnum);
200 		wakeup((caddr_t)semaptr);
201 		break;
202 
203 	case SETALL:
204 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
205 			return(eval);
206 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
207 			return(eval);
208 		for (i = 0; i < semaptr->sem_nsems; i++) {
209 			eval = copyin(&real_arg.array[i],
210 			    (caddr_t)&semaptr->_sem_base[i].semval,
211 			    sizeof(real_arg.array[0]));
212 			if (eval != 0)
213 				break;
214 		}
215 		semundo_clear(semid, -1);
216 		wakeup((caddr_t)semaptr);
217 		break;
218 
219 	default:
220 		return(EINVAL);
221 	}
222 
223 	if (eval == 0)
224 		*retval = rval;
225 	return(eval);
226 #else
227 	return (ENOSYS);
228 #endif
229 }
230 
231 int
232 netbsd32_semget(l, v, retval)
233 	struct lwp *l;
234 	void *v;
235 	register_t *retval;
236 {
237 	struct netbsd32_semget_args /* {
238 		syscallarg(netbsd32_key_t) key;
239 		syscallarg(int) nsems;
240 		syscallarg(int) semflg;
241 	} */ *uap = v;
242 	struct sys_semget_args ua;
243 
244 	NETBSD32TOX_UAP(key, key_t);
245 	NETBSD32TO64_UAP(nsems);
246 	NETBSD32TO64_UAP(semflg);
247 	return (sys_semget(l, &ua, retval));
248 }
249 
250 int
251 netbsd32_semop(l, v, retval)
252 	struct lwp *l;
253 	void *v;
254 	register_t *retval;
255 {
256 	struct netbsd32_semop_args /* {
257 		syscallarg(int) semid;
258 		syscallarg(netbsd32_sembufp_t) sops;
259 		syscallarg(netbsd32_size_t) nsops;
260 	} */ *uap = v;
261 	struct sys_semop_args ua;
262 
263 	NETBSD32TO64_UAP(semid);
264 	NETBSD32TOP_UAP(sops, struct sembuf);
265 	NETBSD32TOX_UAP(nsops, size_t);
266 	return (sys_semop(l, &ua, retval));
267 }
268 
269 int
270 netbsd32_semconfig(l, v, retval)
271 	struct lwp *l;
272 	void *v;
273 	register_t *retval;
274 {
275 	struct netbsd32_semconfig_args /* {
276 		syscallarg(int) flag;
277 	} */ *uap = v;
278 	struct sys_semconfig_args ua;
279 
280 	NETBSD32TO64_UAP(flag);
281 	return (sys_semconfig(l, &ua, retval));
282 }
283 #endif /* SYSVSEM */
284 
285 #if defined(SYSVMSG)
286 
287 int
288 netbsd32___msgctl13(l, v, retval)
289 	struct lwp *l;
290 	void *v;
291 	register_t *retval;
292 {
293 #if 0
294 	struct netbsd32_msgctl_args /* {
295 		syscallarg(int) msqid;
296 		syscallarg(int) cmd;
297 		syscallarg(netbsd32_msqid_dsp_t) buf;
298 	} */ *uap = v;
299 	struct sys_msgctl_args ua;
300 	struct msqid_ds ds;
301 	struct netbsd32_msqid_ds *ds32p;
302 	int error;
303 
304 	NETBSD32TO64_UAP(msqid);
305 	NETBSD32TO64_UAP(cmd);
306 	ds32p = (struct netbsd32_msqid_ds *)NETBSD32PTR64(SCARG(uap, buf));
307 	if (ds32p) {
308 		SCARG(&ua, buf) = NULL;
309 		netbsd32_to_msqid_ds(ds32p, &ds);
310 	} else
311 		SCARG(&ua, buf) = NULL;
312 	error = sys_msgctl(p, &ua, retval);
313 	if (error)
314 		return (error);
315 
316 	if (ds32p)
317 		netbsd32_from_msqid_ds(&ds, ds32p);
318 	return (0);
319 #else
320 	return (ENOSYS);
321 #endif
322 }
323 
324 int
325 netbsd32_msgget(l, v, retval)
326 	struct lwp *l;
327 	void *v;
328 	register_t *retval;
329 {
330 #if 0
331 	struct netbsd32_msgget_args /* {
332 		syscallarg(netbsd32_key_t) key;
333 		syscallarg(int) msgflg;
334 	} */ *uap = v;
335 	struct sys_msgget_args ua;
336 
337 	NETBSD32TOX_UAP(key, key_t);
338 	NETBSD32TO64_UAP(msgflg);
339 	return (sys_msgget(l, &ua, retval));
340 #else
341 	return (ENOSYS);
342 #endif
343 }
344 
345 int
346 netbsd32_msgsnd(l, v, retval)
347 	struct lwp *l;
348 	void *v;
349 	register_t *retval;
350 {
351 #if 0
352 	struct netbsd32_msgsnd_args /* {
353 		syscallarg(int) msqid;
354 		syscallarg(const netbsd32_voidp) msgp;
355 		syscallarg(netbsd32_size_t) msgsz;
356 		syscallarg(int) msgflg;
357 	} */ *uap = v;
358 	struct sys_msgsnd_args ua;
359 
360 	NETBSD32TO64_UAP(msqid);
361 	NETBSD32TOP_UAP(msgp, void);
362 	NETBSD32TOX_UAP(msgsz, size_t);
363 	NETBSD32TO64_UAP(msgflg);
364 	return (sys_msgsnd(l, &ua, retval));
365 #else
366 	return (ENOSYS);
367 #endif
368 }
369 
370 int
371 netbsd32_msgrcv(l, v, retval)
372 	struct lwp *l;
373 	void *v;
374 	register_t *retval;
375 {
376 #if 0
377 	struct netbsd32_msgrcv_args /* {
378 		syscallarg(int) msqid;
379 		syscallarg(netbsd32_voidp) msgp;
380 		syscallarg(netbsd32_size_t) msgsz;
381 		syscallarg(netbsd32_long) msgtyp;
382 		syscallarg(int) msgflg;
383 	} */ *uap = v;
384 	struct sys_msgrcv_args ua;
385 	ssize_t rt;
386 	int error;
387 
388 	NETBSD32TO64_UAP(msqid);
389 	NETBSD32TOP_UAP(msgp, void);
390 	NETBSD32TOX_UAP(msgsz, size_t);
391 	NETBSD32TOX_UAP(msgtyp, long);
392 	NETBSD32TO64_UAP(msgflg);
393 	error = sys_msgrcv(l, &ua, (register_t *)&rt);
394 	*retval = rt;
395 	return (error);
396 #else
397 	return (ENOSYS);
398 #endif
399 }
400 #endif /* SYSVMSG */
401 
402 #if defined(SYSVSHM)
403 
404 int
405 netbsd32_shmat(l, v, retval)
406 	struct lwp *l;
407 	void *v;
408 	register_t *retval;
409 {
410 #if 0
411 	struct netbsd32_shmat_args /* {
412 		syscallarg(int) shmid;
413 		syscallarg(const netbsd32_voidp) shmaddr;
414 		syscallarg(int) shmflg;
415 	} */ *uap = v;
416 	struct sys_shmat_args ua;
417 	void *rt;
418 	int error;
419 
420 	NETBSD32TO64_UAP(shmid);
421 	NETBSD32TOP_UAP(shmaddr, void);
422 	NETBSD32TO64_UAP(shmflg);
423 	error = sys_shmat(l, &ua, (register_t *)&rt);
424 	*retval = rt;
425 	return (error);
426 #else
427 	return (ENOSYS);
428 #endif
429 }
430 
431 int
432 netbsd32___shmctl13(l, v, retval)
433 	struct lwp *l;
434 	void *v;
435 	register_t *retval;
436 {
437 #if 0
438 	struct netbsd32_shmctl_args /* {
439 		syscallarg(int) shmid;
440 		syscallarg(int) cmd;
441 		syscallarg(netbsd32_shmid_dsp_t) buf;
442 	} */ *uap = v;
443 	struct sys_shmctl_args ua;
444 	struct shmid_ds ds;
445 	struct netbsd32_shmid_ds *ds32p;
446 	int error;
447 
448 	NETBSD32TO64_UAP(shmid);
449 	NETBSD32TO64_UAP(cmd);
450 	ds32p = (struct netbsd32_shmid_ds *)NETBSD32PTR64(SCARG(uap, buf));
451 	if (ds32p) {
452 		SCARG(&ua, buf) = NULL;
453 		netbsd32_to_shmid_ds(ds32p, &ds);
454 	} else
455 		SCARG(&ua, buf) = NULL;
456 	error = sys_shmctl(p, &ua, retval);
457 	if (error)
458 		return (error);
459 
460 	if (ds32p)
461 		netbsd32_from_shmid_ds(&ds, ds32p);
462 	return (0);
463 #else
464 	return (ENOSYS);
465 #endif
466 }
467 
468 int
469 netbsd32_shmdt(l, v, retval)
470 	struct lwp *l;
471 	void *v;
472 	register_t *retval;
473 {
474 #if 0
475 	struct netbsd32_shmdt_args /* {
476 		syscallarg(const netbsd32_voidp) shmaddr;
477 	} */ *uap = v;
478 	struct sys_shmdt_args ua;
479 
480 	NETBSD32TOP_UAP(shmaddr, const char);
481 	return (sys_shmdt(l, &ua, retval));
482 #else
483 	return (ENOSYS);
484 #endif
485 }
486 
487 int
488 netbsd32_shmget(l, v, retval)
489 	struct lwp *l;
490 	void *v;
491 	register_t *retval;
492 {
493 #if 0
494 	struct netbsd32_shmget_args /* {
495 		syscallarg(netbsd32_key_t) key;
496 		syscallarg(netbsd32_size_t) size;
497 		syscallarg(int) shmflg;
498 	} */ *uap = v;
499 	struct sys_shmget_args ua;
500 
501 	NETBSD32TOX_UAP(key, key_t)
502 	NETBSD32TOX_UAP(size, size_t)
503 	NETBSD32TO64_UAP(shmflg);
504 	return (sys_shmget(l, &ua, retval));
505 #else
506 	return (ENOSYS);
507 #endif
508 }
509 #endif /* SYSVSHM */
510