curl-library
Re: CURLE_GOT_NOTHING on slow connections
Date: Fri, 27 Feb 2004 13:18:14 -0600
Joe Halpin wrote:
> Richard Bramante wrote:
>> Curl then calls waitconnect() and select() returns 1, *but* it does
>> not set this socket in the errfd set, so curl assumes that it is
>> connected and waitconnect returns 0.
>
> I don't recall ever using a system in which the errfd set was used for
> this. POSIX, in fact, specifies that for a socket, this set will report
> pending exceptional conditions, not errors. The only exceptional
> condition I know of for TCP sockets is out-of-band data.
>
> Perhaps Windows does this differently, I wouldn't be surprised, but I
> don't think this is a reliable way to detect an error in general.
I'm not as familiar with the socket code in curl as I probably should
be, so take this for what it's worth. Here's a suggestion for a
different way to check whether the socket was connected or not.
Joe
Index: lib/connect.c
===================================================================
RCS file: /repository/curl/lib/connect.c,v
retrieving revision 1.77
diff -u -r1.77 connect.c
--- lib/connect.c 15 Feb 2004 13:55:24 -0000 1.77
+++ lib/connect.c 27 Feb 2004 19:13:31 -0000
@@ -173,9 +173,10 @@
int timeout_msec)
{
fd_set fd;
- fd_set errfd;
struct timeval interval;
int rc;
+ struct sockaddr_in name;
+ socklen_t namelen = sizeof name;
#ifdef mpeix
/* Call this function once now, and ignore the results. We do this to
"clear" the error state on the socket so that we can later read it
@@ -187,15 +188,12 @@
FD_ZERO(&fd);
FD_SET(sockfd, &fd);
- FD_ZERO(&errfd);
- FD_SET(sockfd, &errfd);
-
interval.tv_sec = timeout_msec/1000;
timeout_msec -= interval.tv_sec*1000;
interval.tv_usec = timeout_msec*1000;
- rc = select(sockfd+1, NULL, &fd, &errfd, &interval);
+ rc = select(sockfd+1, NULL, &fd, (fd_set*)0, &interval);
if(-1 == rc)
/* error, no connect here, try next */
return -1;
@@ -204,8 +202,10 @@
/* timeout, no connect today */
return 1;
- if(FD_ISSET(sockfd, &errfd))
- /* error condition caught */
+ if(-1 == getpeername(sockfd, (struct sockaddr*)&name, &namelen))
+ /* not connected */
+ /* might want to add some kind of debug output to
+ display strerror(errno) here */
return 2;
/* we have a connect! */
Received on 2004-02-27