This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[patch] specify MSG_DONTWAIT in the __recvmsg call in clntudp_call
- From: Jeff Moyer <jmoyer at redhat dot com>
- To: libc-alpha at sources dot redhat dot com
- Date: Thu, 18 Oct 2007 18:07:44 -0400
- Subject: [patch] specify MSG_DONTWAIT in the __recvmsg call in clntudp_call
Hi,
I've run across a situation where the poll in clntudp_call returns a
ready file descriptor, but a subsequent recvmsg on that file
descriptor blocks forever. This means that the timeout value
specified in the clnt_call will not be honored, and the entire
application hangs.
The BUGS section of the select man page has this to say:
Under Linux, select() may report a socket file descriptor as "ready for
reading", while nevertheless a subsequent read blocks. This could for
example happen when data has arrived but upon examination has wrong
checksum and is discarded. There may be other circumstances in which a
file descriptor is spuriously reported as ready. Thus it may be safer
to use O_NONBLOCK on sockets that should not block.
Given that, and the discussion found here:
http://lkml.org/lkml/2004/10/6/117
I think it's reasonable to use MSG_DONTWAIT to make clntudp_call a bit
more robust. The following patch fixed the behaviour in the test
environment. I ensured that it applies against a cvs checkout of the
glibc tree (it applied with an offset of -6 lines).
Cheers,
Jeff
--- glibc-2.3.6/sunrpc/clnt_udp.c.orig 2007-10-17 22:05:28.000000000 -0400
+++ glibc-2.3.6/sunrpc/clnt_udp.c 2007-10-17 22:08:24.000000000 -0400
@@ -419,7 +419,7 @@ send_again:
{
fromlen = sizeof (struct sockaddr);
inlen = __recvfrom (cu->cu_sock, cu->cu_inbuf,
- (int) cu->cu_recvsz, 0,
+ (int) cu->cu_recvsz, MSG_DONTWAIT,
(struct sockaddr *) &from, &fromlen);
}
while (inlen < 0 && errno == EINTR);