- if (m == 0 || (so->so_rcv.sb_cc < uio->uio_resid &&
- so->so_rcv.sb_cc < so->so_rcv.sb_lowat) ||
- ((flags & MSG_WAITALL) && so->so_rcv.sb_cc < uio->uio_resid &&
- so->so_rcv.sb_hiwat >= uio->uio_resid && !sosendallatonce(so))) {
+ /*
+ * If we have less data than requested, block awaiting more
+ * (subject to any timeout) if:
+ * 1. the current count is less than the low water mark, or
+ * 2. MSG_WAITALL is set, and it is possible to do the entire
+ * receive operation at once if we block (resid <= hiwat).
+ * 3. MSG_DONTWAIT is not set
+ * If MSG_WAITALL is set but resid is larger than the receive buffer,
+ * we have to do the receive in sections, and thus risk returning
+ * a short count if a timeout or signal occurs after we start.
+ */
+ if (m == 0 || ((flags & MSG_DONTWAIT) == 0 &&
+ so->so_rcv.sb_cc < uio->uio_resid) &&
+ (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
+ ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)))
+ if (m && (m->m_nextpkt || (m->m_flags & M_EOR) ||
+ m->m_type == MT_OOBDATA || m->m_type == MT_CONTROL))
+ break;