sysv_msg.c (100511) | sysv_msg.c (100523) |
---|---|
1/* $FreeBSD: head/sys/kern/sysv_msg.c 100511 2002-07-22 16:12:55Z alfred $ */ | 1/* $FreeBSD: head/sys/kern/sysv_msg.c 100523 2002-07-22 18:27:54Z alfred $ */ |
2 3/* 4 * Implementation of SVID messages 5 * 6 * Author: Daniel Boulet 7 * 8 * Copyright 1993 Daniel Boulet and RTMX Inc. 9 * --- 26 unchanged lines hidden (view full) --- 36#include <sys/jail.h> 37 38static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues"); 39 40static void msginit(void); 41static int msgunload(void); 42static int sysvmsg_modload(struct module *, int, void *); 43 | 2 3/* 4 * Implementation of SVID messages 5 * 6 * Author: Daniel Boulet 7 * 8 * Copyright 1993 Daniel Boulet and RTMX Inc. 9 * --- 26 unchanged lines hidden (view full) --- 36#include <sys/jail.h> 37 38static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues"); 39 40static void msginit(void); 41static int msgunload(void); 42static int sysvmsg_modload(struct module *, int, void *); 43 |
44#define MSG_DEBUG 45#undef MSG_DEBUG_OK | 44#ifdef MSG_DEBUG 45#define DPRINTF(a) printf a 46#else 47#define DPRINTF(a) 48#endif |
46 47static void msg_freehdr(struct msg *msghdr); 48 49/* XXX casting to (sy_call_t *) is bogus, as usual. */ 50static sy_call_t *msgcalls[] = { 51 (sy_call_t *)msgctl, (sy_call_t *)msgget, 52 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv 53}; --- 101 unchanged lines hidden (view full) --- 155 * It is also pretty silly if msginfo.msgssz is less than 8 156 * or greater than about 256 so ... 157 */ 158 159 i = 8; 160 while (i < 1024 && i != msginfo.msgssz) 161 i <<= 1; 162 if (i != msginfo.msgssz) { | 49 50static void msg_freehdr(struct msg *msghdr); 51 52/* XXX casting to (sy_call_t *) is bogus, as usual. */ 53static sy_call_t *msgcalls[] = { 54 (sy_call_t *)msgctl, (sy_call_t *)msgget, 55 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv 56}; --- 101 unchanged lines hidden (view full) --- 158 * It is also pretty silly if msginfo.msgssz is less than 8 159 * or greater than about 256 so ... 160 */ 161 162 i = 8; 163 while (i < 1024 && i != msginfo.msgssz) 164 i <<= 1; 165 if (i != msginfo.msgssz) { |
163 printf("msginfo.msgssz=%d (0x%x)\n", msginfo.msgssz, 164 msginfo.msgssz); | 166 DPRINTF(("msginfo.msgssz=%d (0x%x)\n", msginfo.msgssz, 167 msginfo.msgssz)); |
165 panic("msginfo.msgssz not a small power of 2"); 166 } 167 168 if (msginfo.msgseg > 32767) { | 168 panic("msginfo.msgssz not a small power of 2"); 169 } 170 171 if (msginfo.msgseg > 32767) { |
169 printf("msginfo.msgseg=%d\n", msginfo.msgseg); | 172 DPRINTF(("msginfo.msgseg=%d\n", msginfo.msgseg)); |
170 panic("msginfo.msgseg > 32767"); 171 } 172 173 if (msgmaps == NULL) 174 panic("msgmaps is NULL"); 175 176 for (i = 0; i < msginfo.msgseg; i++) { 177 if (i > 0) --- 162 unchanged lines hidden (view full) --- 340{ 341 int msqid = uap->msqid; 342 int cmd = uap->cmd; 343 struct msqid_ds *user_msqptr = uap->buf; 344 int rval, error; 345 struct msqid_ds msqbuf; 346 register struct msqid_ds *msqptr; 347 | 173 panic("msginfo.msgseg > 32767"); 174 } 175 176 if (msgmaps == NULL) 177 panic("msgmaps is NULL"); 178 179 for (i = 0; i < msginfo.msgseg; i++) { 180 if (i > 0) --- 162 unchanged lines hidden (view full) --- 343{ 344 int msqid = uap->msqid; 345 int cmd = uap->cmd; 346 struct msqid_ds *user_msqptr = uap->buf; 347 int rval, error; 348 struct msqid_ds msqbuf; 349 register struct msqid_ds *msqptr; 350 |
348#ifdef MSG_DEBUG_OK 349 printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr); 350#endif | 351 DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr)); |
351 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 352 return (ENOSYS); 353 354 mtx_lock(&Giant); 355 msqid = IPCID_TO_IX(msqid); 356 357 if (msqid < 0 || msqid >= msginfo.msgmni) { | 352 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 353 return (ENOSYS); 354 355 mtx_lock(&Giant); 356 msqid = IPCID_TO_IX(msqid); 357 358 if (msqid < 0 || msqid >= msginfo.msgmni) { |
358#ifdef MSG_DEBUG_OK 359 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, 360 msginfo.msgmni); 361#endif | 359 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid, 360 msginfo.msgmni)); |
362 error = EINVAL; 363 goto done2; 364 } 365 366 msqptr = &msqids[msqid]; 367 368 if (msqptr->msg_qbytes == 0) { | 361 error = EINVAL; 362 goto done2; 363 } 364 365 msqptr = &msqids[msqid]; 366 367 if (msqptr->msg_qbytes == 0) { |
369#ifdef MSG_DEBUG_OK 370 printf("no such msqid\n"); 371#endif | 368 DPRINTF(("no such msqid\n")); |
372 error = EINVAL; 373 goto done2; 374 } 375 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { | 369 error = EINVAL; 370 goto done2; 371 } 372 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { |
376#ifdef MSG_DEBUG_OK 377 printf("wrong sequence number\n"); 378#endif | 373 DPRINTF(("wrong sequence number\n")); |
379 error = EINVAL; 380 goto done2; 381 } 382 383 error = 0; 384 rval = 0; 385 386 switch (cmd) { --- 34 unchanged lines hidden (view full) --- 421 if ((error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0) 422 goto done2; 423 if (msqbuf.msg_qbytes > msqptr->msg_qbytes) { 424 error = suser(td); 425 if (error) 426 goto done2; 427 } 428 if (msqbuf.msg_qbytes > msginfo.msgmnb) { | 374 error = EINVAL; 375 goto done2; 376 } 377 378 error = 0; 379 rval = 0; 380 381 switch (cmd) { --- 34 unchanged lines hidden (view full) --- 416 if ((error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0) 417 goto done2; 418 if (msqbuf.msg_qbytes > msqptr->msg_qbytes) { 419 error = suser(td); 420 if (error) 421 goto done2; 422 } 423 if (msqbuf.msg_qbytes > msginfo.msgmnb) { |
429#ifdef MSG_DEBUG_OK 430 printf("can't increase msg_qbytes beyond %d (truncating)\n", 431 msginfo.msgmnb); 432#endif | 424 DPRINTF(("can't increase msg_qbytes beyond %d" 425 "(truncating)\n", msginfo.msgmnb)); |
433 msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */ 434 } 435 if (msqbuf.msg_qbytes == 0) { | 426 msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */ 427 } 428 if (msqbuf.msg_qbytes == 0) { |
436#ifdef MSG_DEBUG_OK 437 printf("can't reduce msg_qbytes to 0\n"); 438#endif | 429 DPRINTF(("can't reduce msg_qbytes to 0\n")); |
439 error = EINVAL; /* non-standard errno! */ 440 goto done2; 441 } 442 msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */ 443 msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */ 444 msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) | 445 (msqbuf.msg_perm.mode & 0777); 446 msqptr->msg_qbytes = msqbuf.msg_qbytes; 447 msqptr->msg_ctime = time_second; 448 break; 449 450 case IPC_STAT: 451 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) { | 430 error = EINVAL; /* non-standard errno! */ 431 goto done2; 432 } 433 msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */ 434 msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */ 435 msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) | 436 (msqbuf.msg_perm.mode & 0777); 437 msqptr->msg_qbytes = msqbuf.msg_qbytes; 438 msqptr->msg_ctime = time_second; 439 break; 440 441 case IPC_STAT: 442 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) { |
452#ifdef MSG_DEBUG_OK 453 printf("requester doesn't have read access\n"); 454#endif | 443 DPRINTF(("requester doesn't have read access\n")); |
455 goto done2; 456 } 457 error = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds)); 458 break; 459 460 default: | 444 goto done2; 445 } 446 error = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds)); 447 break; 448 449 default: |
461#ifdef MSG_DEBUG_OK 462 printf("invalid command %d\n", cmd); 463#endif | 450 DPRINTF(("invalid command %d\n", cmd)); |
464 error = EINVAL; 465 goto done2; 466 } 467 468 if (error == 0) 469 td->td_retval[0] = rval; 470done2: 471 mtx_unlock(&Giant); --- 16 unchanged lines hidden (view full) --- 488 register struct msgget_args *uap; 489{ 490 int msqid, error = 0; 491 int key = uap->key; 492 int msgflg = uap->msgflg; 493 struct ucred *cred = td->td_ucred; 494 register struct msqid_ds *msqptr = NULL; 495 | 451 error = EINVAL; 452 goto done2; 453 } 454 455 if (error == 0) 456 td->td_retval[0] = rval; 457done2: 458 mtx_unlock(&Giant); --- 16 unchanged lines hidden (view full) --- 475 register struct msgget_args *uap; 476{ 477 int msqid, error = 0; 478 int key = uap->key; 479 int msgflg = uap->msgflg; 480 struct ucred *cred = td->td_ucred; 481 register struct msqid_ds *msqptr = NULL; 482 |
496#ifdef MSG_DEBUG_OK 497 printf("msgget(0x%x, 0%o)\n", key, msgflg); 498#endif | 483 DPRINTF(("msgget(0x%x, 0%o)\n", key, msgflg)); |
499 500 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 501 return (ENOSYS); 502 503 mtx_lock(&Giant); 504 if (key != IPC_PRIVATE) { 505 for (msqid = 0; msqid < msginfo.msgmni; msqid++) { 506 msqptr = &msqids[msqid]; 507 if (msqptr->msg_qbytes != 0 && 508 msqptr->msg_perm.key == key) 509 break; 510 } 511 if (msqid < msginfo.msgmni) { | 484 485 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 486 return (ENOSYS); 487 488 mtx_lock(&Giant); 489 if (key != IPC_PRIVATE) { 490 for (msqid = 0; msqid < msginfo.msgmni; msqid++) { 491 msqptr = &msqids[msqid]; 492 if (msqptr->msg_qbytes != 0 && 493 msqptr->msg_perm.key == key) 494 break; 495 } 496 if (msqid < msginfo.msgmni) { |
512#ifdef MSG_DEBUG_OK 513 printf("found public key\n"); 514#endif | 497 DPRINTF(("found public key\n")); |
515 if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) { | 498 if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) { |
516#ifdef MSG_DEBUG_OK 517 printf("not exclusive\n"); 518#endif | 499 DPRINTF(("not exclusive\n")); |
519 error = EEXIST; 520 goto done2; 521 } 522 if ((error = ipcperm(td, &msqptr->msg_perm, msgflg & 0700 ))) { | 500 error = EEXIST; 501 goto done2; 502 } 503 if ((error = ipcperm(td, &msqptr->msg_perm, msgflg & 0700 ))) { |
523#ifdef MSG_DEBUG_OK 524 printf("requester doesn't have 0%o access\n", 525 msgflg & 0700); 526#endif | 504 DPRINTF(("requester doesn't have 0%o access\n", 505 msgflg & 0700)); |
527 goto done2; 528 } 529 goto found; 530 } 531 } 532 | 506 goto done2; 507 } 508 goto found; 509 } 510 } 511 |
533#ifdef MSG_DEBUG_OK 534 printf("need to allocate the msqid_ds\n"); 535#endif | 512 DPRINTF(("need to allocate the msqid_ds\n")); |
536 if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) { 537 for (msqid = 0; msqid < msginfo.msgmni; msqid++) { 538 /* 539 * Look for an unallocated and unlocked msqid_ds. 540 * msqid_ds's can be locked by msgsnd or msgrcv while 541 * they are copying the message in/out. We can't 542 * re-use the entry until they release it. 543 */ 544 msqptr = &msqids[msqid]; 545 if (msqptr->msg_qbytes == 0 && 546 (msqptr->msg_perm.mode & MSG_LOCKED) == 0) 547 break; 548 } 549 if (msqid == msginfo.msgmni) { | 513 if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) { 514 for (msqid = 0; msqid < msginfo.msgmni; msqid++) { 515 /* 516 * Look for an unallocated and unlocked msqid_ds. 517 * msqid_ds's can be locked by msgsnd or msgrcv while 518 * they are copying the message in/out. We can't 519 * re-use the entry until they release it. 520 */ 521 msqptr = &msqids[msqid]; 522 if (msqptr->msg_qbytes == 0 && 523 (msqptr->msg_perm.mode & MSG_LOCKED) == 0) 524 break; 525 } 526 if (msqid == msginfo.msgmni) { |
550#ifdef MSG_DEBUG_OK 551 printf("no more msqid_ds's available\n"); 552#endif | 527 DPRINTF(("no more msqid_ds's available\n")); |
553 error = ENOSPC; 554 goto done2; 555 } | 528 error = ENOSPC; 529 goto done2; 530 } |
556#ifdef MSG_DEBUG_OK 557 printf("msqid %d is available\n", msqid); 558#endif | 531 DPRINTF(("msqid %d is available\n", msqid)); |
559 msqptr->msg_perm.key = key; 560 msqptr->msg_perm.cuid = cred->cr_uid; 561 msqptr->msg_perm.uid = cred->cr_uid; 562 msqptr->msg_perm.cgid = cred->cr_gid; 563 msqptr->msg_perm.gid = cred->cr_gid; 564 msqptr->msg_perm.mode = (msgflg & 0777); 565 /* Make sure that the returned msqid is unique */ 566 msqptr->msg_perm.seq++; 567 msqptr->msg_first = NULL; 568 msqptr->msg_last = NULL; 569 msqptr->msg_cbytes = 0; 570 msqptr->msg_qnum = 0; 571 msqptr->msg_qbytes = msginfo.msgmnb; 572 msqptr->msg_lspid = 0; 573 msqptr->msg_lrpid = 0; 574 msqptr->msg_stime = 0; 575 msqptr->msg_rtime = 0; 576 msqptr->msg_ctime = time_second; 577 } else { | 532 msqptr->msg_perm.key = key; 533 msqptr->msg_perm.cuid = cred->cr_uid; 534 msqptr->msg_perm.uid = cred->cr_uid; 535 msqptr->msg_perm.cgid = cred->cr_gid; 536 msqptr->msg_perm.gid = cred->cr_gid; 537 msqptr->msg_perm.mode = (msgflg & 0777); 538 /* Make sure that the returned msqid is unique */ 539 msqptr->msg_perm.seq++; 540 msqptr->msg_first = NULL; 541 msqptr->msg_last = NULL; 542 msqptr->msg_cbytes = 0; 543 msqptr->msg_qnum = 0; 544 msqptr->msg_qbytes = msginfo.msgmnb; 545 msqptr->msg_lspid = 0; 546 msqptr->msg_lrpid = 0; 547 msqptr->msg_stime = 0; 548 msqptr->msg_rtime = 0; 549 msqptr->msg_ctime = time_second; 550 } else { |
578#ifdef MSG_DEBUG_OK 579 printf("didn't find it and wasn't asked to create it\n"); 580#endif | 551 DPRINTF(("didn't find it and wasn't asked to create it\n")); |
581 error = ENOENT; 582 goto done2; 583 } 584 585found: 586 /* Construct the unique msqid */ 587 td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); 588done2: --- 22 unchanged lines hidden (view full) --- 611 void *user_msgp = uap->msgp; 612 size_t msgsz = uap->msgsz; 613 int msgflg = uap->msgflg; 614 int segs_needed, error = 0; 615 register struct msqid_ds *msqptr; 616 register struct msg *msghdr; 617 short next; 618 | 552 error = ENOENT; 553 goto done2; 554 } 555 556found: 557 /* Construct the unique msqid */ 558 td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); 559done2: --- 22 unchanged lines hidden (view full) --- 582 void *user_msgp = uap->msgp; 583 size_t msgsz = uap->msgsz; 584 int msgflg = uap->msgflg; 585 int segs_needed, error = 0; 586 register struct msqid_ds *msqptr; 587 register struct msg *msghdr; 588 short next; 589 |
619#ifdef MSG_DEBUG_OK 620 printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz, 621 msgflg); 622#endif | 590 DPRINTF(("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz, 591 msgflg)); |
623 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 624 return (ENOSYS); 625 626 mtx_lock(&Giant); 627 msqid = IPCID_TO_IX(msqid); 628 629 if (msqid < 0 || msqid >= msginfo.msgmni) { | 592 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 593 return (ENOSYS); 594 595 mtx_lock(&Giant); 596 msqid = IPCID_TO_IX(msqid); 597 598 if (msqid < 0 || msqid >= msginfo.msgmni) { |
630#ifdef MSG_DEBUG_OK 631 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, 632 msginfo.msgmni); 633#endif | 599 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid, 600 msginfo.msgmni)); |
634 error = EINVAL; 635 goto done2; 636 } 637 638 msqptr = &msqids[msqid]; 639 if (msqptr->msg_qbytes == 0) { | 601 error = EINVAL; 602 goto done2; 603 } 604 605 msqptr = &msqids[msqid]; 606 if (msqptr->msg_qbytes == 0) { |
640#ifdef MSG_DEBUG_OK 641 printf("no such message queue id\n"); 642#endif | 607 DPRINTF(("no such message queue id\n")); |
643 error = EINVAL; 644 goto done2; 645 } 646 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { | 608 error = EINVAL; 609 goto done2; 610 } 611 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { |
647#ifdef MSG_DEBUG_OK 648 printf("wrong sequence number\n"); 649#endif | 612 DPRINTF(("wrong sequence number\n")); |
650 error = EINVAL; 651 goto done2; 652 } 653 654 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_W))) { | 613 error = EINVAL; 614 goto done2; 615 } 616 617 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_W))) { |
655#ifdef MSG_DEBUG_OK 656 printf("requester doesn't have write access\n"); 657#endif | 618 DPRINTF(("requester doesn't have write access\n")); |
658 goto done2; 659 } 660 661 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; | 619 goto done2; 620 } 621 622 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; |
662#ifdef MSG_DEBUG_OK 663 printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz, 664 segs_needed); 665#endif | 623 DPRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz, 624 segs_needed)); |
666 for (;;) { 667 int need_more_resources = 0; 668 669 /* 670 * check msgsz 671 * (inside this loop in case msg_qbytes changes while we sleep) 672 */ 673 674 if (msgsz > msqptr->msg_qbytes) { | 625 for (;;) { 626 int need_more_resources = 0; 627 628 /* 629 * check msgsz 630 * (inside this loop in case msg_qbytes changes while we sleep) 631 */ 632 633 if (msgsz > msqptr->msg_qbytes) { |
675#ifdef MSG_DEBUG_OK 676 printf("msgsz > msqptr->msg_qbytes\n"); 677#endif | 634 DPRINTF(("msgsz > msqptr->msg_qbytes\n")); |
678 error = EINVAL; 679 goto done2; 680 } 681 682 if (msqptr->msg_perm.mode & MSG_LOCKED) { | 635 error = EINVAL; 636 goto done2; 637 } 638 639 if (msqptr->msg_perm.mode & MSG_LOCKED) { |
683#ifdef MSG_DEBUG_OK 684 printf("msqid is locked\n"); 685#endif | 640 DPRINTF(("msqid is locked\n")); |
686 need_more_resources = 1; 687 } 688 if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) { | 641 need_more_resources = 1; 642 } 643 if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) { |
689#ifdef MSG_DEBUG_OK 690 printf("msgsz + msg_cbytes > msg_qbytes\n"); 691#endif | 644 DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n")); |
692 need_more_resources = 1; 693 } 694 if (segs_needed > nfree_msgmaps) { | 645 need_more_resources = 1; 646 } 647 if (segs_needed > nfree_msgmaps) { |
695#ifdef MSG_DEBUG_OK 696 printf("segs_needed > nfree_msgmaps\n"); 697#endif | 648 DPRINTF(("segs_needed > nfree_msgmaps\n")); |
698 need_more_resources = 1; 699 } 700 if (free_msghdrs == NULL) { | 649 need_more_resources = 1; 650 } 651 if (free_msghdrs == NULL) { |
701#ifdef MSG_DEBUG_OK 702 printf("no more msghdrs\n"); 703#endif | 652 DPRINTF(("no more msghdrs\n")); |
704 need_more_resources = 1; 705 } 706 707 if (need_more_resources) { 708 int we_own_it; 709 710 if ((msgflg & IPC_NOWAIT) != 0) { | 653 need_more_resources = 1; 654 } 655 656 if (need_more_resources) { 657 int we_own_it; 658 659 if ((msgflg & IPC_NOWAIT) != 0) { |
711#ifdef MSG_DEBUG_OK 712 printf("need more resources but caller doesn't want to wait\n"); 713#endif | 660 DPRINTF(("need more resources but caller " 661 "doesn't want to wait\n")); |
714 error = EAGAIN; 715 goto done2; 716 } 717 718 if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) { | 662 error = EAGAIN; 663 goto done2; 664 } 665 666 if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) { |
719#ifdef MSG_DEBUG_OK 720 printf("we don't own the msqid_ds\n"); 721#endif | 667 DPRINTF(("we don't own the msqid_ds\n")); |
722 we_own_it = 0; 723 } else { 724 /* Force later arrivals to wait for our 725 request */ | 668 we_own_it = 0; 669 } else { 670 /* Force later arrivals to wait for our 671 request */ |
726#ifdef MSG_DEBUG_OK 727 printf("we own the msqid_ds\n"); 728#endif | 672 DPRINTF(("we own the msqid_ds\n")); |
729 msqptr->msg_perm.mode |= MSG_LOCKED; 730 we_own_it = 1; 731 } | 673 msqptr->msg_perm.mode |= MSG_LOCKED; 674 we_own_it = 1; 675 } |
732#ifdef MSG_DEBUG_OK 733 printf("goodnight\n"); 734#endif | 676 DPRINTF(("goodnight\n")); |
735 error = tsleep(msqptr, (PZERO - 4) | PCATCH, 736 "msgwait", 0); | 677 error = tsleep(msqptr, (PZERO - 4) | PCATCH, 678 "msgwait", 0); |
737#ifdef MSG_DEBUG_OK 738 printf("good morning, error=%d\n", error); 739#endif | 679 DPRINTF(("good morning, error=%d\n", error)); |
740 if (we_own_it) 741 msqptr->msg_perm.mode &= ~MSG_LOCKED; 742 if (error != 0) { | 680 if (we_own_it) 681 msqptr->msg_perm.mode &= ~MSG_LOCKED; 682 if (error != 0) { |
743#ifdef MSG_DEBUG_OK 744 printf("msgsnd: interrupted system call\n"); 745#endif | 683 DPRINTF(("msgsnd: interrupted system call\n")); |
746 error = EINTR; 747 goto done2; 748 } 749 750 /* 751 * Make sure that the msq queue still exists 752 */ 753 754 if (msqptr->msg_qbytes == 0) { | 684 error = EINTR; 685 goto done2; 686 } 687 688 /* 689 * Make sure that the msq queue still exists 690 */ 691 692 if (msqptr->msg_qbytes == 0) { |
755#ifdef MSG_DEBUG_OK 756 printf("msqid deleted\n"); 757#endif | 693 DPRINTF(("msqid deleted\n")); |
758 error = EIDRM; 759 goto done2; 760 } 761 762 } else { | 694 error = EIDRM; 695 goto done2; 696 } 697 698 } else { |
763#ifdef MSG_DEBUG_OK 764 printf("got all the resources that we need\n"); 765#endif | 699 DPRINTF(("got all the resources that we need\n")); |
766 break; 767 } 768 } 769 770 /* 771 * We have the resources that we need. 772 * Make sure! 773 */ --- 34 unchanged lines hidden (view full) --- 808 panic("not enough msgmaps"); 809 if (free_msgmaps == -1) 810 panic("nil free_msgmaps"); 811 next = free_msgmaps; 812 if (next <= -1) 813 panic("next too low #1"); 814 if (next >= msginfo.msgseg) 815 panic("next out of range #1"); | 700 break; 701 } 702 } 703 704 /* 705 * We have the resources that we need. 706 * Make sure! 707 */ --- 34 unchanged lines hidden (view full) --- 742 panic("not enough msgmaps"); 743 if (free_msgmaps == -1) 744 panic("nil free_msgmaps"); 745 next = free_msgmaps; 746 if (next <= -1) 747 panic("next too low #1"); 748 if (next >= msginfo.msgseg) 749 panic("next out of range #1"); |
816#ifdef MSG_DEBUG_OK 817 printf("allocating segment %d to message\n", next); 818#endif | 750 DPRINTF(("allocating segment %d to message\n", next)); |
819 free_msgmaps = msgmaps[next].next; 820 nfree_msgmaps--; 821 msgmaps[next].next = msghdr->msg_spot; 822 msghdr->msg_spot = next; 823 segs_needed--; 824 } 825 826 /* 827 * Copy in the message type 828 */ 829 830 if ((error = copyin(user_msgp, &msghdr->msg_type, 831 sizeof(msghdr->msg_type))) != 0) { | 751 free_msgmaps = msgmaps[next].next; 752 nfree_msgmaps--; 753 msgmaps[next].next = msghdr->msg_spot; 754 msghdr->msg_spot = next; 755 segs_needed--; 756 } 757 758 /* 759 * Copy in the message type 760 */ 761 762 if ((error = copyin(user_msgp, &msghdr->msg_type, 763 sizeof(msghdr->msg_type))) != 0) { |
832#ifdef MSG_DEBUG_OK 833 printf("error %d copying the message type\n", error); 834#endif | 764 DPRINTF(("error %d copying the message type\n", error)); |
835 msg_freehdr(msghdr); 836 msqptr->msg_perm.mode &= ~MSG_LOCKED; 837 wakeup(msqptr); 838 goto done2; 839 } 840 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); 841 842 /* 843 * Validate the message type 844 */ 845 846 if (msghdr->msg_type < 1) { 847 msg_freehdr(msghdr); 848 msqptr->msg_perm.mode &= ~MSG_LOCKED; 849 wakeup(msqptr); | 765 msg_freehdr(msghdr); 766 msqptr->msg_perm.mode &= ~MSG_LOCKED; 767 wakeup(msqptr); 768 goto done2; 769 } 770 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); 771 772 /* 773 * Validate the message type 774 */ 775 776 if (msghdr->msg_type < 1) { 777 msg_freehdr(msghdr); 778 msqptr->msg_perm.mode &= ~MSG_LOCKED; 779 wakeup(msqptr); |
850#ifdef MSG_DEBUG_OK 851 printf("mtype (%d) < 1\n", msghdr->msg_type); 852#endif | 780 DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type)); |
853 error = EINVAL; 854 goto done2; 855 } 856 857 /* 858 * Copy in the message body 859 */ 860 --- 5 unchanged lines hidden (view full) --- 866 else 867 tlen = msgsz; 868 if (next <= -1) 869 panic("next too low #2"); 870 if (next >= msginfo.msgseg) 871 panic("next out of range #2"); 872 if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz], 873 tlen)) != 0) { | 781 error = EINVAL; 782 goto done2; 783 } 784 785 /* 786 * Copy in the message body 787 */ 788 --- 5 unchanged lines hidden (view full) --- 794 else 795 tlen = msgsz; 796 if (next <= -1) 797 panic("next too low #2"); 798 if (next >= msginfo.msgseg) 799 panic("next out of range #2"); 800 if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz], 801 tlen)) != 0) { |
874#ifdef MSG_DEBUG_OK 875 printf("error %d copying in message segment\n", error); 876#endif | 802 DPRINTF(("error %d copying in message segment\n", 803 error)); |
877 msg_freehdr(msghdr); 878 msqptr->msg_perm.mode &= ~MSG_LOCKED; 879 wakeup(msqptr); 880 goto done2; 881 } 882 msgsz -= tlen; 883 user_msgp = (char *)user_msgp + tlen; 884 next = msgmaps[next].next; --- 67 unchanged lines hidden (view full) --- 952 long msgtyp = uap->msgtyp; 953 int msgflg = uap->msgflg; 954 size_t len; 955 register struct msqid_ds *msqptr; 956 register struct msg *msghdr; 957 int error = 0; 958 short next; 959 | 804 msg_freehdr(msghdr); 805 msqptr->msg_perm.mode &= ~MSG_LOCKED; 806 wakeup(msqptr); 807 goto done2; 808 } 809 msgsz -= tlen; 810 user_msgp = (char *)user_msgp + tlen; 811 next = msgmaps[next].next; --- 67 unchanged lines hidden (view full) --- 879 long msgtyp = uap->msgtyp; 880 int msgflg = uap->msgflg; 881 size_t len; 882 register struct msqid_ds *msqptr; 883 register struct msg *msghdr; 884 int error = 0; 885 short next; 886 |
960#ifdef MSG_DEBUG_OK 961 printf("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp, 962 msgsz, msgtyp, msgflg); 963#endif | 887 DPRINTF(("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp, 888 msgsz, msgtyp, msgflg)); |
964 965 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 966 return (ENOSYS); 967 968 mtx_lock(&Giant); 969 msqid = IPCID_TO_IX(msqid); 970 971 if (msqid < 0 || msqid >= msginfo.msgmni) { | 889 890 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 891 return (ENOSYS); 892 893 mtx_lock(&Giant); 894 msqid = IPCID_TO_IX(msqid); 895 896 if (msqid < 0 || msqid >= msginfo.msgmni) { |
972#ifdef MSG_DEBUG_OK 973 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, 974 msginfo.msgmni); 975#endif | 897 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid, 898 msginfo.msgmni)); |
976 error = EINVAL; 977 goto done2; 978 } 979 980 msqptr = &msqids[msqid]; 981 if (msqptr->msg_qbytes == 0) { | 899 error = EINVAL; 900 goto done2; 901 } 902 903 msqptr = &msqids[msqid]; 904 if (msqptr->msg_qbytes == 0) { |
982#ifdef MSG_DEBUG_OK 983 printf("no such message queue id\n"); 984#endif | 905 DPRINTF(("no such message queue id\n")); |
985 error = EINVAL; 986 goto done2; 987 } 988 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { | 906 error = EINVAL; 907 goto done2; 908 } 909 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { |
989#ifdef MSG_DEBUG_OK 990 printf("wrong sequence number\n"); 991#endif | 910 DPRINTF(("wrong sequence number\n")); |
992 error = EINVAL; 993 goto done2; 994 } 995 996 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) { | 911 error = EINVAL; 912 goto done2; 913 } 914 915 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) { |
997#ifdef MSG_DEBUG_OK 998 printf("requester doesn't have read access\n"); 999#endif | 916 DPRINTF(("requester doesn't have read access\n")); |
1000 goto done2; 1001 } 1002 1003 msghdr = NULL; 1004 while (msghdr == NULL) { 1005 if (msgtyp == 0) { 1006 msghdr = msqptr->msg_first; 1007 if (msghdr != NULL) { 1008 if (msgsz < msghdr->msg_ts && 1009 (msgflg & MSG_NOERROR) == 0) { | 917 goto done2; 918 } 919 920 msghdr = NULL; 921 while (msghdr == NULL) { 922 if (msgtyp == 0) { 923 msghdr = msqptr->msg_first; 924 if (msghdr != NULL) { 925 if (msgsz < msghdr->msg_ts && 926 (msgflg & MSG_NOERROR) == 0) { |
1010#ifdef MSG_DEBUG_OK 1011 printf("first message on the queue is too big (want %d, got %d)\n", 1012 msgsz, msghdr->msg_ts); 1013#endif | 927 DPRINTF(("first message on the queue " 928 "is too big (want %d, got %d)\n", 929 msgsz, msghdr->msg_ts)); |
1014 error = E2BIG; 1015 goto done2; 1016 } 1017 if (msqptr->msg_first == msqptr->msg_last) { 1018 msqptr->msg_first = NULL; 1019 msqptr->msg_last = NULL; 1020 } else { 1021 msqptr->msg_first = msghdr->msg_next; --- 14 unchanged lines hidden (view full) --- 1036 * the absolute value of a negative msgtyp? 1037 * Note that the second half of this test can 1038 * NEVER be true if msgtyp is positive since 1039 * msg_type is always positive! 1040 */ 1041 1042 if (msgtyp == msghdr->msg_type || 1043 msghdr->msg_type <= -msgtyp) { | 930 error = E2BIG; 931 goto done2; 932 } 933 if (msqptr->msg_first == msqptr->msg_last) { 934 msqptr->msg_first = NULL; 935 msqptr->msg_last = NULL; 936 } else { 937 msqptr->msg_first = msghdr->msg_next; --- 14 unchanged lines hidden (view full) --- 952 * the absolute value of a negative msgtyp? 953 * Note that the second half of this test can 954 * NEVER be true if msgtyp is positive since 955 * msg_type is always positive! 956 */ 957 958 if (msgtyp == msghdr->msg_type || 959 msghdr->msg_type <= -msgtyp) { |
1044#ifdef MSG_DEBUG_OK 1045 printf("found message type %d, requested %d\n", 1046 msghdr->msg_type, msgtyp); 1047#endif | 960 DPRINTF(("found message type %d, " 961 "requested %d\n", 962 msghdr->msg_type, msgtyp)); |
1048 if (msgsz < msghdr->msg_ts && 1049 (msgflg & MSG_NOERROR) == 0) { | 963 if (msgsz < msghdr->msg_ts && 964 (msgflg & MSG_NOERROR) == 0) { |
1050#ifdef MSG_DEBUG_OK 1051 printf("requested message on the queue is too big (want %d, got %d)\n", 1052 msgsz, msghdr->msg_ts); 1053#endif | 965 DPRINTF(("requested message " 966 "on the queue is too big " 967 "(want %d, got %d)\n", 968 msgsz, msghdr->msg_ts)); |
1054 error = E2BIG; 1055 goto done2; 1056 } 1057 *prev = msghdr->msg_next; 1058 if (msghdr == msqptr->msg_last) { 1059 if (previous == NULL) { 1060 if (prev != 1061 &msqptr->msg_first) --- 26 unchanged lines hidden (view full) --- 1088 if (msghdr != NULL) 1089 break; 1090 1091 /* 1092 * Hmph! No message found. Does the user want to wait? 1093 */ 1094 1095 if ((msgflg & IPC_NOWAIT) != 0) { | 969 error = E2BIG; 970 goto done2; 971 } 972 *prev = msghdr->msg_next; 973 if (msghdr == msqptr->msg_last) { 974 if (previous == NULL) { 975 if (prev != 976 &msqptr->msg_first) --- 26 unchanged lines hidden (view full) --- 1003 if (msghdr != NULL) 1004 break; 1005 1006 /* 1007 * Hmph! No message found. Does the user want to wait? 1008 */ 1009 1010 if ((msgflg & IPC_NOWAIT) != 0) { |
1096#ifdef MSG_DEBUG_OK 1097 printf("no appropriate message found (msgtyp=%d)\n", 1098 msgtyp); 1099#endif | 1011 DPRINTF(("no appropriate message found (msgtyp=%d)\n", 1012 msgtyp)); |
1100 /* The SVID says to return ENOMSG. */ 1101 error = ENOMSG; 1102 goto done2; 1103 } 1104 1105 /* 1106 * Wait for something to happen 1107 */ 1108 | 1013 /* The SVID says to return ENOMSG. */ 1014 error = ENOMSG; 1015 goto done2; 1016 } 1017 1018 /* 1019 * Wait for something to happen 1020 */ 1021 |
1109#ifdef MSG_DEBUG_OK 1110 printf("msgrcv: goodnight\n"); 1111#endif | 1022 DPRINTF(("msgrcv: goodnight\n")); |
1112 error = tsleep(msqptr, (PZERO - 4) | PCATCH, "msgwait", 0); | 1023 error = tsleep(msqptr, (PZERO - 4) | PCATCH, "msgwait", 0); |
1113#ifdef MSG_DEBUG_OK 1114 printf("msgrcv: good morning (error=%d)\n", error); 1115#endif | 1024 DPRINTF(("msgrcv: good morning (error=%d)\n", error)); |
1116 1117 if (error != 0) { | 1025 1026 if (error != 0) { |
1118#ifdef MSG_DEBUG_OK 1119 printf("msgsnd: interrupted system call\n"); 1120#endif | 1027 DPRINTF(("msgsnd: interrupted system call\n")); |
1121 error = EINTR; 1122 goto done2; 1123 } 1124 1125 /* 1126 * Make sure that the msq queue still exists 1127 */ 1128 1129 if (msqptr->msg_qbytes == 0 || 1130 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { | 1028 error = EINTR; 1029 goto done2; 1030 } 1031 1032 /* 1033 * Make sure that the msq queue still exists 1034 */ 1035 1036 if (msqptr->msg_qbytes == 0 || 1037 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { |
1131#ifdef MSG_DEBUG_OK 1132 printf("msqid deleted\n"); 1133#endif | 1038 DPRINTF(("msqid deleted\n")); |
1134 error = EIDRM; 1135 goto done2; 1136 } 1137 } 1138 1139 /* 1140 * Return the message to the user. 1141 * --- 6 unchanged lines hidden (view full) --- 1148 msqptr->msg_rtime = time_second; 1149 1150 /* 1151 * Make msgsz the actual amount that we'll be returning. 1152 * Note that this effectively truncates the message if it is too long 1153 * (since msgsz is never increased). 1154 */ 1155 | 1039 error = EIDRM; 1040 goto done2; 1041 } 1042 } 1043 1044 /* 1045 * Return the message to the user. 1046 * --- 6 unchanged lines hidden (view full) --- 1053 msqptr->msg_rtime = time_second; 1054 1055 /* 1056 * Make msgsz the actual amount that we'll be returning. 1057 * Note that this effectively truncates the message if it is too long 1058 * (since msgsz is never increased). 1059 */ 1060 |
1156#ifdef MSG_DEBUG_OK 1157 printf("found a message, msgsz=%d, msg_ts=%d\n", msgsz, 1158 msghdr->msg_ts); 1159#endif | 1061 DPRINTF(("found a message, msgsz=%d, msg_ts=%d\n", msgsz, 1062 msghdr->msg_ts)); |
1160 if (msgsz > msghdr->msg_ts) 1161 msgsz = msghdr->msg_ts; 1162 1163 /* 1164 * Return the type to the user. 1165 */ 1166 1167 error = copyout(&(msghdr->msg_type), user_msgp, 1168 sizeof(msghdr->msg_type)); 1169 if (error != 0) { | 1063 if (msgsz > msghdr->msg_ts) 1064 msgsz = msghdr->msg_ts; 1065 1066 /* 1067 * Return the type to the user. 1068 */ 1069 1070 error = copyout(&(msghdr->msg_type), user_msgp, 1071 sizeof(msghdr->msg_type)); 1072 if (error != 0) { |
1170#ifdef MSG_DEBUG_OK 1171 printf("error (%d) copying out message type\n", error); 1172#endif | 1073 DPRINTF(("error (%d) copying out message type\n", error)); |
1173 msg_freehdr(msghdr); 1174 wakeup(msqptr); 1175 goto done2; 1176 } 1177 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); 1178 1179 /* 1180 * Return the segments to the user --- 9 unchanged lines hidden (view full) --- 1190 tlen = msgsz - len; 1191 if (next <= -1) 1192 panic("next too low #3"); 1193 if (next >= msginfo.msgseg) 1194 panic("next out of range #3"); 1195 error = copyout(&msgpool[next * msginfo.msgssz], 1196 user_msgp, tlen); 1197 if (error != 0) { | 1074 msg_freehdr(msghdr); 1075 wakeup(msqptr); 1076 goto done2; 1077 } 1078 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); 1079 1080 /* 1081 * Return the segments to the user --- 9 unchanged lines hidden (view full) --- 1091 tlen = msgsz - len; 1092 if (next <= -1) 1093 panic("next too low #3"); 1094 if (next >= msginfo.msgseg) 1095 panic("next out of range #3"); 1096 error = copyout(&msgpool[next * msginfo.msgssz], 1097 user_msgp, tlen); 1098 if (error != 0) { |
1198#ifdef MSG_DEBUG_OK 1199 printf("error (%d) copying out message segment\n", 1200 error); 1201#endif | 1099 DPRINTF(("error (%d) copying out message segment\n", 1100 error)); |
1202 msg_freehdr(msghdr); 1203 wakeup(msqptr); 1204 goto done2; 1205 } 1206 user_msgp = (char *)user_msgp + tlen; 1207 next = msgmaps[next].next; 1208 } 1209 --- 29 unchanged lines hidden --- | 1101 msg_freehdr(msghdr); 1102 wakeup(msqptr); 1103 goto done2; 1104 } 1105 user_msgp = (char *)user_msgp + tlen; 1106 next = msgmaps[next].next; 1107 } 1108 --- 29 unchanged lines hidden --- |