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