653         } else {
 654                 mutex_exit(&so->so_lock);
 655                 return (B_FALSE);
 656         }
 657 }
 658 
 659 int
 660 so_dequeue_msg(struct sonode *so, mblk_t **mctlp, struct uio *uiop,
 661     rval_t *rvalp, int flags)
 662 {
 663         mblk_t  *mp, *nmp;
 664         mblk_t  *savemp, *savemptail;
 665         mblk_t  *new_msg_head;
 666         mblk_t  *new_msg_last_head;
 667         mblk_t  *last_tail;
 668         boolean_t partial_read;
 669         boolean_t reset_atmark = B_FALSE;
 670         int more = 0;
 671         int error;
 672         ssize_t oobmark;
 673         sodirect_t *sodp = so->so_direct;
 674 
 675         partial_read = B_FALSE;
 676         *mctlp = NULL;
 677 again:
 678         mutex_enter(&so->so_lock);
 679 again1:
 680 #ifdef DEBUG
 681         if (so_debug_length) {
 682                 ASSERT(so_check_length(so));
 683         }
 684 #endif
 685         if (so->so_state & SS_RCVATMARK) {
 686                 /* Check whether the caller is OK to read past the mark */
 687                 if (flags & MSG_NOMARK) {
 688                         mutex_exit(&so->so_lock);
 689                         return (EWOULDBLOCK);
 690                 }
 691                 reset_atmark = B_TRUE;
 692         }
 693         /*
 694          * First move messages from the dump area to processing area
 695          */
 696         if (sodp != NULL) {
 
 767                         savemptail = mp;
 768                         ASSERT(DB_TYPE(mp) == M_PROTO ||
 769                             DB_TYPE(mp) == M_PCPROTO);
 770                         while (mp->b_cont != NULL &&
 771                             DB_TYPE(mp->b_cont) != M_DATA) {
 772                                 ASSERT(DB_TYPE(mp->b_cont) == M_PROTO ||
 773                                     DB_TYPE(mp->b_cont) == M_PCPROTO);
 774                                 mp = mp->b_cont;
 775                                 savemptail = mp;
 776                         }
 777                         mp = savemptail->b_cont;
 778                         savemptail->b_cont = NULL;
 779                 }
 780 
 781                 ASSERT(DB_TYPE(mp) == M_DATA);
 782                 /*
 783                  * Now process DATA blocks, if any. Note that for sodirect
 784                  * enabled socket, uio_resid can be 0.
 785                  */
 786                 if (uiop->uio_resid >= 0) {
 787                         ssize_t copied = 0;
 788 
 789                         if (sodp != NULL && (DB_FLAGS(mp) & DBLK_UIOA)) {
 790                                 mutex_enter(&so->so_lock);
 791                                 ASSERT(uiop == (uio_t *)&sodp->sod_uioa);
 792                                 copied = sod_uioa_mblk(so, mp);
 793                                 if (copied > 0)
 794                                         partial_read = B_TRUE;
 795                                 mutex_exit(&so->so_lock);
 796                                 /* mark this mblk as processed */
 797                                 mp = NULL;
 798                         } else {
 799                                 ssize_t oldresid = uiop->uio_resid;
 800 
 801                                 if (MBLKL(mp) < so_mblk_pull_len) {
 802                                         if (pullupmsg(mp, -1) == 1) {
 803                                                 last_tail = mp;
 804                                         }
 805                                 }
 806                                 /*
 807                                  * Can not read beyond the oobmark
 808                                  */
 
 826                                 ASSERT(so->so_oobmark >= 0);
 827                                 if (so->so_oobmark > 0) {
 828                                         so->so_oobmark -= copied;
 829                                         ASSERT(so->so_oobmark >= 0);
 830                                         if (so->so_oobmark == 0) {
 831                                                 ASSERT(so->so_state &
 832                                                     SS_OOBPEND);
 833                                                 so->so_oobmark = 0;
 834                                                 so->so_state |= SS_RCVATMARK;
 835                                         }
 836                                 }
 837                                 /*
 838                                  * so_check_flow_control() will drop
 839                                  * so->so_lock.
 840                                  */
 841                                 rvalp->r_val2 = so_check_flow_control(so);
 842                         }
 843                 }
 844                 if (mp != NULL) { /* more data blocks in msg */
 845                         more |= MOREDATA;
 846                         if ((flags & (MSG_PEEK|MSG_TRUNC))) {
 847                                 if (flags & MSG_PEEK) {
 848                                         freemsg(mp);
 849                                 } else {
 850                                         unsigned int msize = msgdsize(mp);
 851 
 852                                         freemsg(mp);
 853                                         mutex_enter(&so->so_lock);
 854                                         so->so_rcv_queued -= msize;
 855                                         /*
 856                                          * so_check_flow_control() will drop
 857                                          * so->so_lock.
 858                                          */
 859                                         rvalp->r_val2 =
 860                                             so_check_flow_control(so);
 861                                 }
 862                         } else if (partial_read && !somsghasdata(mp)) {
 863                                 /*
 864                                  * Avoid queuing a zero-length tail part of
 865                                  * a message. partial_read == 1 indicates that
 
 | 
 
 
 653         } else {
 654                 mutex_exit(&so->so_lock);
 655                 return (B_FALSE);
 656         }
 657 }
 658 
 659 int
 660 so_dequeue_msg(struct sonode *so, mblk_t **mctlp, struct uio *uiop,
 661     rval_t *rvalp, int flags)
 662 {
 663         mblk_t  *mp, *nmp;
 664         mblk_t  *savemp, *savemptail;
 665         mblk_t  *new_msg_head;
 666         mblk_t  *new_msg_last_head;
 667         mblk_t  *last_tail;
 668         boolean_t partial_read;
 669         boolean_t reset_atmark = B_FALSE;
 670         int more = 0;
 671         int error;
 672         ssize_t oobmark;
 673         ssize_t copied = 0;
 674         sodirect_t *sodp = so->so_direct;
 675         xuio_t *xuio = NULL;
 676 
 677         partial_read = B_FALSE;
 678         *mctlp = NULL;
 679         if ((uiop->uio_extflg & UIO_XUIO) != 0) {
 680                 xuio = (xuio_t *)uiop;
 681         }
 682 again:
 683         mutex_enter(&so->so_lock);
 684 again1:
 685 #ifdef DEBUG
 686         if (so_debug_length) {
 687                 ASSERT(so_check_length(so));
 688         }
 689 #endif
 690         if (so->so_state & SS_RCVATMARK) {
 691                 /* Check whether the caller is OK to read past the mark */
 692                 if (flags & MSG_NOMARK) {
 693                         mutex_exit(&so->so_lock);
 694                         return (EWOULDBLOCK);
 695                 }
 696                 reset_atmark = B_TRUE;
 697         }
 698         /*
 699          * First move messages from the dump area to processing area
 700          */
 701         if (sodp != NULL) {
 
 772                         savemptail = mp;
 773                         ASSERT(DB_TYPE(mp) == M_PROTO ||
 774                             DB_TYPE(mp) == M_PCPROTO);
 775                         while (mp->b_cont != NULL &&
 776                             DB_TYPE(mp->b_cont) != M_DATA) {
 777                                 ASSERT(DB_TYPE(mp->b_cont) == M_PROTO ||
 778                                     DB_TYPE(mp->b_cont) == M_PCPROTO);
 779                                 mp = mp->b_cont;
 780                                 savemptail = mp;
 781                         }
 782                         mp = savemptail->b_cont;
 783                         savemptail->b_cont = NULL;
 784                 }
 785 
 786                 ASSERT(DB_TYPE(mp) == M_DATA);
 787                 /*
 788                  * Now process DATA blocks, if any. Note that for sodirect
 789                  * enabled socket, uio_resid can be 0.
 790                  */
 791                 if (uiop->uio_resid >= 0) {
 792                         if (sodp != NULL && (DB_FLAGS(mp) & DBLK_UIOA)) {
 793                                 mutex_enter(&so->so_lock);
 794                                 ASSERT(uiop == (uio_t *)&sodp->sod_uioa);
 795                                 copied = sod_uioa_mblk(so, mp);
 796                                 if (copied > 0)
 797                                         partial_read = B_TRUE;
 798                                 mutex_exit(&so->so_lock);
 799                                 /* mark this mblk as processed */
 800                                 mp = NULL;
 801                         } else {
 802                                 ssize_t oldresid = uiop->uio_resid;
 803 
 804                                 if (MBLKL(mp) < so_mblk_pull_len) {
 805                                         if (pullupmsg(mp, -1) == 1) {
 806                                                 last_tail = mp;
 807                                         }
 808                                 }
 809                                 /*
 810                                  * Can not read beyond the oobmark
 811                                  */
 
 829                                 ASSERT(so->so_oobmark >= 0);
 830                                 if (so->so_oobmark > 0) {
 831                                         so->so_oobmark -= copied;
 832                                         ASSERT(so->so_oobmark >= 0);
 833                                         if (so->so_oobmark == 0) {
 834                                                 ASSERT(so->so_state &
 835                                                     SS_OOBPEND);
 836                                                 so->so_oobmark = 0;
 837                                                 so->so_state |= SS_RCVATMARK;
 838                                         }
 839                                 }
 840                                 /*
 841                                  * so_check_flow_control() will drop
 842                                  * so->so_lock.
 843                                  */
 844                                 rvalp->r_val2 = so_check_flow_control(so);
 845                         }
 846                 }
 847                 if (mp != NULL) { /* more data blocks in msg */
 848                         more |= MOREDATA;
 849 
 850                         /*
 851                          * If requested, tally up remaining data along with the
 852                          * amount already copied.
 853                          */
 854                         if (xuio != NULL &&
 855                             xuio->xu_type == UIOTYPE_PEEKSIZE) {
 856                                 xuio->xu_ext.xu_ps.xu_ps_set = B_TRUE;
 857                                 xuio->xu_ext.xu_ps.xu_ps_size =
 858                                     copied + msgdsize(mp);
 859                         }
 860 
 861                         if ((flags & (MSG_PEEK|MSG_TRUNC))) {
 862                                 if (flags & MSG_PEEK) {
 863                                         freemsg(mp);
 864                                 } else {
 865                                         unsigned int msize = msgdsize(mp);
 866 
 867                                         freemsg(mp);
 868                                         mutex_enter(&so->so_lock);
 869                                         so->so_rcv_queued -= msize;
 870                                         /*
 871                                          * so_check_flow_control() will drop
 872                                          * so->so_lock.
 873                                          */
 874                                         rvalp->r_val2 =
 875                                             so_check_flow_control(so);
 876                                 }
 877                         } else if (partial_read && !somsghasdata(mp)) {
 878                                 /*
 879                                  * Avoid queuing a zero-length tail part of
 880                                  * a message. partial_read == 1 indicates that
 
 |