[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] Sockets on Windows
From: |
Michael Lenaghan |
Subject: |
[libmicrohttpd] Sockets on Windows |
Date: |
Wed, 6 Jan 2010 22:19:09 -0500 |
Christian, the following code (from MHD_start_daemon_va) is wrong for Windows:
socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
if (socket_fd < 0)
{
#if HAVE_MESSAGES
if ((options & MHD_USE_DEBUG) != 0)
FPRINTF (stderr, "Call to socket failed: %s\n", STRERROR (errno));
#endif
free (retVal);
return NULL;
}
if (socket_fd >= FD_SETSIZE)
{
#if HAVE_MESSAGES
if ((options & MHD_USE_DEBUG) != 0)
FPRINTF (stderr,
"Socket descriptor larger than FD_SETSIZE: %d > %d\n",
socket_fd,
FD_SETSIZE);
On Windows socket() returns a value of type SOCKET:
WINSOCK_API_LINKAGE
SOCKET
WSAAPI
socket(
IN int af,
IN int type,
IN int protocol
);
SOCKET isn't a signed int--it's a pointer-sized unsigned int:
typedef UINT_PTR SOCKET;
Here's the description of UINT_PTR:
// The INT_PTR is guaranteed to be the same size as a pointer. Its
// size with change with pointer size (32/64). It should be used
// anywhere that a pointer is cast to an integer type. UINT_PTR is
// the unsigned variation.
fd_set is an array of these values:
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;
FD_SET() simply fills the next available slot in the array:
#define FD_SET(fd, set) do { \
if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \
((fd_set FAR *)(set))->fd_array[((fd_set FAR
*)(set))->fd_count++]=(fd);\
} while(0)
And select() ignores its first parameter.
So on Windows:
* You should only test socket fds against INVALID_SOCKET
* You shouldn't check socket fds against FD_SETSIZE
* You should check the total number of sockets being select()ed
against FD_SETSIZE