summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_socket.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index e6b7bac..bed769d 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1962,6 +1962,7 @@ release:
/*
* Optimized version of soreceive() for stream (TCP) sockets.
+ * XXXAO: (MSG_WAITALL | MSG_PEEK) isn't properly handled.
*/
int
soreceive_stream(struct socket *so, struct sockaddr **psa, struct uio *uio,
@@ -2050,7 +2051,7 @@ restart:
/* On MSG_WAITALL we must wait until all data or error arrives. */
if ((flags & MSG_WAITALL) &&
- (sb->sb_cc >= uio->uio_resid || sb->sb_cc >= sb->sb_lowat))
+ (sb->sb_cc >= uio->uio_resid || sb->sb_cc >= sb->sb_hiwat))
goto deliver;
/*
@@ -2076,7 +2077,11 @@ deliver:
if (mp0 != NULL) {
/* Dequeue as many mbufs as possible. */
if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) {
- for (*mp0 = m = sb->sb_mb;
+ if (*mp0 == NULL)
+ *mp0 = sb->sb_mb;
+ else
+ m_cat(*mp0, sb->sb_mb);
+ for (m = sb->sb_mb;
m != NULL && m->m_len <= len;
m = m->m_next) {
len -= m->m_len;
@@ -2084,10 +2089,11 @@ deliver:
sbfree(sb, m);
n = m;
}
+ n->m_next = NULL;
sb->sb_mb = m;
+ sb->sb_lastrecord = sb->sb_mb;
if (sb->sb_mb == NULL)
SB_EMPTY_FIXUP(sb);
- n->m_next = NULL;
}
/* Copy the remainder. */
if (len > 0) {
@@ -2098,9 +2104,9 @@ deliver:
if (m == NULL)
len = 0; /* Don't flush data from sockbuf. */
else
- uio->uio_resid -= m->m_len;
+ uio->uio_resid -= len;
if (*mp0 != NULL)
- n->m_next = m;
+ m_cat(*mp0, m);
else
*mp0 = m;
if (*mp0 == NULL) {
OpenPOWER on IntegriCloud