From Andrew Gierth ( andrew@erlenstar.demon.co.uk):
Technically, fcntl(soc, F_SETFL, O_NONBLOCK)
is incorrect since it
clobbers all other file flags. Generally one gets away with it since
the other flags (O_APPEND
for example) don't really apply much to
sockets. In a similarly rough vein, you would use fcntl(soc, F_SETFL, 0)
to go back to blocking mode.
To do it right, use F_GETFL
to get the current flags, set or clear the
O_NONBLOCK
flag, then use F_SETFL
to set the flags.
And yes, the flag can be changed either way at will.
Andrew Gierth
(
andrew@erlenstar.demon.co.uk) has outlined the following
procedure for using select()
with connect()
, which will allow you to
put a timeout on the connect()
call:
First, create the socket and put it into non-blocking mode, then call
connect()
. There are three possibilities:
EINPROGRESS
. The connection attempt has begun,
but not yet completed.If the connection succeeds:
select()
as writable (and will
also select as readable
if data arrives)If the connection fails:
getsockopt(SO_ERROR)
to get the error status - but be
careful; some systems return the error code in the result parameter of
getsockopt()
, but others (incorrectly) cause the getsockopt
call itself
to fail with the stored value as the error.Sample code that illustrates this can be found in the socket-faq
examples, in the file connect.c
.