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