svr4_ipc.c revision 50477
1/* 2 * $FreeBSD: head/sys/compat/svr4/svr4_ipc.c 50477 1999-08-28 01:08:13Z peter $ 3 * Derived from: 4 * $NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $ */ 5 6/*- 7 * Original copyright: 8 * 9 * Copyright (c) 1995 The NetBSD Foundation, Inc. 10 * All rights reserved. 11 * 12 * This code is derived from software contributed to The NetBSD Foundation 13 * by Christos Zoulas. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. All advertising materials mentioning features or use of this software 24 * must display the following acknowledgement: 25 * This product includes software developed by the NetBSD 26 * Foundation, Inc. and its contributors. 27 * 4. Neither the name of The NetBSD Foundation nor the names of its 28 * contributors may be used to endorse or promote products derived 29 * from this software without specific prior written permission. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 32 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 33 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 34 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 35 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGE. 42 */ 43 44/* 45 * Portions of this code have been derived from software contributed 46 * to the FreeBSD Project by Mark Newton. 47 * 48 * Copyright (c) 1999 Mark Newton 49 * All rights reserved. 50 * 51 * Redistribution and use in source and binary forms, with or without 52 * modification, are permitted provided that the following conditions 53 * are met: 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. The name of the author may not be used to endorse or promote products 60 * derived from this software without specific prior written permission 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 63 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 64 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 65 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 66 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 67 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 68 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 69 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 70 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 71 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 72 * 73 * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due 74 * to preprocessor conditionals). A nice project for a kernel hacking 75 * novice might be to MakeItGo, but I have more important fish to fry 76 * at present. 77 * 78 */ 79 80#include <sys/types.h> 81#include <sys/param.h> 82#include <sys/kernel.h> 83#include <sys/shm.h> 84#include <sys/msg.h> 85#include <sys/sem.h> 86#include <sys/proc.h> 87#include <sys/uio.h> 88#include <sys/time.h> 89#include <sys/malloc.h> 90#include <sys/mman.h> 91#include <sys/systm.h> 92#include <sys/stat.h> 93 94#include <sys/mount.h> 95#include <sys/sysproto.h> 96 97#include <svr4/svr4_types.h> 98#include <svr4/svr4_signal.h> 99#include <svr4/svr4_proto.h> 100#include <svr4/svr4_util.h> 101#include <svr4/svr4_ipc.h> 102 103#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM) 104static void svr4_to_bsd_ipc_perm __P((const struct svr4_ipc_perm *, 105 struct ipc_perm *)); 106static void bsd_to_svr4_ipc_perm __P((const struct ipc_perm *, 107 struct svr4_ipc_perm *)); 108#endif 109 110#ifdef SYSVSEM 111static void bsd_to_svr4_semid_ds __P((const struct semid_ds *, 112 struct svr4_semid_ds *)); 113static void svr4_to_bsd_semid_ds __P((const struct svr4_semid_ds *, 114 struct semid_ds *)); 115static int svr4_setsemun __P((caddr_t *sgp, union semun **argp, 116 union semun *usp)); 117static int svr4_semop __P((struct proc *, void *, register_t *)); 118static int svr4_semget __P((struct proc *, void *, register_t *)); 119static int svr4_semctl __P((struct proc *, void *, register_t *)); 120#endif 121 122#ifdef SYSVMSG 123static void bsd_to_svr4_msqid_ds __P((const struct msqid_ds *, 124 struct svr4_msqid_ds *)); 125static void svr4_to_bsd_msqid_ds __P((const struct svr4_msqid_ds *, 126 struct msqid_ds *)); 127static int svr4_msgsnd __P((struct proc *, void *, register_t *)); 128static int svr4_msgrcv __P((struct proc *, void *, register_t *)); 129static int svr4_msgget __P((struct proc *, void *, register_t *)); 130static int svr4_msgctl __P((struct proc *, void *, register_t *)); 131#endif 132 133#ifdef SYSVSHM 134static void bsd_to_svr4_shmid_ds __P((const struct shmid_ds *, 135 struct svr4_shmid_ds *)); 136static void svr4_to_bsd_shmid_ds __P((const struct svr4_shmid_ds *, 137 struct shmid_ds *)); 138static int svr4_shmat __P((struct proc *, void *, register_t *)); 139static int svr4_shmdt __P((struct proc *, void *, register_t *)); 140static int svr4_shmget __P((struct proc *, void *, register_t *)); 141static int svr4_shmctl __P((struct proc *, void *, register_t *)); 142#endif 143 144#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM) 145 146static void 147svr4_to_bsd_ipc_perm(spp, bpp) 148 const struct svr4_ipc_perm *spp; 149 struct ipc_perm *bpp; 150{ 151 bpp->key = spp->key; 152 bpp->uid = spp->uid; 153 bpp->gid = spp->gid; 154 bpp->cuid = spp->cuid; 155 bpp->cgid = spp->cgid; 156 bpp->mode = spp->mode; 157 bpp->seq = spp->seq; 158} 159 160static void 161bsd_to_svr4_ipc_perm(bpp, spp) 162 const struct ipc_perm *bpp; 163 struct svr4_ipc_perm *spp; 164{ 165 spp->key = bpp->key; 166 spp->uid = bpp->uid; 167 spp->gid = bpp->gid; 168 spp->cuid = bpp->cuid; 169 spp->cgid = bpp->cgid; 170 spp->mode = bpp->mode; 171 spp->seq = bpp->seq; 172} 173#endif 174 175#ifdef SYSVSEM 176static void 177bsd_to_svr4_semid_ds(bds, sds) 178 const struct semid_ds *bds; 179 struct svr4_semid_ds *sds; 180{ 181 bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm); 182 sds->sem_base = (struct svr4_sem *) bds->sem_base; 183 sds->sem_nsems = bds->sem_nsems; 184 sds->sem_otime = bds->sem_otime; 185 sds->sem_pad1 = bds->sem_pad1; 186 sds->sem_ctime = bds->sem_ctime; 187 sds->sem_pad2 = bds->sem_pad2; 188} 189 190static void 191svr4_to_bsd_semid_ds(sds, bds) 192 const struct svr4_semid_ds *sds; 193 struct semid_ds *bds; 194{ 195 svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm); 196 bds->sem_base = (struct sem *) bds->sem_base; 197 bds->sem_nsems = sds->sem_nsems; 198 bds->sem_otime = sds->sem_otime; 199 bds->sem_pad1 = sds->sem_pad1; 200 bds->sem_ctime = sds->sem_ctime; 201 bds->sem_pad2 = sds->sem_pad2; 202} 203 204static int 205svr4_setsemun(sgp, argp, usp) 206 caddr_t *sgp; 207 union semun **argp; 208 union semun *usp; 209{ 210 *argp = stackgap_alloc(sgp, sizeof(union semun)); 211 return copyout((caddr_t)usp, *argp, sizeof(union semun)); 212} 213 214struct svr4_sys_semctl_args { 215 syscallarg(int) what; 216 syscallarg(int) semid; 217 syscallarg(int) semnum; 218 syscallarg(int) cmd; 219 syscallarg(union semun) arg; 220}; 221 222static int 223svr4_semctl(p, v, retval) 224 struct proc *p; 225 void *v; 226 register_t *retval; 227{ 228 int error; 229 struct svr4_sys_semctl_args *uap = v; 230 struct sys___semctl_args ap; 231 struct svr4_semid_ds ss; 232 struct semid_ds bs, *bsp; 233 caddr_t sg = stackgap_init(p->p_emul); 234 235 SCARG(&ap, semid) = SCARG(uap, semid); 236 SCARG(&ap, semnum) = SCARG(uap, semnum); 237 238 switch (SCARG(uap, cmd)) { 239 case SVR4_SEM_GETZCNT: 240 case SVR4_SEM_GETNCNT: 241 case SVR4_SEM_GETPID: 242 case SVR4_SEM_GETVAL: 243 switch (SCARG(uap, cmd)) { 244 case SVR4_SEM_GETZCNT: 245 SCARG(&ap, cmd) = GETZCNT; 246 break; 247 case SVR4_SEM_GETNCNT: 248 SCARG(&ap, cmd) = GETNCNT; 249 break; 250 case SVR4_SEM_GETPID: 251 SCARG(&ap, cmd) = GETPID; 252 break; 253 case SVR4_SEM_GETVAL: 254 SCARG(&ap, cmd) = GETVAL; 255 break; 256 } 257 return sys___semctl(p, &ap, retval); 258 259 case SVR4_SEM_SETVAL: 260 error = svr4_setsemun(&sg, &SCARG(&ap, arg), &SCARG(uap, arg)); 261 if (error) 262 return error; 263 SCARG(&ap, cmd) = SETVAL; 264 return sys___semctl(p, &ap, retval); 265 266 case SVR4_SEM_GETALL: 267 error = svr4_setsemun(&sg, &SCARG(&ap, arg), &SCARG(uap, arg)); 268 if (error) 269 return error; 270 SCARG(&ap, cmd) = GETVAL; 271 return sys___semctl(p, &ap, retval); 272 273 case SVR4_SEM_SETALL: 274 error = svr4_setsemun(&sg, &SCARG(&ap, arg), &SCARG(uap, arg)); 275 if (error) 276 return error; 277 SCARG(&ap, cmd) = SETVAL; 278 return sys___semctl(p, &ap, retval); 279 280 case SVR4_IPC_STAT: 281 SCARG(&ap, cmd) = IPC_STAT; 282 bsp = stackgap_alloc(&sg, sizeof(bs)); 283 error = svr4_setsemun(&sg, &SCARG(&ap, arg), 284 (union semun *)&bsp); 285 if (error) 286 return error; 287 if ((error = sys___semctl(p, &ap, retval)) != 0) 288 return error; 289 error = copyin((caddr_t)bsp, (caddr_t)&bs, sizeof(bs)); 290 if (error) 291 return error; 292 bsd_to_svr4_semid_ds(&bs, &ss); 293 return copyout(&ss, SCARG(uap, arg).buf, sizeof(ss)); 294 295 case SVR4_IPC_SET: 296 SCARG(&ap, cmd) = IPC_SET; 297 bsp = stackgap_alloc(&sg, sizeof(bs)); 298 error = svr4_setsemun(&sg, &SCARG(&ap, arg), 299 (union semun *)&bsp); 300 if (error) 301 return error; 302 error = copyin(SCARG(uap, arg).buf, (caddr_t) &ss, sizeof ss); 303 if (error) 304 return error; 305 svr4_to_bsd_semid_ds(&ss, &bs); 306 error = copyout(&bs, bsp, sizeof(bs)); 307 if (error) 308 return error; 309 return sys___semctl(p, &ap, retval); 310 311 case SVR4_IPC_RMID: 312 SCARG(&ap, cmd) = IPC_RMID; 313 bsp = stackgap_alloc(&sg, sizeof(bs)); 314 error = svr4_setsemun(&sg, &SCARG(&ap, arg), 315 (union semun *)&bsp); 316 if (error) 317 return error; 318 error = copyin(SCARG(uap, arg).buf, &ss, sizeof ss); 319 if (error) 320 return error; 321 svr4_to_bsd_semid_ds(&ss, &bs); 322 error = copyout(&bs, bsp, sizeof(bs)); 323 if (error) 324 return error; 325 return sys___semctl(p, &ap, retval); 326 327 default: 328 return EINVAL; 329 } 330} 331 332struct svr4_sys_semget_args { 333 syscallarg(int) what; 334 syscallarg(svr4_key_t) key; 335 syscallarg(int) nsems; 336 syscallarg(int) semflg; 337}; 338 339static int 340svr4_semget(p, v, retval) 341 struct proc *p; 342 void *v; 343 register_t *retval; 344{ 345 struct svr4_sys_semget_args *uap = v; 346 struct sys_semget_args ap; 347 348 SCARG(&ap, key) = SCARG(uap, key); 349 SCARG(&ap, nsems) = SCARG(uap, nsems); 350 SCARG(&ap, semflg) = SCARG(uap, semflg); 351 352 return sys_semget(p, &ap, retval); 353} 354 355struct svr4_sys_semop_args { 356 syscallarg(int) what; 357 syscallarg(int) semid; 358 syscallarg(struct svr4_sembuf *) sops; 359 syscallarg(u_int) nsops; 360}; 361 362static int 363svr4_semop(p, v, retval) 364 struct proc *p; 365 void *v; 366 register_t *retval; 367{ 368 struct svr4_sys_semop_args *uap = v; 369 struct sys_semop_args ap; 370 371 SCARG(&ap, semid) = SCARG(uap, semid); 372 /* These are the same */ 373 SCARG(&ap, sops) = (struct sembuf *) SCARG(uap, sops); 374 SCARG(&ap, nsops) = SCARG(uap, nsops); 375 376 return sys_semop(p, &ap, retval); 377} 378 379int 380svr4_sys_semsys(p, v, retval) 381 struct proc *p; 382 void *v; 383 register_t *retval; 384{ 385 struct svr4_sys_semsys_args *uap = v; 386 387 DPRINTF(("svr4_semsys(%d)\n", SCARG(uap, what))); 388 389 switch (SCARG(uap, what)) { 390 case SVR4_semctl: 391 return svr4_semctl(p, v, retval); 392 case SVR4_semget: 393 return svr4_semget(p, v, retval); 394 case SVR4_semop: 395 return svr4_semop(p, v, retval); 396 default: 397 return EINVAL; 398 } 399} 400#endif 401 402#ifdef SYSVMSG 403static void 404bsd_to_svr4_msqid_ds(bds, sds) 405 const struct msqid_ds *bds; 406 struct svr4_msqid_ds *sds; 407{ 408 bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm); 409 sds->msg_first = (struct svr4_msg *) bds->msg_first; 410 sds->msg_last = (struct svr4_msg *) bds->msg_last; 411 sds->msg_cbytes = bds->msg_cbytes; 412 sds->msg_qnum = bds->msg_qnum; 413 sds->msg_qbytes = bds->msg_qbytes; 414 sds->msg_lspid = bds->msg_lspid; 415 sds->msg_lrpid = bds->msg_lrpid; 416 sds->msg_stime = bds->msg_stime; 417 sds->msg_pad1 = bds->msg_pad1; 418 sds->msg_rtime = bds->msg_rtime; 419 sds->msg_pad2 = bds->msg_pad2; 420 sds->msg_ctime = bds->msg_ctime; 421 sds->msg_pad3 = bds->msg_pad3; 422 423 /* use the padding for the rest of the fields */ 424 { 425 const short *pad = (const short *) bds->msg_pad4; 426 sds->msg_cv = pad[0]; 427 sds->msg_qnum_cv = pad[1]; 428 } 429} 430 431static void 432svr4_to_bsd_msqid_ds(sds, bds) 433 const struct svr4_msqid_ds *sds; 434 struct msqid_ds *bds; 435{ 436 svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm); 437 bds->msg_first = (struct msg *) sds->msg_first; 438 bds->msg_last = (struct msg *) sds->msg_last; 439 bds->msg_cbytes = sds->msg_cbytes; 440 bds->msg_qnum = sds->msg_qnum; 441 bds->msg_qbytes = sds->msg_qbytes; 442 bds->msg_lspid = sds->msg_lspid; 443 bds->msg_lrpid = sds->msg_lrpid; 444 bds->msg_stime = sds->msg_stime; 445 bds->msg_pad1 = sds->msg_pad1; 446 bds->msg_rtime = sds->msg_rtime; 447 bds->msg_pad2 = sds->msg_pad2; 448 bds->msg_ctime = sds->msg_ctime; 449 bds->msg_pad3 = sds->msg_pad3; 450 451 /* use the padding for the rest of the fields */ 452 { 453 short *pad = (short *) bds->msg_pad4; 454 pad[0] = sds->msg_cv; 455 pad[1] = sds->msg_qnum_cv; 456 } 457} 458 459struct svr4_sys_msgsnd_args { 460 syscallarg(int) what; 461 syscallarg(int) msqid; 462 syscallarg(void *) msgp; 463 syscallarg(size_t) msgsz; 464 syscallarg(int) msgflg; 465}; 466 467static int 468svr4_msgsnd(p, v, retval) 469 struct proc *p; 470 void *v; 471 register_t *retval; 472{ 473 struct svr4_sys_msgsnd_args *uap = v; 474 struct sys_msgsnd_args ap; 475 476 SCARG(&ap, msqid) = SCARG(uap, msqid); 477 SCARG(&ap, msgp) = SCARG(uap, msgp); 478 SCARG(&ap, msgsz) = SCARG(uap, msgsz); 479 SCARG(&ap, msgflg) = SCARG(uap, msgflg); 480 481 return sys_msgsnd(p, &ap, retval); 482} 483 484struct svr4_sys_msgrcv_args { 485 syscallarg(int) what; 486 syscallarg(int) msqid; 487 syscallarg(void *) msgp; 488 syscallarg(size_t) msgsz; 489 syscallarg(long) msgtyp; 490 syscallarg(int) msgflg; 491}; 492 493static int 494svr4_msgrcv(p, v, retval) 495 struct proc *p; 496 void *v; 497 register_t *retval; 498{ 499 struct svr4_sys_msgrcv_args *uap = v; 500 struct sys_msgrcv_args ap; 501 502 SCARG(&ap, msqid) = SCARG(uap, msqid); 503 SCARG(&ap, msgp) = SCARG(uap, msgp); 504 SCARG(&ap, msgsz) = SCARG(uap, msgsz); 505 SCARG(&ap, msgtyp) = SCARG(uap, msgtyp); 506 SCARG(&ap, msgflg) = SCARG(uap, msgflg); 507 508 return sys_msgrcv(p, &ap, retval); 509} 510 511struct svr4_sys_msgget_args { 512 syscallarg(int) what; 513 syscallarg(svr4_key_t) key; 514 syscallarg(int) msgflg; 515}; 516 517static int 518svr4_msgget(p, v, retval) 519 struct proc *p; 520 void *v; 521 register_t *retval; 522{ 523 struct svr4_sys_msgget_args *uap = v; 524 struct sys_msgget_args ap; 525 526 SCARG(&ap, key) = SCARG(uap, key); 527 SCARG(&ap, msgflg) = SCARG(uap, msgflg); 528 529 return sys_msgget(p, &ap, retval); 530} 531 532struct svr4_sys_msgctl_args { 533 syscallarg(int) what; 534 syscallarg(int) msqid; 535 syscallarg(int) cmd; 536 syscallarg(struct svr4_msqid_ds *) buf; 537}; 538 539static int 540svr4_msgctl(p, v, retval) 541 struct proc *p; 542 void *v; 543 register_t *retval; 544{ 545 int error; 546 struct svr4_sys_msgctl_args *uap = v; 547 struct sys_msgctl_args ap; 548 struct svr4_msqid_ds ss; 549 struct msqid_ds bs; 550 caddr_t sg = stackgap_init(p->p_emul); 551 552 SCARG(&ap, msqid) = SCARG(uap, msqid); 553 SCARG(&ap, cmd) = SCARG(uap, cmd); 554 SCARG(&ap, buf) = stackgap_alloc(&sg, sizeof(bs)); 555 556 switch (SCARG(uap, cmd)) { 557 case SVR4_IPC_STAT: 558 SCARG(&ap, cmd) = IPC_STAT; 559 if ((error = sys_msgctl(p, &ap, retval)) != 0) 560 return error; 561 error = copyin(&bs, SCARG(&ap, buf), sizeof bs); 562 if (error) 563 return error; 564 bsd_to_svr4_msqid_ds(&bs, &ss); 565 return copyout(&ss, SCARG(uap, buf), sizeof ss); 566 567 case SVR4_IPC_SET: 568 SCARG(&ap, cmd) = IPC_SET; 569 error = copyin(SCARG(uap, buf), &ss, sizeof ss); 570 if (error) 571 return error; 572 svr4_to_bsd_msqid_ds(&ss, &bs); 573 error = copyout(&bs, SCARG(&ap, buf), sizeof bs); 574 if (error) 575 return error; 576 return sys_msgctl(p, &ap, retval); 577 578 case SVR4_IPC_RMID: 579 SCARG(&ap, cmd) = IPC_RMID; 580 error = copyin(SCARG(uap, buf), &ss, sizeof ss); 581 if (error) 582 return error; 583 svr4_to_bsd_msqid_ds(&ss, &bs); 584 error = copyout(&bs, SCARG(&ap, buf), sizeof bs); 585 if (error) 586 return error; 587 return sys_msgctl(p, &ap, retval); 588 589 default: 590 return EINVAL; 591 } 592} 593 594int 595svr4_sys_msgsys(p, v, retval) 596 struct proc *p; 597 void *v; 598 register_t *retval; 599{ 600 struct svr4_sys_msgsys_args *uap = v; 601 602 DPRINTF(("svr4_msgsys(%d)\n", SCARG(uap, what))); 603 604 switch (SCARG(uap, what)) { 605 case SVR4_msgsnd: 606 return svr4_msgsnd(p, v, retval); 607 case SVR4_msgrcv: 608 return svr4_msgrcv(p, v, retval); 609 case SVR4_msgget: 610 return svr4_msgget(p, v, retval); 611 case SVR4_msgctl: 612 return svr4_msgctl(p, v, retval); 613 default: 614 return EINVAL; 615 } 616} 617#endif 618 619#ifdef SYSVSHM 620 621static void 622bsd_to_svr4_shmid_ds(bds, sds) 623 const struct shmid_ds *bds; 624 struct svr4_shmid_ds *sds; 625{ 626 bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm); 627 sds->shm_segsz = bds->shm_segsz; 628 sds->shm_lkcnt = 0; 629 sds->shm_lpid = bds->shm_lpid; 630 sds->shm_cpid = bds->shm_cpid; 631 sds->shm_amp = bds->shm_internal; 632 sds->shm_nattch = bds->shm_nattch; 633 sds->shm_cnattch = 0; 634 sds->shm_atime = bds->shm_atime; 635 sds->shm_pad1 = 0; 636 sds->shm_dtime = bds->shm_dtime; 637 sds->shm_pad2 = 0; 638 sds->shm_ctime = bds->shm_ctime; 639 sds->shm_pad3 = 0; 640} 641 642static void 643svr4_to_bsd_shmid_ds(sds, bds) 644 const struct svr4_shmid_ds *sds; 645 struct shmid_ds *bds; 646{ 647 svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm); 648 bds->shm_segsz = sds->shm_segsz; 649 bds->shm_lpid = sds->shm_lpid; 650 bds->shm_cpid = sds->shm_cpid; 651 bds->shm_internal = sds->shm_amp; 652 bds->shm_nattch = sds->shm_nattch; 653 bds->shm_atime = sds->shm_atime; 654 bds->shm_dtime = sds->shm_dtime; 655 bds->shm_ctime = sds->shm_ctime; 656} 657 658struct svr4_sys_shmat_args { 659 syscallarg(int) what; 660 syscallarg(int) shmid; 661 syscallarg(void *) shmaddr; 662 syscallarg(int) shmflg; 663}; 664 665static int 666svr4_shmat(p, v, retval) 667 struct proc *p; 668 void *v; 669 register_t *retval; 670{ 671 struct svr4_sys_shmat_args *uap = v; 672 struct sys_shmat_args ap; 673 674 SCARG(&ap, shmid) = SCARG(uap, shmid); 675 SCARG(&ap, shmaddr) = SCARG(uap, shmaddr); 676 SCARG(&ap, shmflg) = SCARG(uap, shmflg); 677 678 return sys_shmat(p, &ap, retval); 679} 680 681struct svr4_sys_shmdt_args { 682 syscallarg(int) what; 683 syscallarg(void *) shmaddr; 684}; 685 686static int 687svr4_shmdt(p, v, retval) 688 struct proc *p; 689 void *v; 690 register_t *retval; 691{ 692 struct svr4_sys_shmdt_args *uap = v; 693 struct sys_shmdt_args ap; 694 695 SCARG(&ap, shmaddr) = SCARG(uap, shmaddr); 696 697 return sys_shmdt(p, &ap, retval); 698} 699 700struct svr4_sys_shmget_args { 701 syscallarg(int) what; 702 syscallarg(key_t) key; 703 syscallarg(int) size; 704 syscallarg(int) shmflg; 705}; 706 707static int 708svr4_shmget(p, v, retval) 709 struct proc *p; 710 void *v; 711 register_t *retval; 712{ 713 struct svr4_sys_shmget_args *uap = v; 714 struct sys_shmget_args ap; 715 716 SCARG(&ap, key) = SCARG(uap, key); 717 SCARG(&ap, size) = SCARG(uap, size); 718 SCARG(&ap, shmflg) = SCARG(uap, shmflg); 719 720 return sys_shmget(p, &ap, retval); 721} 722 723struct svr4_sys_shmctl_args { 724 syscallarg(int) what; 725 syscallarg(int) shmid; 726 syscallarg(int) cmd; 727 syscallarg(struct svr4_shmid_ds *) buf; 728}; 729 730int 731svr4_shmctl(p, v, retval) 732 struct proc *p; 733 void *v; 734 register_t *retval; 735{ 736 struct svr4_sys_shmctl_args *uap = v; 737 int error; 738 caddr_t sg = stackgap_init(p->p_emul); 739 struct sys_shmctl_args ap; 740 struct shmid_ds bs; 741 struct svr4_shmid_ds ss; 742 743 SCARG(&ap, shmid) = SCARG(uap, shmid); 744 745 if (SCARG(uap, buf) != NULL) { 746 SCARG(&ap, buf) = stackgap_alloc(&sg, sizeof (struct shmid_ds)); 747 switch (SCARG(uap, cmd)) { 748 case SVR4_IPC_SET: 749 case SVR4_IPC_RMID: 750 case SVR4_SHM_LOCK: 751 case SVR4_SHM_UNLOCK: 752 error = copyin(SCARG(uap, buf), (caddr_t) &ss, 753 sizeof ss); 754 if (error) 755 return error; 756 svr4_to_bsd_shmid_ds(&ss, &bs); 757 error = copyout(&bs, SCARG(&ap, buf), sizeof bs); 758 if (error) 759 return error; 760 break; 761 default: 762 break; 763 } 764 } 765 else 766 SCARG(&ap, buf) = NULL; 767 768 769 switch (SCARG(uap, cmd)) { 770 case SVR4_IPC_STAT: 771 SCARG(&ap, cmd) = IPC_STAT; 772 if ((error = sys_shmctl(p, &ap, retval)) != 0) 773 return error; 774 if (SCARG(uap, buf) == NULL) 775 return 0; 776 error = copyin(&bs, SCARG(&ap, buf), sizeof bs); 777 if (error) 778 return error; 779 bsd_to_svr4_shmid_ds(&bs, &ss); 780 return copyout(&ss, SCARG(uap, buf), sizeof ss); 781 782 case SVR4_IPC_SET: 783 SCARG(&ap, cmd) = IPC_SET; 784 return sys_shmctl(p, &ap, retval); 785 786 case SVR4_IPC_RMID: 787 case SVR4_SHM_LOCK: 788 case SVR4_SHM_UNLOCK: 789 switch (SCARG(uap, cmd)) { 790 case SVR4_IPC_RMID: 791 SCARG(&ap, cmd) = IPC_RMID; 792 break; 793 case SVR4_SHM_LOCK: 794 SCARG(&ap, cmd) = SHM_LOCK; 795 break; 796 case SVR4_SHM_UNLOCK: 797 SCARG(&ap, cmd) = SHM_UNLOCK; 798 break; 799 default: 800 return EINVAL; 801 } 802 return sys_shmctl(p, &ap, retval); 803 804 default: 805 return EINVAL; 806 } 807} 808 809int 810svr4_sys_shmsys(p, v, retval) 811 struct proc *p; 812 void *v; 813 register_t *retval; 814{ 815 struct svr4_sys_shmsys_args *uap = v; 816 817 DPRINTF(("svr4_shmsys(%d)\n", SCARG(uap, what))); 818 819 switch (SCARG(uap, what)) { 820 case SVR4_shmat: 821 return svr4_shmat(p, v, retval); 822 case SVR4_shmdt: 823 return svr4_shmdt(p, v, retval); 824 case SVR4_shmget: 825 return svr4_shmget(p, v, retval); 826 case SVR4_shmctl: 827 return svr4_shmctl(p, v, retval); 828 default: 829 return ENOSYS; 830 } 831} 832#endif /* SYSVSHM */ 833