Deleted Added
full compact
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 ---