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