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