Deleted Added
sdiff udiff text old ( 107839 ) new ( 107849 )
full compact
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 * $FreeBSD: head/sys/i386/ibcs2/ibcs2_ipc.c 107849 2002-12-14 01:56:26Z alfred $
26 */
27
28#include <sys/param.h>
29#include <sys/systm.h>
30#include <sys/msg.h>
31#include <sys/sem.h>
32#include <sys/shm.h>
33#include <sys/sysproto.h>
34
35#include <i386/ibcs2/ibcs2_types.h>
36#include <i386/ibcs2/ibcs2_signal.h>
37#include <i386/ibcs2/ibcs2_proto.h>
38#include <i386/ibcs2/ibcs2_util.h>
39#include <i386/ibcs2/ibcs2_ipc.h>
40
41#define IBCS2_IPC_RMID 0
42#define IBCS2_IPC_SET 1
43#define IBCS2_IPC_STAT 2
44#define IBCS2_SETVAL 8
45
46
47
48static void cvt_msqid2imsqid(struct msqid_ds *, struct ibcs2_msqid_ds *);
49static void cvt_imsqid2msqid(struct ibcs2_msqid_ds *, struct msqid_ds *);
50#ifdef unused
51static void cvt_sem2isem(struct sem *, struct ibcs2_sem *);
52static void cvt_isem2sem(struct ibcs2_sem *, struct sem *);
53#endif
54static void cvt_semid2isemid(struct semid_ds *, struct ibcs2_semid_ds *);
55static void cvt_isemid2semid(struct ibcs2_semid_ds *, struct semid_ds *);
56static void cvt_shmid2ishmid(struct shmid_ds *, struct ibcs2_shmid_ds *);
57static void cvt_ishmid2shmid(struct ibcs2_shmid_ds *, struct shmid_ds *);
58static void cvt_perm2iperm(struct ipc_perm *, struct ibcs2_ipc_perm *);
59static void cvt_iperm2perm(struct ibcs2_ipc_perm *, struct ipc_perm *);
60
61
62/*
63 * iBCS2 msgsys call
64 */
65
66static void
67cvt_msqid2imsqid(bp, ibp)
68struct msqid_ds *bp;
69struct ibcs2_msqid_ds *ibp;
70{
71 cvt_perm2iperm(&bp->msg_perm, &ibp->msg_perm);
72 ibp->msg_first = bp->msg_first;
73 ibp->msg_last = bp->msg_last;
74 ibp->msg_cbytes = (u_short)bp->msg_cbytes;
75 ibp->msg_qnum = (u_short)bp->msg_qnum;
76 ibp->msg_qbytes = (u_short)bp->msg_qbytes;
77 ibp->msg_lspid = (u_short)bp->msg_lspid;
78 ibp->msg_lrpid = (u_short)bp->msg_lrpid;
79 ibp->msg_stime = bp->msg_stime;
80 ibp->msg_rtime = bp->msg_rtime;
81 ibp->msg_ctime = bp->msg_ctime;
82 return;
83}
84
85static void
86cvt_imsqid2msqid(ibp, bp)
87struct ibcs2_msqid_ds *ibp;
88struct msqid_ds *bp;
89{
90 cvt_iperm2perm(&ibp->msg_perm, &bp->msg_perm);
91 bp->msg_first = ibp->msg_first;
92 bp->msg_last = ibp->msg_last;
93 bp->msg_cbytes = ibp->msg_cbytes;
94 bp->msg_qnum = ibp->msg_qnum;
95 bp->msg_qbytes = ibp->msg_qbytes;
96 bp->msg_lspid = ibp->msg_lspid;
97 bp->msg_lrpid = ibp->msg_lrpid;
98 bp->msg_stime = ibp->msg_stime;
99 bp->msg_rtime = ibp->msg_rtime;
100 bp->msg_ctime = ibp->msg_ctime;
101 return;
102}
103
104int
105ibcs2_msgsys(td, uap)
106 struct thread *td;
107 struct ibcs2_msgsys_args *uap;
108{
109 switch (uap->which) {
110 case 0: /* msgget */
111 uap->which = 1;
112 return msgsys(td, (struct msgsys_args *)uap);
113 case 1: { /* msgctl */
114 int error;
115 struct msgsys_args margs;
116 caddr_t sg = stackgap_init();
117
118 margs.which = 0;
119 margs.a2 = uap->a2;
120 margs.a4 =
121 (int)stackgap_alloc(&sg, sizeof(struct msqid_ds));
122 margs.a3 = uap->a3;
123 switch (margs.a3) {
124 case IBCS2_IPC_STAT:
125 error = msgsys(td, &margs);
126 if (!error)
127 cvt_msqid2imsqid(
128 (struct msqid_ds *)margs.a4,
129 (struct ibcs2_msqid_ds *)uap->a4);
130 return error;
131 case IBCS2_IPC_SET:
132 cvt_imsqid2msqid((struct ibcs2_msqid_ds *)uap->a4,
133 (struct msqid_ds *)margs.a4);
134 return msgsys(td, &margs);
135 case IBCS2_IPC_RMID:
136 return msgsys(td, &margs);
137 }
138 return EINVAL;
139 }
140 case 2: /* msgrcv */
141 uap->which = 3;
142 return msgsys(td, (struct msgsys_args *)uap);
143 case 3: /* msgsnd */
144 uap->which = 2;
145 return msgsys(td, (struct msgsys_args *)uap);
146 default:
147 return EINVAL;
148 }
149}
150
151/*
152 * iBCS2 semsys call
153 */
154#ifdef unused
155static void
156cvt_sem2isem(bp, ibp)
157struct sem *bp;
158struct ibcs2_sem *ibp;
159{
160 ibp->semval = bp->semval;
161 ibp->sempid = bp->sempid;
162 ibp->semncnt = bp->semncnt;
163 ibp->semzcnt = bp->semzcnt;
164 return;
165}
166
167static void
168cvt_isem2sem(ibp, bp)
169struct ibcs2_sem *ibp;
170struct sem *bp;
171{
172 bp->semval = ibp->semval;
173 bp->sempid = ibp->sempid;
174 bp->semncnt = ibp->semncnt;
175 bp->semzcnt = ibp->semzcnt;
176 return;
177}
178#endif
179
180static void
181cvt_iperm2perm(ipp, pp)
182struct ibcs2_ipc_perm *ipp;
183struct ipc_perm *pp;
184{
185 pp->uid = ipp->uid;
186 pp->gid = ipp->gid;
187 pp->cuid = ipp->cuid;
188 pp->cgid = ipp->cgid;
189 pp->mode = ipp->mode;
190 pp->seq = ipp->seq;
191 pp->key = ipp->key;
192}
193
194static void
195cvt_perm2iperm(pp, ipp)
196struct ipc_perm *pp;
197struct ibcs2_ipc_perm *ipp;
198{
199 ipp->uid = pp->uid;
200 ipp->gid = pp->gid;
201 ipp->cuid = pp->cuid;
202 ipp->cgid = pp->cgid;
203 ipp->mode = pp->mode;
204 ipp->seq = pp->seq;
205 ipp->key = pp->key;
206}
207
208static void
209cvt_semid2isemid(bp, ibp)
210struct semid_ds *bp;
211struct ibcs2_semid_ds *ibp;
212{
213 cvt_perm2iperm(&bp->sem_perm, &ibp->sem_perm);
214 ibp->sem_base = (struct ibcs2_sem *)bp->sem_base;
215 ibp->sem_nsems = bp->sem_nsems;
216 ibp->sem_otime = bp->sem_otime;
217 ibp->sem_ctime = bp->sem_ctime;
218 return;
219}
220
221static void
222cvt_isemid2semid(ibp, bp)
223struct ibcs2_semid_ds *ibp;
224struct semid_ds *bp;
225{
226 cvt_iperm2perm(&ibp->sem_perm, &bp->sem_perm);
227 bp->sem_base = (struct sem *)ibp->sem_base;
228 bp->sem_nsems = ibp->sem_nsems;
229 bp->sem_otime = ibp->sem_otime;
230 bp->sem_ctime = ibp->sem_ctime;
231 return;
232}
233
234int
235ibcs2_semsys(td, uap)
236 struct thread *td;
237 struct ibcs2_semsys_args *uap;
238{
239 int error;
240
241 switch (uap->which) {
242 case 0: /* semctl */
243 switch(uap->a4) {
244 case IBCS2_IPC_STAT:
245 {
246 struct ibcs2_semid_ds *isp;
247 struct semid_ds *sp;
248 union semun *sup, ssu;
249 caddr_t sg = stackgap_init();
250
251
252 ssu = (union semun) uap->a5;
253 sp = stackgap_alloc(&sg, sizeof(struct semid_ds));
254 sup = stackgap_alloc(&sg, sizeof(union semun));
255 sup->buf = sp;
256 uap->a5 = (int)sup;
257 error = semsys(td, (struct semsys_args *)uap);
258 if (!error) {
259 uap->a5 = (int)ssu.buf;
260 isp = stackgap_alloc(&sg, sizeof(*isp));
261 cvt_semid2isemid(sp, isp);
262 error = copyout((caddr_t)isp,
263 (caddr_t)ssu.buf,
264 sizeof(*isp));
265 }
266 return error;
267 }
268 case IBCS2_IPC_SET:
269 {
270 struct ibcs2_semid_ds *isp;
271 struct semid_ds *sp;
272 caddr_t sg = stackgap_init();
273
274 isp = stackgap_alloc(&sg, sizeof(*isp));
275 sp = stackgap_alloc(&sg, sizeof(*sp));
276 error = copyin((caddr_t)uap->a5, (caddr_t)isp,
277 sizeof(*isp));
278 if (error)
279 return error;
280 cvt_isemid2semid(isp, sp);
281 uap->a5 = (int)sp;
282 return semsys(td, (struct semsys_args *)uap);
283 }
284 case IBCS2_SETVAL:
285 {
286 union semun *sp;
287 caddr_t sg = stackgap_init();
288
289 sp = stackgap_alloc(&sg, sizeof(*sp));
290 sp->val = (int) uap->a5;
291 uap->a5 = (int)sp;
292 return semsys(td, (struct semsys_args *)uap);
293 }
294 }
295
296 return semsys(td, (struct semsys_args *)uap);
297
298 case 1: /* semget */
299 return semsys(td, (struct semsys_args *)uap);
300
301 case 2: /* semop */
302 return semsys(td, (struct semsys_args *)uap);
303 }
304 return EINVAL;
305}
306
307
308/*
309 * iBCS2 shmsys call
310 */
311
312static void
313cvt_shmid2ishmid(bp, ibp)
314struct shmid_ds *bp;
315struct ibcs2_shmid_ds *ibp;
316{
317 cvt_perm2iperm(&bp->shm_perm, &ibp->shm_perm);
318 ibp->shm_segsz = bp->shm_segsz;
319 ibp->shm_lpid = bp->shm_lpid;
320 ibp->shm_cpid = bp->shm_cpid;
321 ibp->shm_nattch = bp->shm_nattch;
322 ibp->shm_cnattch = 0; /* ignored anyway */
323 ibp->shm_atime = bp->shm_atime;
324 ibp->shm_dtime = bp->shm_dtime;
325 ibp->shm_ctime = bp->shm_ctime;
326 return;
327}
328
329static void
330cvt_ishmid2shmid(ibp, bp)
331struct ibcs2_shmid_ds *ibp;
332struct shmid_ds *bp;
333{
334 cvt_iperm2perm(&ibp->shm_perm, &bp->shm_perm);
335 bp->shm_segsz = ibp->shm_segsz;
336 bp->shm_lpid = ibp->shm_lpid;
337 bp->shm_cpid = ibp->shm_cpid;
338 bp->shm_nattch = ibp->shm_nattch;
339 bp->shm_atime = ibp->shm_atime;
340 bp->shm_dtime = ibp->shm_dtime;
341 bp->shm_ctime = ibp->shm_ctime;
342 bp->shm_internal = (void *)0; /* ignored anyway */
343 return;
344}
345
346int
347ibcs2_shmsys(td, uap)
348 struct thread *td;
349 struct ibcs2_shmsys_args *uap;
350{
351 int error;
352
353 switch (uap->which) {
354 case 0: /* shmat */
355 return shmsys(td, (struct shmsys_args *)uap);
356
357 case 1: /* shmctl */
358 switch(uap->a3) {
359 case IBCS2_IPC_STAT:
360 {
361 struct ibcs2_shmid_ds *isp;
362 struct shmid_ds *sp;
363 caddr_t sg = stackgap_init();
364
365 isp = (struct ibcs2_shmid_ds *)uap->a4;
366 sp = stackgap_alloc(&sg, sizeof(*sp));
367 uap->a4 = (int)sp;
368 error = shmsys(td, (struct shmsys_args *)uap);
369 if (!error) {
370 uap->a4 = (int)isp;
371 isp = stackgap_alloc(&sg, sizeof(*isp));
372 cvt_shmid2ishmid(sp, isp);
373 error = copyout((caddr_t)isp,
374 (caddr_t)uap->a4,
375 sizeof(*isp));
376 }
377 return error;
378 }
379 case IBCS2_IPC_SET:
380 {
381 struct ibcs2_shmid_ds *isp;
382 struct shmid_ds *sp;
383 caddr_t sg = stackgap_init();
384
385 isp = stackgap_alloc(&sg, sizeof(*isp));
386 sp = stackgap_alloc(&sg, sizeof(*sp));
387 error = copyin((caddr_t)uap->a4, (caddr_t)isp,
388 sizeof(*isp));
389 if (error)
390 return error;
391 cvt_ishmid2shmid(isp, sp);
392 uap->a4 = (int)sp;
393 return shmsys(td, (struct shmsys_args *)uap);
394 }
395 }
396
397 return shmsys(td, (struct shmsys_args *)uap);
398
399 case 2: /* shmdt */
400 return shmsys(td, (struct shmsys_args *)uap);
401
402 case 3: /* shmget */
403 return shmsys(td, (struct shmsys_args *)uap);
404 }
405 return EINVAL;
406}