svr4_ipc.c revision 259065
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: releng/10.0/sys/compat/svr4/svr4_ipc.c 225617 2011-09-16 13:58:51Z kmacy $"); 75 76#include "opt_sysvipc.h" 77 78#include <sys/param.h> 79#include <sys/ipc.h> 80#include <sys/msg.h> 81#include <sys/proc.h> 82#include <sys/sem.h> 83#include <sys/shm.h> 84#include <sys/syscallsubr.h> 85#include <sys/sysproto.h> 86#include <sys/systm.h> 87#include <sys/time.h> 88 89#include <compat/svr4/svr4.h> 90#include <compat/svr4/svr4_types.h> 91#include <compat/svr4/svr4_signal.h> 92#include <compat/svr4/svr4_proto.h> 93#include <compat/svr4/svr4_util.h> 94#include <compat/svr4/svr4_ipc.h> 95 96#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM) 97static void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *, 98 struct ipc_perm *); 99static void bsd_to_svr4_ipc_perm(const struct ipc_perm *, 100 struct svr4_ipc_perm *); 101#endif 102 103#ifdef SYSVSEM 104static void bsd_to_svr4_semid_ds(const struct semid_ds *, 105 struct svr4_semid_ds *); 106static void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *, 107 struct semid_ds *); 108static int svr4_semop(struct thread *, void *); 109static int svr4_semget(struct thread *, void *); 110static int svr4_semctl(struct thread *, void *); 111#endif 112 113#ifdef SYSVMSG 114static void bsd_to_svr4_msqid_ds(const struct msqid_ds *, 115 struct svr4_msqid_ds *); 116static void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *, 117 struct msqid_ds *); 118static int svr4_msgsnd(struct thread *, void *); 119static int svr4_msgrcv(struct thread *, void *); 120static int svr4_msgget(struct thread *, void *); 121static int svr4_msgctl(struct thread *, void *); 122#endif 123 124#ifdef SYSVSHM 125static void bsd_to_svr4_shmid_ds(const struct shmid_ds *, 126 struct svr4_shmid_ds *); 127static void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *, 128 struct shmid_ds *); 129static int svr4_shmat(struct thread *, void *); 130static int svr4_shmdt(struct thread *, void *); 131static int svr4_shmget(struct thread *, void *); 132static int svr4_shmctl(struct thread *, void *); 133#endif 134 135#if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM) 136 137static void 138svr4_to_bsd_ipc_perm(spp, bpp) 139 const struct svr4_ipc_perm *spp; 140 struct ipc_perm *bpp; 141{ 142 bpp->key = spp->key; 143 bpp->uid = spp->uid; 144 bpp->gid = spp->gid; 145 bpp->cuid = spp->cuid; 146 bpp->cgid = spp->cgid; 147 bpp->mode = spp->mode; 148 bpp->seq = spp->seq; 149} 150 151static void 152bsd_to_svr4_ipc_perm(bpp, spp) 153 const struct ipc_perm *bpp; 154 struct svr4_ipc_perm *spp; 155{ 156 spp->key = bpp->key; 157 spp->uid = bpp->uid; 158 spp->gid = bpp->gid; 159 spp->cuid = bpp->cuid; 160 spp->cgid = bpp->cgid; 161 spp->mode = bpp->mode; 162 spp->seq = bpp->seq; 163} 164#endif 165 166#ifdef SYSVSEM 167static void 168bsd_to_svr4_semid_ds(bds, sds) 169 const struct semid_ds *bds; 170 struct svr4_semid_ds *sds; 171{ 172 bzero(sds, sizeof(*sds)); 173 bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm); 174 sds->sem_base = (struct svr4_sem *) bds->sem_base; 175 sds->sem_nsems = bds->sem_nsems; 176 sds->sem_otime = bds->sem_otime; 177 sds->sem_ctime = bds->sem_ctime; 178} 179 180static void 181svr4_to_bsd_semid_ds(sds, bds) 182 const struct svr4_semid_ds *sds; 183 struct semid_ds *bds; 184{ 185 svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm); 186 bds->sem_base = (struct sem *) bds->sem_base; 187 bds->sem_nsems = sds->sem_nsems; 188 bds->sem_otime = sds->sem_otime; 189 bds->sem_ctime = sds->sem_ctime; 190} 191 192struct svr4_sys_semctl_args { 193 int what; 194 int semid; 195 int semnum; 196 int cmd; 197 union semun arg; 198}; 199 200static int 201svr4_semctl(td, v) 202 struct thread *td; 203 void *v; 204{ 205 struct svr4_sys_semctl_args *uap = v; 206 struct svr4_semid_ds ss; 207 struct semid_ds bs; 208 union semun semun; 209 register_t rval; 210 int cmd, error; 211 212 switch (uap->cmd) { 213 case SVR4_SEM_GETZCNT: 214 cmd = GETZCNT; 215 break; 216 217 case SVR4_SEM_GETNCNT: 218 cmd = GETNCNT; 219 break; 220 221 case SVR4_SEM_GETPID: 222 cmd = GETPID; 223 break; 224 225 case SVR4_SEM_GETVAL: 226 cmd = GETVAL; 227 break; 228 229 case SVR4_SEM_SETVAL: 230 cmd = SETVAL; 231 break; 232 233 case SVR4_SEM_GETALL: 234 cmd = GETVAL; 235 break; 236 237 case SVR4_SEM_SETALL: 238 cmd = SETVAL; 239 break; 240 241 case SVR4_IPC_STAT: 242 cmd = IPC_STAT; 243 semun.buf = &bs; 244 error = kern_semctl(td, uap->semid, uap->semnum, cmd, &semun, 245 &rval); 246 if (error) 247 return (error); 248 bsd_to_svr4_semid_ds(&bs, &ss); 249 error = copyout(&ss, uap->arg.buf, sizeof(ss)); 250 if (error == 0) 251 td->td_retval[0] = rval; 252 return (error); 253 254 case SVR4_IPC_SET: 255 cmd = IPC_SET; 256 error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss); 257 if (error) 258 return (error); 259 svr4_to_bsd_semid_ds(&ss, &bs); 260 semun.buf = &bs; 261 return (kern_semctl(td, uap->semid, uap->semnum, cmd, &semun, 262 td->td_retval)); 263 264 case SVR4_IPC_RMID: 265 cmd = IPC_RMID; 266 break; 267 268 default: 269 return EINVAL; 270 } 271 272 return (kern_semctl(td, uap->semid, uap->semnum, cmd, &uap->arg, 273 td->td_retval)); 274} 275 276struct svr4_sys_semget_args { 277 int what; 278 svr4_key_t key; 279 int nsems; 280 int semflg; 281}; 282 283static int 284svr4_semget(td, v) 285 struct thread *td; 286 void *v; 287{ 288 struct svr4_sys_semget_args *uap = v; 289 struct semget_args ap; 290 291 ap.key = uap->key; 292 ap.nsems = uap->nsems; 293 ap.semflg = uap->semflg; 294 295 return sys_semget(td, &ap); 296} 297 298struct svr4_sys_semop_args { 299 int what; 300 int semid; 301 struct svr4_sembuf * sops; 302 u_int nsops; 303}; 304 305static int 306svr4_semop(td, v) 307 struct thread *td; 308 void *v; 309{ 310 struct svr4_sys_semop_args *uap = v; 311 struct semop_args ap; 312 313 ap.semid = uap->semid; 314 /* These are the same */ 315 ap.sops = (struct sembuf *) uap->sops; 316 ap.nsops = uap->nsops; 317 318 return sys_semop(td, &ap); 319} 320 321int 322svr4_sys_semsys(td, uap) 323 struct thread *td; 324 struct svr4_sys_semsys_args *uap; 325{ 326 327 DPRINTF(("svr4_semsys(%d)\n", uap->what)); 328 329 switch (uap->what) { 330 case SVR4_semctl: 331 return svr4_semctl(td, uap); 332 case SVR4_semget: 333 return svr4_semget(td, uap); 334 case SVR4_semop: 335 return svr4_semop(td, uap); 336 default: 337 return EINVAL; 338 } 339} 340 341MODULE_DEPEND(svr4elf, sysvsem, 1, 1, 1); 342#endif 343 344#ifdef SYSVMSG 345static void 346bsd_to_svr4_msqid_ds(bds, sds) 347 const struct msqid_ds *bds; 348 struct svr4_msqid_ds *sds; 349{ 350 bzero(sds, sizeof(*sds)); 351 bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm); 352 sds->msg_first = (struct svr4_msg *) bds->msg_first; 353 sds->msg_last = (struct svr4_msg *) bds->msg_last; 354 sds->msg_cbytes = bds->msg_cbytes; 355 sds->msg_qnum = bds->msg_qnum; 356 sds->msg_qbytes = bds->msg_qbytes; 357 sds->msg_lspid = bds->msg_lspid; 358 sds->msg_lrpid = bds->msg_lrpid; 359 sds->msg_stime = bds->msg_stime; 360 sds->msg_rtime = bds->msg_rtime; 361 sds->msg_ctime = bds->msg_ctime; 362} 363 364static void 365svr4_to_bsd_msqid_ds(sds, bds) 366 const struct svr4_msqid_ds *sds; 367 struct msqid_ds *bds; 368{ 369 svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm); 370 bds->msg_first = (struct msg *) sds->msg_first; 371 bds->msg_last = (struct msg *) sds->msg_last; 372 bds->msg_cbytes = sds->msg_cbytes; 373 bds->msg_qnum = sds->msg_qnum; 374 bds->msg_qbytes = sds->msg_qbytes; 375 bds->msg_lspid = sds->msg_lspid; 376 bds->msg_lrpid = sds->msg_lrpid; 377 bds->msg_stime = sds->msg_stime; 378 bds->msg_rtime = sds->msg_rtime; 379 bds->msg_ctime = sds->msg_ctime; 380} 381 382struct svr4_sys_msgsnd_args { 383 int what; 384 int msqid; 385 void * msgp; 386 size_t msgsz; 387 int msgflg; 388}; 389 390static int 391svr4_msgsnd(td, v) 392 struct thread *td; 393 void *v; 394{ 395 struct svr4_sys_msgsnd_args *uap = v; 396 struct msgsnd_args ap; 397 398 ap.msqid = uap->msqid; 399 ap.msgp = uap->msgp; 400 ap.msgsz = uap->msgsz; 401 ap.msgflg = uap->msgflg; 402 403 return sys_msgsnd(td, &ap); 404} 405 406struct svr4_sys_msgrcv_args { 407 int what; 408 int msqid; 409 void * msgp; 410 size_t msgsz; 411 long msgtyp; 412 int msgflg; 413}; 414 415static int 416svr4_msgrcv(td, v) 417 struct thread *td; 418 void *v; 419{ 420 struct svr4_sys_msgrcv_args *uap = v; 421 struct msgrcv_args ap; 422 423 ap.msqid = uap->msqid; 424 ap.msgp = uap->msgp; 425 ap.msgsz = uap->msgsz; 426 ap.msgtyp = uap->msgtyp; 427 ap.msgflg = uap->msgflg; 428 429 return sys_msgrcv(td, &ap); 430} 431 432struct svr4_sys_msgget_args { 433 int what; 434 svr4_key_t key; 435 int msgflg; 436}; 437 438static int 439svr4_msgget(td, v) 440 struct thread *td; 441 void *v; 442{ 443 struct svr4_sys_msgget_args *uap = v; 444 struct msgget_args ap; 445 446 ap.key = uap->key; 447 ap.msgflg = uap->msgflg; 448 449 return sys_msgget(td, &ap); 450} 451 452struct svr4_sys_msgctl_args { 453 int what; 454 int msqid; 455 int cmd; 456 struct svr4_msqid_ds * buf; 457}; 458 459static int 460svr4_msgctl(td, v) 461 struct thread *td; 462 void *v; 463{ 464 struct svr4_sys_msgctl_args *uap = v; 465 struct svr4_msqid_ds ss; 466 struct msqid_ds bs; 467 int error; 468 469 switch (uap->cmd) { 470 case SVR4_IPC_STAT: 471 error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs); 472 if (error) 473 return error; 474 bsd_to_svr4_msqid_ds(&bs, &ss); 475 return copyout(&ss, uap->buf, sizeof ss); 476 477 case SVR4_IPC_SET: 478 error = copyin(uap->buf, &ss, sizeof ss); 479 if (error) 480 return error; 481 svr4_to_bsd_msqid_ds(&ss, &bs); 482 return (kern_msgctl(td, uap->msqid, IPC_SET, &bs)); 483 484 case SVR4_IPC_RMID: 485 return (kern_msgctl(td, uap->msqid, IPC_RMID, NULL)); 486 487 default: 488 return EINVAL; 489 } 490} 491 492int 493svr4_sys_msgsys(td, uap) 494 struct thread *td; 495 struct svr4_sys_msgsys_args *uap; 496{ 497 498 DPRINTF(("svr4_msgsys(%d)\n", uap->what)); 499 500 switch (uap->what) { 501 case SVR4_msgsnd: 502 return svr4_msgsnd(td, uap); 503 case SVR4_msgrcv: 504 return svr4_msgrcv(td, uap); 505 case SVR4_msgget: 506 return svr4_msgget(td, uap); 507 case SVR4_msgctl: 508 return svr4_msgctl(td, uap); 509 default: 510 return EINVAL; 511 } 512} 513 514MODULE_DEPEND(svr4elf, sysvmsg, 1, 1, 1); 515#endif 516 517#ifdef SYSVSHM 518 519static void 520bsd_to_svr4_shmid_ds(bds, sds) 521 const struct shmid_ds *bds; 522 struct svr4_shmid_ds *sds; 523{ 524 bzero(sds, sizeof(*sds)); 525 bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm); 526 sds->shm_segsz = bds->shm_segsz; 527 sds->shm_lkcnt = 0; 528 sds->shm_lpid = bds->shm_lpid; 529 sds->shm_cpid = bds->shm_cpid; 530 sds->shm_amp = 0; 531 sds->shm_nattch = bds->shm_nattch; 532 sds->shm_cnattch = 0; 533 sds->shm_atime = bds->shm_atime; 534 sds->shm_dtime = bds->shm_dtime; 535 sds->shm_ctime = bds->shm_ctime; 536} 537 538static void 539svr4_to_bsd_shmid_ds(sds, bds) 540 const struct svr4_shmid_ds *sds; 541 struct shmid_ds *bds; 542{ 543 svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm); 544 bds->shm_segsz = sds->shm_segsz; 545 bds->shm_lpid = sds->shm_lpid; 546 bds->shm_cpid = sds->shm_cpid; 547 bds->shm_nattch = sds->shm_nattch; 548 bds->shm_atime = sds->shm_atime; 549 bds->shm_dtime = sds->shm_dtime; 550 bds->shm_ctime = sds->shm_ctime; 551} 552 553struct svr4_sys_shmat_args { 554 int what; 555 int shmid; 556 void * shmaddr; 557 int shmflg; 558}; 559 560static int 561svr4_shmat(td, v) 562 struct thread *td; 563 void *v; 564{ 565 struct svr4_sys_shmat_args *uap = v; 566 struct shmat_args ap; 567 568 ap.shmid = uap->shmid; 569 ap.shmaddr = uap->shmaddr; 570 ap.shmflg = uap->shmflg; 571 572 return sys_shmat(td, &ap); 573} 574 575struct svr4_sys_shmdt_args { 576 int what; 577 void * shmaddr; 578}; 579 580static int 581svr4_shmdt(td, v) 582 struct thread *td; 583 void *v; 584{ 585 struct svr4_sys_shmdt_args *uap = v; 586 struct shmdt_args ap; 587 588 ap.shmaddr = uap->shmaddr; 589 590 return sys_shmdt(td, &ap); 591} 592 593struct svr4_sys_shmget_args { 594 int what; 595 key_t key; 596 int size; 597 int shmflg; 598}; 599 600static int 601svr4_shmget(td, v) 602 struct thread *td; 603 void *v; 604{ 605 struct svr4_sys_shmget_args *uap = v; 606 struct shmget_args ap; 607 608 ap.key = uap->key; 609 ap.size = uap->size; 610 ap.shmflg = uap->shmflg; 611 612 return sys_shmget(td, &ap); 613} 614 615struct svr4_sys_shmctl_args { 616 int what; 617 int shmid; 618 int cmd; 619 struct svr4_shmid_ds * buf; 620}; 621 622int 623svr4_shmctl(td, v) 624 struct thread *td; 625 void *v; 626{ 627 struct svr4_sys_shmctl_args *uap = v; 628 struct shmid_ds bs; 629 struct svr4_shmid_ds ss; 630 size_t bufsize; 631 int cmd, error; 632 633 if (uap->buf != NULL) { 634 switch (uap->cmd) { 635 case SVR4_IPC_SET: 636 case SVR4_SHM_LOCK: 637 case SVR4_SHM_UNLOCK: 638 error = copyin(uap->buf, &ss, sizeof(ss)); 639 if (error) 640 return (error); 641 svr4_to_bsd_shmid_ds(&ss, &bs); 642 break; 643 default: 644 return (EINVAL); 645 } 646 } 647 648 switch (uap->cmd) { 649 case SVR4_IPC_STAT: 650 cmd = IPC_STAT; 651 break; 652 case SVR4_IPC_SET: 653 cmd = IPC_SET; 654 break; 655 case SVR4_IPC_RMID: 656 cmd = IPC_RMID; 657 break; 658 case SVR4_SHM_LOCK: 659 cmd = SHM_LOCK; 660 break; 661 case SVR4_SHM_UNLOCK: 662 cmd = SHM_UNLOCK; 663 break; 664 default: 665 return (EINVAL); 666 } 667 668 error = kern_shmctl(td, uap->shmid, cmd, &bs, &bufsize); 669 if (error) 670 return (error); 671 672 switch (uap->cmd) { 673 case SVR4_IPC_STAT: 674 if (uap->buf != NULL) { 675 bsd_to_svr4_shmid_ds(&bs, &ss); 676 error = copyout(&ss, uap->buf, sizeof(ss)); 677 } 678 break; 679 } 680 681 return (error); 682} 683 684int 685svr4_sys_shmsys(td, uap) 686 struct thread *td; 687 struct svr4_sys_shmsys_args *uap; 688{ 689 690 DPRINTF(("svr4_shmsys(%d)\n", uap->what)); 691 692 switch (uap->what) { 693 case SVR4_shmat: 694 return svr4_shmat(td, uap); 695 case SVR4_shmdt: 696 return svr4_shmdt(td, uap); 697 case SVR4_shmget: 698 return svr4_shmget(td, uap); 699 case SVR4_shmctl: 700 return svr4_shmctl(td, uap); 701 default: 702 return ENOSYS; 703 } 704} 705 706MODULE_DEPEND(svr4elf, sysvshm, 1, 1, 1); 707#endif /* SYSVSHM */ 708