ibcs2_ipc.c revision 148541
1/*-
2 * Copyright (c) 1995 Scott Bartram
3 * Copyright (c) 1995 Steven Wallace
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. The name of the author may not be used to endorse or promote products
12 *    derived from this software without specific prior written permission
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_ipc.c 148541 2005-07-29 19:41:04Z jhb $");
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/msg.h>
32#include <sys/sem.h>
33#include <sys/shm.h>
34#include <sys/sysproto.h>
35
36#include <i386/ibcs2/ibcs2_types.h>
37#include <i386/ibcs2/ibcs2_signal.h>
38#include <i386/ibcs2/ibcs2_proto.h>
39#include <i386/ibcs2/ibcs2_util.h>
40#include <i386/ibcs2/ibcs2_ipc.h>
41
42#define IBCS2_IPC_RMID	0
43#define IBCS2_IPC_SET	1
44#define IBCS2_IPC_STAT	2
45#define IBCS2_SETVAL	8
46
47
48
49static void cvt_msqid2imsqid(struct msqid_ds *, struct ibcs2_msqid_ds *);
50static void cvt_imsqid2msqid(struct ibcs2_msqid_ds *, struct msqid_ds *);
51#ifdef unused
52static void cvt_sem2isem(struct sem *, struct ibcs2_sem *);
53static void cvt_isem2sem(struct ibcs2_sem *, struct sem *);
54#endif
55static void cvt_semid2isemid(struct semid_ds *, struct ibcs2_semid_ds *);
56static void cvt_isemid2semid(struct ibcs2_semid_ds *, struct semid_ds *);
57static void cvt_shmid2ishmid(struct shmid_ds *, struct ibcs2_shmid_ds *);
58static void cvt_ishmid2shmid(struct ibcs2_shmid_ds *, struct shmid_ds *);
59static void cvt_perm2iperm(struct ipc_perm *, struct ibcs2_ipc_perm *);
60static void cvt_iperm2perm(struct ibcs2_ipc_perm *, struct ipc_perm *);
61
62
63/*
64 * iBCS2 msgsys call
65 */
66
67static void
68cvt_msqid2imsqid(bp, ibp)
69struct msqid_ds *bp;
70struct ibcs2_msqid_ds *ibp;
71{
72	cvt_perm2iperm(&bp->msg_perm, &ibp->msg_perm);
73	ibp->msg_first = bp->msg_first;
74	ibp->msg_last = bp->msg_last;
75	ibp->msg_cbytes = (u_short)bp->msg_cbytes;
76	ibp->msg_qnum = (u_short)bp->msg_qnum;
77	ibp->msg_qbytes = (u_short)bp->msg_qbytes;
78	ibp->msg_lspid = (u_short)bp->msg_lspid;
79	ibp->msg_lrpid = (u_short)bp->msg_lrpid;
80	ibp->msg_stime = bp->msg_stime;
81	ibp->msg_rtime = bp->msg_rtime;
82	ibp->msg_ctime = bp->msg_ctime;
83	return;
84}
85
86static void
87cvt_imsqid2msqid(ibp, bp)
88struct ibcs2_msqid_ds *ibp;
89struct msqid_ds *bp;
90{
91	cvt_iperm2perm(&ibp->msg_perm, &bp->msg_perm);
92	bp->msg_first = ibp->msg_first;
93	bp->msg_last = ibp->msg_last;
94	bp->msg_cbytes = ibp->msg_cbytes;
95	bp->msg_qnum = ibp->msg_qnum;
96	bp->msg_qbytes = ibp->msg_qbytes;
97	bp->msg_lspid = ibp->msg_lspid;
98	bp->msg_lrpid = ibp->msg_lrpid;
99	bp->msg_stime = ibp->msg_stime;
100	bp->msg_rtime = ibp->msg_rtime;
101	bp->msg_ctime = ibp->msg_ctime;
102	return;
103}
104
105int
106ibcs2_msgsys(td, uap)
107	struct thread *td;
108	struct ibcs2_msgsys_args *uap;
109{
110	switch (uap->which) {
111	case 0:				/* msgget */
112		uap->which = 1;
113		return msgsys(td, (struct msgsys_args *)uap);
114	case 1: {			/* msgctl */
115		int error;
116		struct msgsys_args margs;
117		caddr_t sg = stackgap_init();
118
119		margs.which = 0;
120		margs.a2 = uap->a2;
121		margs.a4 =
122		    (int)stackgap_alloc(&sg, sizeof(struct msqid_ds));
123		margs.a3 = uap->a3;
124		switch (margs.a3) {
125		case IBCS2_IPC_STAT:
126			error = msgsys(td, &margs);
127			if (!error)
128				cvt_msqid2imsqid(
129				    (struct msqid_ds *)margs.a4,
130				    (struct ibcs2_msqid_ds *)uap->a4);
131			return error;
132		case IBCS2_IPC_SET:
133			cvt_imsqid2msqid((struct ibcs2_msqid_ds *)uap->a4,
134					 (struct msqid_ds *)margs.a4);
135			return msgsys(td, &margs);
136		case IBCS2_IPC_RMID:
137			return msgsys(td, &margs);
138		}
139		return EINVAL;
140	}
141	case 2:				/* msgrcv */
142		uap->which = 3;
143		return msgsys(td, (struct msgsys_args *)uap);
144	case 3:				/* msgsnd */
145		uap->which = 2;
146		return msgsys(td, (struct msgsys_args *)uap);
147	default:
148		return EINVAL;
149	}
150}
151
152/*
153 * iBCS2 semsys call
154 */
155#ifdef unused
156static void
157cvt_sem2isem(bp, ibp)
158struct sem *bp;
159struct ibcs2_sem *ibp;
160{
161	ibp->semval = bp->semval;
162	ibp->sempid = bp->sempid;
163	ibp->semncnt = bp->semncnt;
164	ibp->semzcnt = bp->semzcnt;
165	return;
166}
167
168static void
169cvt_isem2sem(ibp, bp)
170struct ibcs2_sem *ibp;
171struct sem *bp;
172{
173	bp->semval = ibp->semval;
174	bp->sempid = ibp->sempid;
175	bp->semncnt = ibp->semncnt;
176	bp->semzcnt = ibp->semzcnt;
177	return;
178}
179#endif
180
181static void
182cvt_iperm2perm(ipp, pp)
183struct ibcs2_ipc_perm *ipp;
184struct ipc_perm *pp;
185{
186	pp->uid = ipp->uid;
187	pp->gid = ipp->gid;
188	pp->cuid = ipp->cuid;
189	pp->cgid = ipp->cgid;
190	pp->mode = ipp->mode;
191	pp->seq = ipp->seq;
192	pp->key = ipp->key;
193}
194
195static void
196cvt_perm2iperm(pp, ipp)
197struct ipc_perm *pp;
198struct ibcs2_ipc_perm *ipp;
199{
200	ipp->uid = pp->uid;
201	ipp->gid = pp->gid;
202	ipp->cuid = pp->cuid;
203	ipp->cgid = pp->cgid;
204	ipp->mode = pp->mode;
205	ipp->seq = pp->seq;
206	ipp->key = pp->key;
207}
208
209static void
210cvt_semid2isemid(bp, ibp)
211struct semid_ds *bp;
212struct ibcs2_semid_ds *ibp;
213{
214	cvt_perm2iperm(&bp->sem_perm, &ibp->sem_perm);
215	ibp->sem_base = (struct ibcs2_sem *)bp->sem_base;
216	ibp->sem_nsems = bp->sem_nsems;
217	ibp->sem_otime = bp->sem_otime;
218	ibp->sem_ctime = bp->sem_ctime;
219	return;
220}
221
222static void
223cvt_isemid2semid(ibp, bp)
224struct ibcs2_semid_ds *ibp;
225struct semid_ds *bp;
226{
227	cvt_iperm2perm(&ibp->sem_perm, &bp->sem_perm);
228	bp->sem_base = (struct sem *)ibp->sem_base;
229	bp->sem_nsems = ibp->sem_nsems;
230	bp->sem_otime = ibp->sem_otime;
231	bp->sem_ctime = ibp->sem_ctime;
232	return;
233}
234
235int
236ibcs2_semsys(td, uap)
237	struct thread *td;
238	struct ibcs2_semsys_args *uap;
239{
240	int error;
241
242	switch (uap->which) {
243	case 0:					/* semctl */
244		switch(uap->a4) {
245		case IBCS2_IPC_STAT:
246		    {
247			struct ibcs2_semid_ds *isp;
248			struct semid_ds *sp;
249			union semun *sup, ssu;
250			caddr_t sg = stackgap_init();
251
252
253			ssu = (union semun) uap->a5;
254			sp = stackgap_alloc(&sg, sizeof(struct semid_ds));
255			sup = stackgap_alloc(&sg, sizeof(union semun));
256			sup->buf = sp;
257			uap->a5 = (int)sup;
258			error = semsys(td, (struct semsys_args *)uap);
259			if (!error) {
260				uap->a5 = (int)ssu.buf;
261				isp = stackgap_alloc(&sg, sizeof(*isp));
262				cvt_semid2isemid(sp, isp);
263				error = copyout((caddr_t)isp,
264						(caddr_t)ssu.buf,
265						sizeof(*isp));
266			}
267			return error;
268		    }
269		case IBCS2_IPC_SET:
270		    {
271			struct ibcs2_semid_ds *isp;
272			struct semid_ds *sp;
273			caddr_t sg = stackgap_init();
274
275			isp = stackgap_alloc(&sg, sizeof(*isp));
276			sp = stackgap_alloc(&sg, sizeof(*sp));
277			error = copyin((caddr_t)uap->a5, (caddr_t)isp,
278				       sizeof(*isp));
279			if (error)
280				return error;
281			cvt_isemid2semid(isp, sp);
282			uap->a5 = (int)sp;
283			return semsys(td, (struct semsys_args *)uap);
284		    }
285		case IBCS2_SETVAL:
286		    {
287			union semun *sp;
288			caddr_t sg = stackgap_init();
289
290			sp = stackgap_alloc(&sg, sizeof(*sp));
291			sp->val = (int) uap->a5;
292			uap->a5 = (int)sp;
293			return semsys(td, (struct semsys_args *)uap);
294		    }
295		}
296
297		return semsys(td, (struct semsys_args *)uap);
298
299	case 1:				/* semget */
300		return semsys(td, (struct semsys_args *)uap);
301
302	case 2:				/* semop */
303		return semsys(td, (struct semsys_args *)uap);
304	}
305	return EINVAL;
306}
307
308
309/*
310 * iBCS2 shmsys call
311 */
312
313static void
314cvt_shmid2ishmid(bp, ibp)
315struct shmid_ds *bp;
316struct ibcs2_shmid_ds *ibp;
317{
318	cvt_perm2iperm(&bp->shm_perm, &ibp->shm_perm);
319	ibp->shm_segsz = bp->shm_segsz;
320	ibp->shm_lpid = bp->shm_lpid;
321	ibp->shm_cpid = bp->shm_cpid;
322	ibp->shm_nattch = bp->shm_nattch;
323	ibp->shm_cnattch = 0;			/* ignored anyway */
324	ibp->shm_atime = bp->shm_atime;
325	ibp->shm_dtime = bp->shm_dtime;
326	ibp->shm_ctime = bp->shm_ctime;
327	return;
328}
329
330static void
331cvt_ishmid2shmid(ibp, bp)
332struct ibcs2_shmid_ds *ibp;
333struct shmid_ds *bp;
334{
335	cvt_iperm2perm(&ibp->shm_perm, &bp->shm_perm);
336	bp->shm_segsz = ibp->shm_segsz;
337	bp->shm_lpid = ibp->shm_lpid;
338	bp->shm_cpid = ibp->shm_cpid;
339	bp->shm_nattch = ibp->shm_nattch;
340	bp->shm_atime = ibp->shm_atime;
341	bp->shm_dtime = ibp->shm_dtime;
342	bp->shm_ctime = ibp->shm_ctime;
343	bp->shm_internal = (void *)0;		/* ignored anyway */
344	return;
345}
346
347int
348ibcs2_shmsys(td, uap)
349	struct thread *td;
350	struct ibcs2_shmsys_args *uap;
351{
352	int error;
353
354	switch (uap->which) {
355	case 0:						/* shmat */
356		return shmsys(td, (struct shmsys_args *)uap);
357
358	case 1:						/* shmctl */
359		switch(uap->a3) {
360		case IBCS2_IPC_STAT:
361		    {
362			struct ibcs2_shmid_ds *isp;
363			struct shmid_ds *sp;
364			caddr_t sg = stackgap_init();
365
366			isp = (struct ibcs2_shmid_ds *)uap->a4;
367			sp = stackgap_alloc(&sg, sizeof(*sp));
368			uap->a4 = (int)sp;
369			error = shmsys(td, (struct shmsys_args *)uap);
370			if (!error) {
371				uap->a4 = (int)isp;
372				isp = stackgap_alloc(&sg, sizeof(*isp));
373				cvt_shmid2ishmid(sp, isp);
374				error = copyout((caddr_t)isp,
375						(caddr_t)uap->a4,
376						sizeof(*isp));
377			}
378			return error;
379		    }
380		case IBCS2_IPC_SET:
381		    {
382			struct ibcs2_shmid_ds *isp;
383			struct shmid_ds *sp;
384			caddr_t sg = stackgap_init();
385
386			isp = stackgap_alloc(&sg, sizeof(*isp));
387			sp = stackgap_alloc(&sg, sizeof(*sp));
388			error = copyin((caddr_t)uap->a4, (caddr_t)isp,
389				       sizeof(*isp));
390			if (error)
391				return error;
392			cvt_ishmid2shmid(isp, sp);
393			uap->a4 = (int)sp;
394			return shmsys(td, (struct shmsys_args *)uap);
395		    }
396		}
397
398		return shmsys(td, (struct shmsys_args *)uap);
399
400	case 2:						/* shmdt */
401		return shmsys(td, (struct shmsys_args *)uap);
402
403	case 3:						/* shmget */
404		return shmsys(td, (struct shmsys_args *)uap);
405	}
406	return EINVAL;
407}
408
409MODULE_DEPEND(ibcs2, sysvmsg, 1, 1, 1);
410MODULE_DEPEND(ibcs2, sysvsem, 1, 1, 1);
411MODULE_DEPEND(ibcs2, sysvshm, 1, 1, 1);
412