
            return;
        }
    }
    if (i == set->fd_count) {
        if (set->fd_count < FD_SETSIZE) {
            set->fd_array[i] = s;
            set->fd_count++;
        }
    }
}

#undef FD_CLR

void
myfdclr(int fd, fd_set *set)
{
    unsigned int i;
    SOCKET s = TO_SOCKET(fd);

    for (i = 0; i < set->fd_count; i++) {
        if (set->fd_array[i] == s) {
            while (i < set->fd_count - 1) {
                set->fd_array[i] = set->fd_array[i + 1];
                i++;
            }
            set->fd_count--;
            break;
        }
    }
}

#undef FD_ISSET

int
myfdisset(int fd, fd_set *set)
{
       return __WSAFDIsSet(TO_SOCKET(fd), set);
}

//
// Networking trampolines
// These are used to avoid socket startup/shutdown overhead in case 
// the socket routines aren\'t used.
//

#undef select

static int NtSocketsInitialized = 0;

static int
extract_file_fd(fd_set *set, fd_set *fileset)
{
    int idx;

    fileset->fd_count = 0;
    if (!set)
	return 0;
    for (idx = 0; idx < set->fd_count; idx++) {
	SOCKET fd = set->fd_array[idx];

	if (!is_socket(fd)) {
	    int i;

	    for (i = 0; i < fileset->fd_count; i++) {
		if (fileset->fd_array[i] == fd) {
		    break;
		}
	    }
	    if (i == fileset->fd_count) {
		if (fileset->fd_count < FD_SETSIZE) {
		    fileset->fd_array[i] = fd;
		    fileset->fd_count++;
		}
	    }
	}
    }
    return fileset->fd_count;
}

long 
myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
	       struct timeval *timeout)
{
    long r;
    fd_set file_rd;
    fd_set file_wr;
#ifdef USE_INTERRUPT_WINSOCK
    fd_set trap;
#endif /* USE_INTERRUPT_WINSOCK */
    int file_nfds;

    if (!NtSocketsInitialized) {
	StartSockets();
    }
    r = 0;
    if (rd && rd->fd_count > r) r = rd->fd_count;
    if (wr && wr->fd_count > r) r = wr->fd_count;
    if (ex && ex->fd_count > r) r = ex->fd_count;
    if (nfds > r) nfds = r;
    if (nfds == 0 && timeout) {
	Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
	return 0;
    }
    file_nfds = extract_file_fd(rd, &file_rd);
    file_nfds += extract_file_fd(wr, &file_wr);
    if (file_nfds)
    {
	// assume normal files are always readable/writable
	// fake read/write fd_set and return value
	if (rd) *rd = file_rd;
	if (wr) *wr = file_wr;
	return file_nfds;
    }

#if USE_INTERRUPT_WINSOCK
    if (ex)
	trap = *ex;
    else
	trap.fd_count = 0;
    if (trap.fd_count < FD_SETSIZE)
	trap.fd_array[trap.fd_count++] = (SOCKET)interrupted_event;
    // else unable to catch interrupt.
    ex = &trap;
#endif /* USE_INTERRUPT_WINSOCK */

    if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
	errno = WSAGetLastError();
	switch (errno) {
	  case WSAEINTR:
	    errno = EINTR;
	    break;
	}
    }
    return r;
}

static void
StartSockets ()
{
    WORD version;
    WSADATA retdata;
    int ret;
    int iSockOpt;
    
    //
    // initalize the winsock interface and insure that it\'s
    // cleaned up at exit.
    //
    version = MAKEWORD(1, 1);
    if (ret = WSAStartup(version, &retdata))
	rb_fatal ("Unable to locate winsock library!\n");
    if (LOBYTE(retdata.wVersion) != 1)
	rb_fatal("could not find version 1 of winsock dll\n");

    if (HIBYTE(retdata.wVersion) != 1)
	rb_fatal("could not find version 1 of winsock dll\n");

    atexit((void (*)(void)) WSACleanup);

    iSockOpt = SO_SYNCHRONOUS_NONALERT;
    /*
     * Enable the use of sockets as filehandles
     */
    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
	       (char *)&iSockOpt, sizeof(iSockOpt));

    main_thread.handle = GetCurrentThreadHandle();
    main_thread.id = GetCurrentThreadId();

    interrupted_event = CreateSignal();
    if (!interrupted_event)
	rb_fatal("Unable to create interrupt event!\n");
    NtSocketsInitialized = 1;
}

#undef accept

SOCKET
myaccept (SOCKET s, struct sockaddr *addr, int *addrlen)
{
    SOCKET r;

    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = accept (TO_SOCKET(s), addr, addrlen)) == INVALID_SOCKET)
	errno = WSAGetLastError();
    return my_open_osfhandle(r, O_RDWR|O_BINARY);
}

#undef bind

int 
mybind (SOCKET s, struct sockaddr *addr, int addrlen)
{
    int r;

    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = bind (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef connect

int 
myconnect (SOCKET s, struct sockaddr *addr, int addrlen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = connect (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}


#undef getpeername

int 
mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = getpeername (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef getsockname

int 
mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = getsockname (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

int 
mygetsockopt (SOCKET s, int level, int optname, char *optval, int *optlen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = getsockopt (TO_SOCKET(s), level, optname, optval, optlen)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef ioctlsocket

int 
myioctlsocket (SOCKET s, long cmd, u_long *argp)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = ioctlsocket (TO_SOCKET(s), cmd, argp)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef listen

int 
mylisten (SOCKET s, int backlog)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = listen (TO_SOCKET(s), backlog)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef recv

int 
myrecv (SOCKET s, char *buf, int len, int flags)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = recv (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef recvfrom

int 
myrecvfrom (SOCKET s, char *buf, int len, int flags, 
		struct sockaddr *from, int *fromlen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = recvfrom (TO_SOCKET(s), buf, len, flags, from, fromlen)) == SOCKET_ERROR)
	errno =  WSAGetLastError();
    return r;
}

#undef send

int 
mysend (SOCKET s, char *buf, int len, int flags)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = send (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef sendto

int 
mysendto (SOCKET s, char *buf, int len, int flags, 
		struct sockaddr *to, int tolen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = sendto (TO_SOCKET(s), buf, len, flags, to, tolen)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef setsockopt

int 
mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen))
    		 == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}
    
#undef shutdown

int 
myshutdown (SOCKET s, int how)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = shutdown (TO_SOCKET(s), how)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef socket

SOCKET 
mysocket (int af, int type, int protocol)
{
    SOCKET s;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
	errno = WSAGetLastError();
	//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
    }
    return my_open_osfhandle(s, O_RDWR|O_BINARY);
}

#undef gethostbyaddr

struct hostent *
mygethostbyaddr (char *addr, int len, int type)
{
    struct hostent *r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = gethostbyaddr (addr, len, type)) == NULL)
	errno = WSAGetLastError();
    return r;
}

#undef gethostbyname

struct hostent *
mygethostbyname (char *name)
{
    struct hostent *r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = gethostbyname (name)) == NULL)
	errno = WSAGetLastError();
    return r;
}

#undef gethostname

int
mygethostname (char *name, int len)
{
    int r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = gethostname (name, len)) == SOCKET_ERROR)
	errno = WSAGetLastError();
    return r;
}

#undef getprotobyname

struct protoent *
mygetprotobyname (char *name)
{
    struct protoent *r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = getprotobyname (name)) == NULL)
	errno = WSAGetLastError();
    return r;
}

#undef getprotobynumber

struct protoent *
mygetprotobynumber (int num)
{
    struct protoent *r;
    if (!NtSocketsInitialized) {
	StartSockets();
    }
    if ((r = getprotobynumber (num)) == NULL)
	errno = WSAGetLastError();
    return r;
}

#undef getservbyname

struct servent *
mygetservbyname (char *name, char *pro