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