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: releng/5.0/sys/i386/ibcs2/ibcs2_ipc.c 108086 2002-12-19 09:40:13Z 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
48 static void cvt_msqid2imsqid(struct msqid_ds *, struct ibcs2_msqid_ds *);
49 static void cvt_imsqid2msqid(struct ibcs2_msqid_ds *, struct msqid_ds *);
50 #ifdef unused
51 static void cvt_sem2isem(struct sem *, struct ibcs2_sem *);
52 static void cvt_isem2sem(struct ibcs2_sem *, struct sem *);
53 #endif
54 static void cvt_semid2isemid(struct semid_ds *, struct ibcs2_semid_ds *);
55 static void cvt_isemid2semid(struct ibcs2_semid_ds *, struct semid_ds *);
56 static void cvt_shmid2ishmid(struct shmid_ds *, struct ibcs2_shmid_ds *);
57 static void cvt_ishmid2shmid(struct ibcs2_shmid_ds *, struct shmid_ds *);
58 static void cvt_perm2iperm(struct ipc_perm *, struct ibcs2_ipc_perm *);
59 static void cvt_iperm2perm(struct ibcs2_ipc_perm *, struct ipc_perm *);
60
61
62 /*
63 * iBCS2 msgsys call
64 */
65
66 static void
67 cvt_msqid2imsqid(bp, ibp)
68 struct msqid_ds *bp;
69 struct 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
85 static void
86 cvt_imsqid2msqid(ibp, bp)
87 struct ibcs2_msqid_ds *ibp;
88 struct 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
104 int
105 ibcs2_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
155 static void
156 cvt_sem2isem(bp, ibp)
157 struct sem *bp;
158 struct 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
167 static void
168 cvt_isem2sem(ibp, bp)
169 struct ibcs2_sem *ibp;
170 struct 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
180 static void
181 cvt_iperm2perm(ipp, pp)
182 struct ibcs2_ipc_perm *ipp;
183 struct 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
194 static void
195 cvt_perm2iperm(pp, ipp)
196 struct ipc_perm *pp;
197 struct 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
208 static void
209 cvt_semid2isemid(bp, ibp)
210 struct semid_ds *bp;
211 struct 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
221 static void
222 cvt_isemid2semid(ibp, bp)
223 struct ibcs2_semid_ds *ibp;
224 struct 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
234 int
235 ibcs2_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
312 static void
313 cvt_shmid2ishmid(bp, ibp)
314 struct shmid_ds *bp;
315 struct 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
329 static void
330 cvt_ishmid2shmid(ibp, bp)
331 struct ibcs2_shmid_ds *ibp;
332 struct 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
346 int
347 ibcs2_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 }
Cache object: f9611e2f4ef0086ea567c021b371c237
|