Reputation: 5823
Update:
My bad. The error I am getting is ECONNREFUSED and not EINPROGRESS. After checking the error
variable I've found that it is greater than 0, I printfed errno
instead of error
.
Of course errno
is EINPROGRESS
because it value didn't change since the call to connect()
.
Question answered. Thanks folks.
I am using the the the same piece of code as in Stevens' UNIX Network Programming non >blocking connect() example:
- Setting socket to nonblocking
- Initiate nonblocking connect()
- Check for immediate completion
- Call select() with timeout and wait for read or write readiness
- When select() returns with value greater than 0 do getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len).
The error I am getting is EINPROGRESS. The code is executed on rhel5 server.
Any ideas why I am getting this error?
Code snippet:
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
if ((retVal = connect(sockfd, saptr, salen)) < 0)
if (errno != EINPROGRESS)
return (-1);
if (retVal == 0)
{
// restore file status flags
fcntl(sockfd, F_SETFL, flags);
return 0;
}
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;
if ((retVal = select(sockfd + 1, &rset, &wset, NULL, &tval)) == 0)
{
// timeout
close(sockfd);
errno = ETIMEDOUT;
return (-1);
}
if (retVal < 0)
{
// select() failed
return (-1);
}
if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))
{
len = sizeof(error);
error = 0;
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return (-1);
if (error > 0) //<<<<< error == EINPROGRESS >>>
{
close(sockfd);
errno = error;
return (-1);
}
}
else
{
return (-1);
}
// restore file status flags
fcntl(sockfd, F_SETFL, flags);
Upvotes: 2
Views: 21234
Reputation: 2883
Shucks....I give up. I tried and tried but could not find a problem with your code. So, all I offer are some suggestions and hypothesis.
Use FD_COPY to copy rset to wset.
Can you do a getsockopt when the first connect fails. I am suspecting that Select is returning 0 and because of above, somehow your writefd set is set and doing a getsockopt is returning you the stale error from the previous connect. IMO, a subsquent connect should return EALREADY (although it could be platform dependant)
Please do the above (and downvote me if I am wrong about using FD_COPY) and share the results
Upvotes: 4
Reputation: 239171
EINPROGRESS indicates that the non-blocking connect() is still... in progress.
So I would ask - are you checking that after the select() returns, the connect()ing file descriptor is still set in the writefds fd_set? If it isn't, then that means select() has returned for some other reason.
Upvotes: 3
Reputation: 11998
A select value greater than zero doesn't indicate any sort of error... it is the number of sockets that met the criteria of the select statement. select will return -1 in the event of a failure.
It's not clear to me when calling getsocktopt with SO_ERROR is valid; you are probably best of sticking with checking for errors everytime you use the socket ( which I think you are doing anyway ). It the select isn't failing, you are fine.
Upvotes: 2