diff options
author | ps <ps@FreeBSD.org> | 2004-11-29 23:09:07 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2004-11-29 23:09:07 +0000 |
commit | 9ed5c9cd2b025cf0c8f4e4c29b4145cd3b891364 (patch) | |
tree | cdefa191c0853eb136f9fc79892877d50636aae7 /sys/kern/uipc_socket.c | |
parent | 2b85447398dccc1b29574142f8c6b4842d8cabe1 (diff) | |
download | FreeBSD-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.c | 24 |
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; |