work like any other one: it's actually thirty two times as big than the
POSIX ones for any given FD_SETSIZE, plus FD_SET and FD_ISSET are O(n)
instead of O(1). But at least, the mingw implementations of FD_SET has
built-in overflow checks.
Also, Winsock insists on returning big socket numbers, so we can't drop
those above FD_SETSIZE or we have no TCP/IP support at all, anyway.
- if( fd >= FD_SETSIZE )
- {
- msg_Err( p_this, "cannot create socket (too many already in use)" );
- net_Close( fd );
- return -1;
- }
-
- /* Set to non-blocking */
#if defined( WIN32 ) || defined( UNDER_CE )
{
unsigned long i_dummy = 1;
#if defined( WIN32 ) || defined( UNDER_CE )
{
unsigned long i_dummy = 1;
msg_Err( p_this, "cannot set socket to non-blocking mode" );
}
#else
msg_Err( p_this, "cannot set socket to non-blocking mode" );
}
#else
- fcntl( fd, F_SETFD, FD_CLOEXEC );
+ if( fd >= FD_SETSIZE )
+ {
+ /* We don't want to overflow select() fd_set */
+ msg_Err( p_this, "cannot create socket (too many already in use)" );
+ net_Close( fd );
+ return -1;
+ }
- if( ( ( i_val = fcntl( fd, F_GETFL, 0 ) ) < 0 ) ||
- ( fcntl( fd, F_SETFL, i_val | O_NONBLOCK ) < 0 ) )
- msg_Err( p_this, "cannot set socket to non-blocking mode (%s)",
- strerror( errno ) );
+ fcntl( fd, F_SETFD, FD_CLOEXEC );
+ i_val = fcntl( fd, F_GETFL, 0 );
+ fcntl( fd, F_SETFL, ((i_val != -1) ? i_val : 0) | O_NONBLOCK );