Merge from vendor branch CVS:
[dragonfly.git] / sys / emulation / ibcs2 / i386 / ibcs2_ipc.c
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: src/sys/i386/ibcs2/ibcs2_ipc.c,v 1.15 1999/08/28 00:43:57 peter Exp $
26  * $DragonFly: src/sys/emulation/ibcs2/i386/Attic/ibcs2_ipc.c,v 1.5 2003/08/27 06:30:03 rob Exp $
27  */
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 "ibcs2_types.h"
37 #include "ibcs2_signal.h"
38 #include "ibcs2_proto.h"
39 #include "ibcs2_util.h"
40 #include "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
49 static void cvt_msqid2imsqid (struct msqid_ds *, struct ibcs2_msqid_ds *);
50 static void cvt_imsqid2msqid (struct ibcs2_msqid_ds *, struct msqid_ds *);
51 #ifdef unused
52 static void cvt_sem2isem     (struct sem *, struct ibcs2_sem *);
53 static void cvt_isem2sem     (struct ibcs2_sem *, struct sem *);
54 #endif
55 static void cvt_semid2isemid (struct semid_ds *, struct ibcs2_semid_ds *);
56 static void cvt_isemid2semid (struct ibcs2_semid_ds *, struct semid_ds *);
57 static void cvt_shmid2ishmid (struct shmid_ds *, struct ibcs2_shmid_ds *);
58 static void cvt_ishmid2shmid (struct ibcs2_shmid_ds *, struct shmid_ds *);
59 static void cvt_perm2iperm   (struct ipc_perm *, struct ibcs2_ipc_perm *);
60 static void cvt_iperm2perm   (struct ibcs2_ipc_perm *, struct ipc_perm *);
61
62
63 /*
64  * iBCS2 msgsys call
65  */
66
67 static void
68 cvt_msqid2imsqid(bp, ibp)
69 struct msqid_ds *bp;
70 struct 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
86 static void
87 cvt_imsqid2msqid(ibp, bp)
88 struct ibcs2_msqid_ds *ibp;
89 struct 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
105 int
106 ibcs2_msgsys(struct ibcs2_msgsys_args *uap)
107 {
108         switch (SCARG(uap, which)) {
109         case 0:                         /* msgget */
110                 SCARG(uap, which) = 1;
111                 return msgsys((struct msgsys_args *)uap);
112         case 1: {                       /* msgctl */
113                 int error;
114                 struct msgsys_args margs;
115                 caddr_t sg = stackgap_init();
116
117                 SCARG(&margs, which) = 0;
118                 SCARG(&margs, a2) = SCARG(uap, a2);
119                 SCARG(&margs, a4) =
120                     (int)stackgap_alloc(&sg, sizeof(struct msqid_ds));
121                 SCARG(&margs, a3) = SCARG(uap, a3);
122                 switch (SCARG(&margs, a3)) {
123                 case IBCS2_IPC_STAT:
124                         error = msgsys(&margs);
125                         if (!error)
126                                 cvt_msqid2imsqid(
127                                     (struct msqid_ds *)SCARG(&margs, a4),
128                                     (struct ibcs2_msqid_ds *)SCARG(uap, a4));
129                         return error;
130                 case IBCS2_IPC_SET:
131                         cvt_imsqid2msqid((struct ibcs2_msqid_ds *)SCARG(uap,
132                                                                         a4),
133                                          (struct msqid_ds *)SCARG(&margs, a4));
134                         return msgsys(&margs);
135                 case IBCS2_IPC_RMID:
136                         return msgsys(&margs);
137                 }
138                 return EINVAL;
139         }
140         case 2:                         /* msgrcv */
141                 SCARG(uap, which) = 3;
142                 return msgsys((struct msgsys_args *)uap);
143         case 3:                         /* msgsnd */
144                 SCARG(uap, which) = 2;
145                 return msgsys((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(struct ibcs2_semsys_args *uap)
236 {
237         int error;
238
239         switch (SCARG(uap, which)) {
240         case 0:                                 /* semctl */
241                 switch(SCARG(uap, a4)) {
242                 case IBCS2_IPC_STAT:
243                     {
244                         struct ibcs2_semid_ds *isp;
245                         struct semid_ds *sp;
246                         union semun *sup, ssu;
247                         caddr_t sg = stackgap_init();
248
249
250                         ssu = (union semun) SCARG(uap, a5);
251                         sp = stackgap_alloc(&sg, sizeof(struct semid_ds));
252                         sup = stackgap_alloc(&sg, sizeof(union semun));
253                         sup->buf = sp;
254                         SCARG(uap, a5) = (int)sup;
255                         error = semsys((struct semsys_args *)uap);
256                         if (!error) {
257                                 SCARG(uap, a5) = (int)ssu.buf;
258                                 isp = stackgap_alloc(&sg, sizeof(*isp));
259                                 cvt_semid2isemid(sp, isp);
260                                 error = copyout((caddr_t)isp,
261                                                 (caddr_t)ssu.buf,
262                                                 sizeof(*isp));
263                         }
264                         return error;
265                     }
266                 case IBCS2_IPC_SET:
267                     {
268                         struct ibcs2_semid_ds *isp;
269                         struct semid_ds *sp;
270                         caddr_t sg = stackgap_init();
271
272                         isp = stackgap_alloc(&sg, sizeof(*isp));
273                         sp = stackgap_alloc(&sg, sizeof(*sp));
274                         error = copyin((caddr_t)SCARG(uap, a5), (caddr_t)isp,
275                                        sizeof(*isp));
276                         if (error)
277                                 return error;
278                         cvt_isemid2semid(isp, sp);
279                         SCARG(uap, a5) = (int)sp;
280                         return semsys((struct semsys_args *)uap);
281                     }
282                 case IBCS2_SETVAL:
283                     {
284                         union semun *sp;
285                         caddr_t sg = stackgap_init();
286
287                         sp = stackgap_alloc(&sg, sizeof(*sp));
288                         sp->val = (int) SCARG(uap, a5);
289                         SCARG(uap, a5) = (int)sp;
290                         return semsys((struct semsys_args *)uap);
291                     }
292                 }
293
294                 return semsys((struct semsys_args *)uap);
295
296         case 1:                         /* semget */
297                 return semsys((struct semsys_args *)uap);
298
299         case 2:                         /* semop */
300                 return semsys((struct semsys_args *)uap);
301         }
302         return EINVAL;
303 }
304
305
306 /*
307  * iBCS2 shmsys call
308  */
309
310 static void
311 cvt_shmid2ishmid(bp, ibp)
312 struct shmid_ds *bp;
313 struct ibcs2_shmid_ds *ibp;
314 {
315         cvt_perm2iperm(&bp->shm_perm, &ibp->shm_perm);
316         ibp->shm_segsz = bp->shm_segsz;
317         ibp->shm_lpid = bp->shm_lpid;
318         ibp->shm_cpid = bp->shm_cpid;
319         ibp->shm_nattch = bp->shm_nattch;
320         ibp->shm_cnattch = 0;                   /* ignored anyway */
321         ibp->shm_atime = bp->shm_atime;
322         ibp->shm_dtime = bp->shm_dtime;
323         ibp->shm_ctime = bp->shm_ctime;
324         return;
325 }
326
327 static void
328 cvt_ishmid2shmid(ibp, bp)
329 struct ibcs2_shmid_ds *ibp;
330 struct shmid_ds *bp;
331 {
332         cvt_iperm2perm(&ibp->shm_perm, &bp->shm_perm);
333         bp->shm_segsz = ibp->shm_segsz;
334         bp->shm_lpid = ibp->shm_lpid;
335         bp->shm_cpid = ibp->shm_cpid;
336         bp->shm_nattch = ibp->shm_nattch;
337         bp->shm_atime = ibp->shm_atime;
338         bp->shm_dtime = ibp->shm_dtime;
339         bp->shm_ctime = ibp->shm_ctime;
340         bp->shm_internal = (void *)0;           /* ignored anyway */
341         return;
342 }
343
344 int
345 ibcs2_shmsys(struct ibcs2_shmsys_args *uap)
346 {
347         int error;
348
349         switch (SCARG(uap, which)) {
350         case 0:                                         /* shmat */
351                 return shmsys((struct shmsys_args *)uap);
352
353         case 1:                                         /* shmctl */
354                 switch(SCARG(uap, a3)) {
355                 case IBCS2_IPC_STAT:
356                     {
357                         struct ibcs2_shmid_ds *isp;
358                         struct shmid_ds *sp;
359                         caddr_t sg = stackgap_init();
360
361                         isp = (struct ibcs2_shmid_ds *)SCARG(uap, a4);
362                         sp = stackgap_alloc(&sg, sizeof(*sp));
363                         SCARG(uap, a4) = (int)sp;
364                         error = shmsys((struct shmsys_args *)uap);
365                         if (!error) {
366                                 SCARG(uap, a4) = (int)isp;
367                                 isp = stackgap_alloc(&sg, sizeof(*isp));
368                                 cvt_shmid2ishmid(sp, isp);
369                                 error = copyout((caddr_t)isp,
370                                                 (caddr_t)SCARG(uap, a4),
371                                                 sizeof(*isp));
372                         }
373                         return error;
374                     }
375                 case IBCS2_IPC_SET:
376                     {
377                         struct ibcs2_shmid_ds *isp;
378                         struct shmid_ds *sp;
379                         caddr_t sg = stackgap_init();
380
381                         isp = stackgap_alloc(&sg, sizeof(*isp));
382                         sp = stackgap_alloc(&sg, sizeof(*sp));
383                         error = copyin((caddr_t)SCARG(uap, a4), (caddr_t)isp,
384                                        sizeof(*isp));
385                         if (error)
386                                 return error;
387                         cvt_ishmid2shmid(isp, sp);
388                         SCARG(uap, a4) = (int)sp;
389                         return shmsys((struct shmsys_args *)uap);
390                     }
391                 }
392
393                 return shmsys((struct shmsys_args *)uap);
394
395         case 2:                                         /* shmdt */
396                 return shmsys((struct shmsys_args *)uap);
397
398         case 3:                                         /* shmget */
399                 return shmsys((struct shmsys_args *)uap);
400         }
401         return EINVAL;
402 }