summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_socket.c
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2004-11-29 23:09:07 +0000
committerps <ps@FreeBSD.org>2004-11-29 23:09:07 +0000
commit9ed5c9cd2b025cf0c8f4e4c29b4145cd3b891364 (patch)
treecdefa191c0853eb136f9fc79892877d50636aae7 /sys/kern/uipc_socket.c
parent2b85447398dccc1b29574142f8c6b4842d8cabe1 (diff)
downloadFreeBSD-src-9ed5c9cd2b025cf0c8f4e4c29b4145cd3b891364.zip
FreeBSD-src-9ed5c9cd2b025cf0c8f4e4c29b4145cd3b891364.tar.gz
Make soreceive(MSG_DONTWAIT) nonblocking. If MSG_DONTWAIT is passed into
soreceive(), then pass in M_DONTWAIT to m_copym(). Also fix up error handling for the case where m_copym() returns failure. Submitted by: Mohan Srinivasan mohans at yahoo-inc dot com Reviewed by: rwatson
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r--sys/kern/uipc_socket.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index e784fe3..f5299fd 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1291,9 +1291,27 @@ dontblock:
moff += len;
else {
if (mp != NULL) {
- SOCKBUF_UNLOCK(&so->so_rcv);
- *mp = m_copym(m, 0, len, M_TRYWAIT);
- SOCKBUF_LOCK(&so->so_rcv);
+ int copy_flag;
+
+ if (flags & MSG_DONTWAIT)
+ copy_flag = M_DONTWAIT;
+ else
+ copy_flag = M_TRYWAIT;
+ if (copy_flag == M_TRYWAIT)
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ *mp = m_copym(m, 0, len, copy_flag);
+ if (copy_flag == M_TRYWAIT)
+ SOCKBUF_LOCK(&so->so_rcv);
+ if (*mp == NULL) {
+ /*
+ * m_copym() couldn't allocate an mbuf.
+ * Adjust uio_resid back (it was adjusted
+ * down by len bytes, which we didn't end
+ * up "copying" over).
+ */
+ uio->uio_resid += len;
+ break;
+ }
}
m->m_data += len;
m->m_len -= len;
OpenPOWER on IntegriCloud