xref: /netbsd/sys/compat/netbsd32/netbsd32_ipc.c (revision bf9ec67e)
1 /*	$NetBSD: netbsd32_ipc.c,v 1.3 2001/11/13 02:09:06 lukem 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.3 2001/11/13 02:09:06 lukem 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*)(u_long)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)(u_long)real_arg.buf, (caddr_t)&sbuf,
125 		    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, (caddr_t)(u_long)real_arg.buf,
140 		    sizeof(struct semid_ds));
141 		break;
142 
143 	case GETNCNT:
144 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
145 			return(eval);
146 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
147 			return(EINVAL);
148 		rval = semaptr->_sem_base[semnum].semncnt;
149 		break;
150 
151 	case GETPID:
152 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
153 			return(eval);
154 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
155 			return(EINVAL);
156 		rval = semaptr->_sem_base[semnum].sempid;
157 		break;
158 
159 	case GETVAL:
160 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
161 			return(eval);
162 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
163 			return(EINVAL);
164 		rval = semaptr->_sem_base[semnum].semval;
165 		break;
166 
167 	case GETALL:
168 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
169 			return(eval);
170 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
171 			return(eval);
172 		for (i = 0; i < semaptr->sem_nsems; i++) {
173 			eval = copyout((caddr_t)&semaptr->_sem_base[i].semval,
174 			    &real_arg.array[i], sizeof(real_arg.array[0]));
175 			if (eval != 0)
176 				break;
177 		}
178 		break;
179 
180 	case GETZCNT:
181 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
182 			return(eval);
183 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
184 			return(EINVAL);
185 		rval = semaptr->_sem_base[semnum].semzcnt;
186 		break;
187 
188 	case SETVAL:
189 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
190 			return(eval);
191 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
192 			return(EINVAL);
193 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
194 			return(eval);
195 		semaptr->_sem_base[semnum].semval = real_arg.val;
196 		semundo_clear(semid, semnum);
197 		wakeup((caddr_t)semaptr);
198 		break;
199 
200 	case SETALL:
201 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
202 			return(eval);
203 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
204 			return(eval);
205 		for (i = 0; i < semaptr->sem_nsems; i++) {
206 			eval = copyin(&real_arg.array[i],
207 			    (caddr_t)&semaptr->_sem_base[i].semval,
208 			    sizeof(real_arg.array[0]));
209 			if (eval != 0)
210 				break;
211 		}
212 		semundo_clear(semid, -1);
213 		wakeup((caddr_t)semaptr);
214 		break;
215 
216 	default:
217 		return(EINVAL);
218 	}
219 
220 	if (eval == 0)
221 		*retval = rval;
222 	return(eval);
223 #else
224 	return (ENOSYS);
225 #endif
226 }
227 
228 int
229 netbsd32_semget(p, v, retval)
230 	struct proc *p;
231 	void *v;
232 	register_t *retval;
233 {
234 	struct netbsd32_semget_args /* {
235 		syscallarg(netbsd32_key_t) key;
236 		syscallarg(int) nsems;
237 		syscallarg(int) semflg;
238 	} */ *uap = v;
239 	struct sys_semget_args ua;
240 
241 	NETBSD32TOX_UAP(key, key_t);
242 	NETBSD32TO64_UAP(nsems);
243 	NETBSD32TO64_UAP(semflg);
244 	return (sys_semget(p, &ua, retval));
245 }
246 
247 int
248 netbsd32_semop(p, v, retval)
249 	struct proc *p;
250 	void *v;
251 	register_t *retval;
252 {
253 	struct netbsd32_semop_args /* {
254 		syscallarg(int) semid;
255 		syscallarg(netbsd32_sembufp_t) sops;
256 		syscallarg(netbsd32_size_t) nsops;
257 	} */ *uap = v;
258 	struct sys_semop_args ua;
259 
260 	NETBSD32TO64_UAP(semid);
261 	NETBSD32TOP_UAP(sops, struct sembuf);
262 	NETBSD32TOX_UAP(nsops, size_t);
263 	return (sys_semop(p, &ua, retval));
264 }
265 
266 int
267 netbsd32_semconfig(p, v, retval)
268 	struct proc *p;
269 	void *v;
270 	register_t *retval;
271 {
272 	struct netbsd32_semconfig_args /* {
273 		syscallarg(int) flag;
274 	} */ *uap = v;
275 	struct sys_semconfig_args ua;
276 
277 	NETBSD32TO64_UAP(flag);
278 	return (sys_semconfig(p, &ua, retval));
279 }
280 #endif /* SYSVSEM */
281 
282 #if defined(SYSVMSG)
283 
284 int
285 netbsd32___msgctl13(p, v, retval)
286 	struct proc *p;
287 	void *v;
288 	register_t *retval;
289 {
290 #if 0
291 	struct netbsd32_msgctl_args /* {
292 		syscallarg(int) msqid;
293 		syscallarg(int) cmd;
294 		syscallarg(netbsd32_msqid_dsp_t) buf;
295 	} */ *uap = v;
296 	struct sys_msgctl_args ua;
297 	struct msqid_ds ds;
298 	struct netbsd32_msqid_ds *ds32p;
299 	int error;
300 
301 	NETBSD32TO64_UAP(msqid);
302 	NETBSD32TO64_UAP(cmd);
303 	ds32p = (struct netbsd32_msqid_ds *)(u_long)SCARG(uap, buf);
304 	if (ds32p) {
305 		SCARG(&ua, buf) = NULL;
306 		netbsd32_to_msqid_ds(ds32p, &ds);
307 	} else
308 		SCARG(&ua, buf) = NULL;
309 	error = sys_msgctl(p, &ua, retval);
310 	if (error)
311 		return (error);
312 
313 	if (ds32p)
314 		netbsd32_from_msqid_ds(&ds, ds32p);
315 	return (0);
316 #else
317 	return (ENOSYS);
318 #endif
319 }
320 
321 int
322 netbsd32_msgget(p, v, retval)
323 	struct proc *p;
324 	void *v;
325 	register_t *retval;
326 {
327 #if 0
328 	struct netbsd32_msgget_args /* {
329 		syscallarg(netbsd32_key_t) key;
330 		syscallarg(int) msgflg;
331 	} */ *uap = v;
332 	struct sys_msgget_args ua;
333 
334 	NETBSD32TOX_UAP(key, key_t);
335 	NETBSD32TO64_UAP(msgflg);
336 	return (sys_msgget(p, &ua, retval));
337 #else
338 	return (ENOSYS);
339 #endif
340 }
341 
342 int
343 netbsd32_msgsnd(p, v, retval)
344 	struct proc *p;
345 	void *v;
346 	register_t *retval;
347 {
348 #if 0
349 	struct netbsd32_msgsnd_args /* {
350 		syscallarg(int) msqid;
351 		syscallarg(const netbsd32_voidp) msgp;
352 		syscallarg(netbsd32_size_t) msgsz;
353 		syscallarg(int) msgflg;
354 	} */ *uap = v;
355 	struct sys_msgsnd_args ua;
356 
357 	NETBSD32TO64_UAP(msqid);
358 	NETBSD32TOP_UAP(msgp, void);
359 	NETBSD32TOX_UAP(msgsz, size_t);
360 	NETBSD32TO64_UAP(msgflg);
361 	return (sys_msgsnd(p, &ua, retval));
362 #else
363 	return (ENOSYS);
364 #endif
365 }
366 
367 int
368 netbsd32_msgrcv(p, v, retval)
369 	struct proc *p;
370 	void *v;
371 	register_t *retval;
372 {
373 #if 0
374 	struct netbsd32_msgrcv_args /* {
375 		syscallarg(int) msqid;
376 		syscallarg(netbsd32_voidp) msgp;
377 		syscallarg(netbsd32_size_t) msgsz;
378 		syscallarg(netbsd32_long) msgtyp;
379 		syscallarg(int) msgflg;
380 	} */ *uap = v;
381 	struct sys_msgrcv_args ua;
382 	ssize_t rt;
383 	int error;
384 
385 	NETBSD32TO64_UAP(msqid);
386 	NETBSD32TOP_UAP(msgp, void);
387 	NETBSD32TOX_UAP(msgsz, size_t);
388 	NETBSD32TOX_UAP(msgtyp, long);
389 	NETBSD32TO64_UAP(msgflg);
390 	error = sys_msgrcv(p, &ua, (register_t *)&rt);
391 	*retval = rt;
392 	return (error);
393 #else
394 	return (ENOSYS);
395 #endif
396 }
397 #endif /* SYSVMSG */
398 
399 #if defined(SYSVSHM)
400 
401 int
402 netbsd32_shmat(p, v, retval)
403 	struct proc *p;
404 	void *v;
405 	register_t *retval;
406 {
407 #if 0
408 	struct netbsd32_shmat_args /* {
409 		syscallarg(int) shmid;
410 		syscallarg(const netbsd32_voidp) shmaddr;
411 		syscallarg(int) shmflg;
412 	} */ *uap = v;
413 	struct sys_shmat_args ua;
414 	void *rt;
415 	int error;
416 
417 	NETBSD32TO64_UAP(shmid);
418 	NETBSD32TOP_UAP(shmaddr, void);
419 	NETBSD32TO64_UAP(shmflg);
420 	error = sys_shmat(p, &ua, (register_t *)&rt);
421 	*retval = rt;
422 	return (error);
423 #else
424 	return (ENOSYS);
425 #endif
426 }
427 
428 int
429 netbsd32___shmctl13(p, v, retval)
430 	struct proc *p;
431 	void *v;
432 	register_t *retval;
433 {
434 #if 0
435 	struct netbsd32_shmctl_args /* {
436 		syscallarg(int) shmid;
437 		syscallarg(int) cmd;
438 		syscallarg(netbsd32_shmid_dsp_t) buf;
439 	} */ *uap = v;
440 	struct sys_shmctl_args ua;
441 	struct shmid_ds ds;
442 	struct netbsd32_shmid_ds *ds32p;
443 	int error;
444 
445 	NETBSD32TO64_UAP(shmid);
446 	NETBSD32TO64_UAP(cmd);
447 	ds32p = (struct netbsd32_shmid_ds *)(u_long)SCARG(uap, buf);
448 	if (ds32p) {
449 		SCARG(&ua, buf) = NULL;
450 		netbsd32_to_shmid_ds(ds32p, &ds);
451 	} else
452 		SCARG(&ua, buf) = NULL;
453 	error = sys_shmctl(p, &ua, retval);
454 	if (error)
455 		return (error);
456 
457 	if (ds32p)
458 		netbsd32_from_shmid_ds(&ds, ds32p);
459 	return (0);
460 #else
461 	return (ENOSYS);
462 #endif
463 }
464 
465 int
466 netbsd32_shmdt(p, v, retval)
467 	struct proc *p;
468 	void *v;
469 	register_t *retval;
470 {
471 #if 0
472 	struct netbsd32_shmdt_args /* {
473 		syscallarg(const netbsd32_voidp) shmaddr;
474 	} */ *uap = v;
475 	struct sys_shmdt_args ua;
476 
477 	NETBSD32TOP_UAP(shmaddr, const char);
478 	return (sys_shmdt(p, &ua, retval));
479 #else
480 	return (ENOSYS);
481 #endif
482 }
483 
484 int
485 netbsd32_shmget(p, v, retval)
486 	struct proc *p;
487 	void *v;
488 	register_t *retval;
489 {
490 #if 0
491 	struct netbsd32_shmget_args /* {
492 		syscallarg(netbsd32_key_t) key;
493 		syscallarg(netbsd32_size_t) size;
494 		syscallarg(int) shmflg;
495 	} */ *uap = v;
496 	struct sys_shmget_args ua;
497 
498 	NETBSD32TOX_UAP(key, key_t)
499 	NETBSD32TOX_UAP(size, size_t)
500 	NETBSD32TO64_UAP(shmflg);
501 	return (sys_shmget(p, &ua, retval));
502 #else
503 	return (ENOSYS);
504 #endif
505 }
506 #endif /* SYSVSHM */
507