Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
w95sock.c File Reference
#include "primpl.h"

Go to the source code of this file.

Classes

struct  _WSA_COMPATIBILITY_MODE

Defines

#define READ_FD   1
#define WRITE_FD   2
#define CONNECT_FD   3
#define IOC_IN   0x80000000 /* copy in parameters */
#define IOC_VENDOR   0x18000000
#define _WSAIOW(x, y)   (IOC_IN|(x)|(y))
#define SIO_SET_COMPATIBILITY_MODE   _WSAIOW(IOC_VENDOR,300)
#define NTDDI_LONGHORN   0x06000000
#define WSAEVENT   HANDLE
#define WSAOVERLAPPED   OVERLAPPED
#define _PR_INTERRUPT_CHECK_INTERVAL_SECS   5

Typedefs

typedef enum
_WSA_COMPATIBILITY_BEHAVIOR_ID 
WSA_COMPATIBILITY_BEHAVIOR_ID
typedef enum
_WSA_COMPATIBILITY_BEHAVIOR_ID
PWSA_COMPATIBILITY_BEHAVIOR_ID
typedef struct _OVERLAPPED * LPWSAOVERLAPPED
typedef void(CALLBACKLPWSAOVERLAPPED_COMPLETION_ROUTINE )(IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags)
typedef DWORD dwIoControlCode
typedef DWORD LPVOID lpvInBuffer
typedef DWORD LPVOID DWORD cbInBuffer
typedef DWORD LPVOID DWORD LPVOID lpvOutBuffer
typedef DWORD LPVOID DWORD
LPVOID DWORD 
cbOutBuffer
typedef DWORD LPVOID DWORD
LPVOID DWORD LPDWORD 
lpcbBytesReturned
typedef DWORD LPVOID DWORD
LPVOID DWORD LPDWORD
LPWSAOVERLAPPED 
lpOverlapped
typedef DWORD LPVOID DWORD
LPVOID DWORD LPDWORD
LPWSAOVERLAPPED
LPWSAOVERLAPPED_COMPLETION_ROUTINE 
lpCompletionRoutine
typedef struct
_WSA_COMPATIBILITY_MODE 
WSA_COMPATIBILITY_MODE
typedef struct
_WSA_COMPATIBILITY_MODE
PWSA_COMPATIBILITY_MODE

Enumerations

enum  _WSA_COMPATIBILITY_BEHAVIOR_ID { WsaBehaviorAll = 0, WsaBehaviorReceiveBuffering, WsaBehaviorAutoTuning }

Functions

static PRInt32 socket_io_wait (PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout)
typedef int (__stdcall *WSAIOCTLPROC)(SOCKET s
void _PR_MD_InitSockets (void)
void _PR_MD_CleanupSockets (void)
PRInt32 _PR_MD_SOCKET (int af, int type, int flags)
PRInt32 _MD_CloseSocket (PRInt32 osfd)
PRInt32 _MD_SocketAvailable (PRFileDesc *fd)
PRInt32 _MD_Accept (PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, PRIntervalTime timeout)
PRInt32 _PR_MD_CONNECT (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
PRInt32 _PR_MD_BIND (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
PRInt32 _PR_MD_LISTEN (PRFileDesc *fd, PRIntn backlog)
PRInt32 _PR_MD_RECV (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
PRInt32 _PR_MD_SEND (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
PRInt32 _PR_MD_SENDTO (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
PRInt32 _PR_MD_RECVFROM (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
PRInt32 _PR_MD_WRITEV (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
PRInt32 _PR_MD_SHUTDOWN (PRFileDesc *fd, PRIntn how)
PRStatus _PR_MD_GETSOCKNAME (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
PRStatus _PR_MD_GETPEERNAME (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
PRStatus _PR_MD_GETSOCKOPT (PRFileDesc *fd, PRInt32 level, PRInt32 optname, char *optval, PRInt32 *optlen)
PRStatus _PR_MD_SETSOCKOPT (PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char *optval, PRInt32 optlen)
void _MD_MakeNonblock (PRFileDesc *f)

Variables

static HMODULE libWinsock2 = NULL
static WSAIOCTLPROC wsaioctlProc = NULL
static PRBool socketSetCompatMode = PR_FALSE

Class Documentation

struct _WSA_COMPATIBILITY_MODE

Definition at line 102 of file w95sock.c.

Class Members
WSA_COMPATIBILITY_BEHAVIOR_ID BehaviorId
ULONG TargetOsVersion

Define Documentation

Definition at line 581 of file w95sock.c.

#define _WSAIOW (   x,
  y 
)    (IOC_IN|(x)|(y))

Definition at line 64 of file w95sock.c.

#define CONNECT_FD   3

Definition at line 46 of file w95sock.c.

#define IOC_IN   0x80000000 /* copy in parameters */

Definition at line 62 of file w95sock.c.

#define IOC_VENDOR   0x18000000

Definition at line 63 of file w95sock.c.

#define NTDDI_LONGHORN   0x06000000

Definition at line 75 of file w95sock.c.

#define READ_FD   1

Definition at line 44 of file w95sock.c.

Definition at line 66 of file w95sock.c.

#define WRITE_FD   2

Definition at line 45 of file w95sock.c.

Definition at line 78 of file w95sock.c.

#define WSAOVERLAPPED   OVERLAPPED

Definition at line 80 of file w95sock.c.


Typedef Documentation

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

Definition at line 92 of file w95sock.c.

typedef struct _OVERLAPPED* LPWSAOVERLAPPED

Definition at line 81 of file w95sock.c.

typedef void(CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE)(IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags)

Definition at line 83 of file w95sock.c.


Enumeration Type Documentation

Enumerator:
WsaBehaviorAll 
WsaBehaviorReceiveBuffering 
WsaBehaviorAutoTuning 

Definition at line 68 of file w95sock.c.


Function Documentation

PRInt32 _MD_Accept ( PRFileDesc fd,
PRNetAddr raddr,
PRUint32 rlen,
PRIntervalTime  timeout 
)

Definition at line 224 of file w95sock.c.

{
    PRInt32 osfd = fd->secret->md.osfd;
    PRInt32 rv, err;

    while ((rv = accept(osfd, (struct sockaddr *) raddr, rlen)) == -1) 
    {
        err = WSAGetLastError();
        if ((err == WSAEWOULDBLOCK) && (!fd->secret->nonblocking))
        {
            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
            {
                return(-1);
            }
        }
        else
        {
            _PR_MD_MAP_ACCEPT_ERROR(err);
            break;
        }
    }
    return(rv);
} /* end _MD_accept() */

Here is the call graph for this function:

Definition at line 201 of file w95sock.c.

{
    PRInt32 rv;

    rv = closesocket((SOCKET) osfd );
    if (rv < 0)
        _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());

    return rv;
}

Here is the call graph for this function:

Definition at line 566 of file w95sock.c.

{
    return; /* do nothing */
}

Definition at line 213 of file w95sock.c.

{
    PRInt32 result;

    if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
        return -1;
    }
    return result;
}

Here is the call graph for this function:

PRInt32 _PR_MD_BIND ( PRFileDesc fd,
const PRNetAddr addr,
PRUint32  addrlen 
)

Definition at line 283 of file w95sock.c.

{
    PRInt32 rv;

    rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen);

    if (rv == SOCKET_ERROR)  {
        _PR_MD_MAP_BIND_ERROR(WSAGetLastError());
        return -1;
    }

    return 0;
}

Here is the call graph for this function:

Definition at line 135 of file w95sock.c.

Here is the caller graph for this function:

PRInt32 _PR_MD_CONNECT ( PRFileDesc fd,
const PRNetAddr addr,
PRUint32  addrlen,
PRIntervalTime  timeout 
)

Definition at line 253 of file w95sock.c.

{
    PRInt32 osfd = fd->secret->md.osfd;
    PRInt32 rv;
    int     err;

    if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) 
    {
        err = WSAGetLastError();
        if ((!fd->secret->nonblocking) && (err == WSAEWOULDBLOCK))
        {
            rv = socket_io_wait(osfd, CONNECT_FD, timeout);
            if ( rv < 0 )
            {
                return(-1);
            }
            else
            {
                PR_ASSERT(rv > 0);
                /* it's connected */
                return(0);
            } 
        }
        _PR_MD_MAP_CONNECT_ERROR(err);
    }
    return rv;
}

Here is the call graph for this function:

PRStatus _PR_MD_GETPEERNAME ( PRFileDesc fd,
PRNetAddr addr,
PRUint32 len 
)

Definition at line 524 of file w95sock.c.

{
    PRInt32 rv;

    rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
    if (rv==0) {
        return PR_SUCCESS;
    } else {
        _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError());
        return PR_FAILURE;
    }
}

Here is the call graph for this function:

PRStatus _PR_MD_GETSOCKNAME ( PRFileDesc fd,
PRNetAddr addr,
PRUint32 len 
)

Definition at line 510 of file w95sock.c.

{
    PRInt32 rv;

    rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
    if (rv==0) {
        return PR_SUCCESS;
    } else {
        _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError());
        return PR_FAILURE;
    }
}

Here is the call graph for this function:

PRStatus _PR_MD_GETSOCKOPT ( PRFileDesc fd,
PRInt32  level,
PRInt32  optname,
char *  optval,
PRInt32 optlen 
)

Definition at line 538 of file w95sock.c.

Here is the call graph for this function:

Definition at line 111 of file w95sock.c.

{
    OSVERSIONINFO osvi;

    memset(&osvi, 0, sizeof(osvi));
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    GetVersionEx(&osvi);

    /* if Vista or later... */
    if (osvi.dwMajorVersion >= 6)
    {
        libWinsock2 = LoadLibrary("Ws2_32.dll");
        if (libWinsock2)
        {
            wsaioctlProc = (WSAIOCTLPROC)GetProcAddress(libWinsock2, 
                                                        "WSAIoctl");
            if (wsaioctlProc)
            {
                socketSetCompatMode = PR_TRUE;
            }
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 _PR_MD_LISTEN ( PRFileDesc fd,
PRIntn  backlog 
)

Definition at line 298 of file w95sock.c.

{
    PRInt32 rv;

    rv = listen(fd->secret->md.osfd, backlog);

    if (rv == SOCKET_ERROR)  {
        _PR_MD_MAP_DEFAULT_ERROR(WSAGetLastError());
        return -1;
    }

    return 0;
}

Here is the call graph for this function:

PRInt32 _PR_MD_RECV ( PRFileDesc fd,
void buf,
PRInt32  amount,
PRIntn  flags,
PRIntervalTime  timeout 
)

Definition at line 313 of file w95sock.c.

{
    PRInt32 osfd = fd->secret->md.osfd;
    PRInt32 rv, err;
    int osflags;

    if (0 == flags) {
        osflags = 0;
    } else {
        PR_ASSERT(PR_MSG_PEEK == flags);
        osflags = MSG_PEEK;
    }
    while ((rv = recv( osfd, buf, amount, osflags)) == -1) 
    {
        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
            && (!fd->secret->nonblocking))
        {
            rv = socket_io_wait(osfd, READ_FD, timeout);
            if ( rv < 0 )
            {
                return -1;
            } 
        } 
        else 
        {
            _PR_MD_MAP_RECV_ERROR(err);
            break;
        }
    } /* end while() */
    return(rv);
}

Here is the call graph for this function:

PRInt32 _PR_MD_RECVFROM ( PRFileDesc fd,
void buf,
PRInt32  amount,
PRIntn  flags,
PRNetAddr addr,
PRUint32 addrlen,
PRIntervalTime  timeout 
)

Definition at line 436 of file w95sock.c.

{
    PRInt32 osfd = fd->secret->md.osfd;
    PRInt32 rv, err;

    while ((rv = recvfrom( osfd, buf, amount, 0, (struct sockaddr *) addr,
            addrlen)) == -1) 
    {
        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
            && (!fd->secret->nonblocking))
        {
            rv = socket_io_wait(osfd, READ_FD, timeout);
            if ( rv < 0)
            {
                return -1;
            } 
        } 
        else 
        {
            _PR_MD_MAP_RECVFROM_ERROR(err);
            break;
        }
    }
    return(rv);
}

Here is the call graph for this function:

PRInt32 _PR_MD_SEND ( PRFileDesc fd,
const void buf,
PRInt32  amount,
PRIntn  flags,
PRIntervalTime  timeout 
)

Definition at line 347 of file w95sock.c.

{
    PRInt32 osfd = fd->secret->md.osfd;
    PRInt32 rv, err;
    PRInt32 bytesSent = 0;

    while(bytesSent < amount ) 
    {
        while ((rv = send( osfd, buf, amount, 0 )) == -1) 
        {
            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
                && (!fd->secret->nonblocking))
            {
                rv = socket_io_wait(osfd, WRITE_FD, timeout);
                if ( rv < 0 )
                {
                    return -1;
                }
            } 
            else 
            {
                _PR_MD_MAP_SEND_ERROR(err);
                return -1;
            }
        }
        bytesSent += rv;
        if (fd->secret->nonblocking)
        {
            break;
        }
        if (bytesSent < amount) 
        {
            rv = socket_io_wait(osfd, WRITE_FD, timeout);
            if ( rv < 0 )
            {
                return -1;
            }
        }
    }
    return bytesSent;
}

Here is the call graph for this function:

PRInt32 _PR_MD_SENDTO ( PRFileDesc fd,
const void buf,
PRInt32  amount,
PRIntn  flags,
const PRNetAddr addr,
PRUint32  addrlen,
PRIntervalTime  timeout 
)

Definition at line 391 of file w95sock.c.

{
    PRInt32 osfd = fd->secret->md.osfd;
    PRInt32 rv, err;
    PRInt32 bytesSent = 0;

    while(bytesSent < amount) 
    {
        while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr,
                addrlen)) == -1) 
        {
            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
                && (!fd->secret->nonblocking))
            {
                rv = socket_io_wait(osfd, WRITE_FD, timeout);
                if ( rv < 0 )
                {
                    return -1;
                }
            } 
            else 
            {
                _PR_MD_MAP_SENDTO_ERROR(err);
                return -1;
            }
        }
        bytesSent += rv;
        if (fd->secret->nonblocking)
        {
            break;
        }
        if (bytesSent < amount) 
        {
            rv = socket_io_wait(osfd, WRITE_FD, timeout);
            if (rv < 0) 
            {
                return -1;
            }
        }
    }
    return bytesSent;
}

Here is the call graph for this function:

PRStatus _PR_MD_SETSOCKOPT ( PRFileDesc fd,
PRInt32  level,
PRInt32  optname,
const char *  optval,
PRInt32  optlen 
)

Definition at line 552 of file w95sock.c.

Here is the call graph for this function:

PRInt32 _PR_MD_SHUTDOWN ( PRFileDesc fd,
PRIntn  how 
)

Definition at line 499 of file w95sock.c.

{
PRInt32 rv;

    rv = shutdown(fd->secret->md.osfd, how);
    if (rv < 0)
        _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());
    return rv;
}

Here is the call graph for this function:

PRInt32 _PR_MD_SOCKET ( int  af,
int  type,
int  flags 
)

Definition at line 147 of file w95sock.c.

{
    SOCKET sock;
    u_long one = 1;

    sock = socket(af, type, flags);

    if (sock == INVALID_SOCKET ) 
    {
        _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError());
        return (PRInt32)sock;
    }

    /*
    ** Make the socket Non-Blocking
    */
    if (ioctlsocket( sock, FIONBIO, &one) != 0)
    {
        PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError());
        closesocket(sock);
        return -1;
    }

    if ((af == AF_INET || af == AF_INET6) && 
        type == SOCK_STREAM && socketSetCompatMode)
    {
        WSA_COMPATIBILITY_MODE mode;
        char dummy[4];
        int ret_dummy;

        mode.BehaviorId = WsaBehaviorAutoTuning;
        mode.TargetOsVersion = NTDDI_LONGHORN;
        if (wsaioctlProc(sock, SIO_SET_COMPATIBILITY_MODE,  
                         (char *)&mode, sizeof(mode),
                         dummy, 4, &ret_dummy, 0, NULL) == SOCKET_ERROR)
        {
            int err = WSAGetLastError();
            PR_LOG(_pr_io_lm, PR_LOG_DEBUG, ("WSAIoctl() failed with %d", err));

            /* SIO_SET_COMPATIBILITY_MODE may not be supported.
            ** If the call to WSAIoctl() fails with WSAEOPNOTSUPP,
            ** don't close the socket.
            */ 
        }
    }

    return (PRInt32)sock;
}

Here is the call graph for this function:

PRInt32 _PR_MD_WRITEV ( PRFileDesc fd,
const PRIOVec iov,
PRInt32  iov_size,
PRIntervalTime  timeout 
)

Definition at line 464 of file w95sock.c.

{
    int index;
    int sent = 0;
    int rv;

    for (index=0; index < iov_size; index++) 
    {
        rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout);
        if (rv > 0) 
            sent += rv;
        if ( rv != iov[index].iov_len ) 
        {
            if (rv < 0)
            {
                if (fd->secret->nonblocking
                    && (PR_GetError() == PR_WOULD_BLOCK_ERROR)
                    && (sent > 0))
                {
                    return sent;
                }
                else
                {
                    return -1;
                }
            }
            /* Only a nonblocking socket can have partial sends */
            PR_ASSERT(fd->secret->nonblocking);
            return sent;
        }
    }
    return sent;
}
typedef int ( __stdcall *  WSAIOCTLPROC)
static PRInt32 socket_io_wait ( PRInt32  osfd,
PRInt32  fd_type,
PRIntervalTime  timeout 
) [static]

Definition at line 583 of file w95sock.c.

{
    PRInt32 rv = -1;
    struct timeval tv;
    PRThread *me = _PR_MD_CURRENT_THREAD();
    PRIntervalTime elapsed, remaining;
    PRBool wait_for_remaining;
    fd_set rd_wr, ex;
    int err, len;

    switch (timeout) {
        case PR_INTERVAL_NO_WAIT:
            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
            break;
        case PR_INTERVAL_NO_TIMEOUT:
            /*
             * This is a special case of the 'default' case below.
             * Please see the comments there.
             */
            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
            tv.tv_usec = 0;
            FD_ZERO(&rd_wr);
            FD_ZERO(&ex);
            do {
                FD_SET(osfd, &rd_wr);
                FD_SET(osfd, &ex);
                switch( fd_type )
                {
                    case READ_FD:
                        rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
                        break;
                    case WRITE_FD:
                        rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
                        break;
                    case CONNECT_FD:
                        rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, &ex, &tv);
                        break;
                    default:
                        PR_ASSERT(0);
                        break;
                } /* end switch() */
                if (rv == -1 )
                {
                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
                    break;
                }
                if ( rv > 0 && fd_type == CONNECT_FD )
                {
                    /*
                     * Call Sleep(0) to work around a Winsock timing bug.
                     */
                    Sleep(0);
                    if (FD_ISSET((SOCKET)osfd, &ex))
                    {
                        len = sizeof(err);
                        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
                                (char *) &err, &len) == SOCKET_ERROR)
                        {  
                            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
                            return -1;
                        }
                        if (err != 0)
                            _PR_MD_MAP_CONNECT_ERROR(err);
                        else
                            PR_SetError(PR_UNKNOWN_ERROR, 0);
                        return -1;
                    }
                    if (FD_ISSET((SOCKET)osfd, &rd_wr))
                    {
                        /* it's connected */
                        return 1;
                    }
                    PR_ASSERT(0);
                }
                if (_PR_PENDING_INTERRUPT(me)) {
                    me->flags &= ~_PR_INTERRUPT;
                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
                    rv = -1;
                    break;
                }
            } while (rv == 0);
            break;
        default:
            remaining = timeout;
            FD_ZERO(&rd_wr);
            FD_ZERO(&ex);
            do {
                /*
                 * We block in _MD_SELECT for at most
                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
                 * so that there is an upper limit on the delay
                 * before the interrupt bit is checked.
                 */
                wait_for_remaining = PR_TRUE;
                tv.tv_sec = PR_IntervalToSeconds(remaining);
                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
                    wait_for_remaining = PR_FALSE;
                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
                    tv.tv_usec = 0;
                } else {
                    tv.tv_usec = PR_IntervalToMicroseconds(
                        remaining -
                        PR_SecondsToInterval(tv.tv_sec));
                }
                FD_SET(osfd, &rd_wr);
                FD_SET(osfd, &ex);
                switch( fd_type )
                {
                    case READ_FD:
                        rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
                        break;
                    case WRITE_FD:
                        rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
                        break;
                    case CONNECT_FD:
                        rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, &ex, &tv);
                        break;
                    default:
                        PR_ASSERT(0);
                        break;
                } /* end switch() */
                if (rv == -1)
                {
                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
                    break;
                }
                if ( rv > 0 && fd_type == CONNECT_FD )
                {
                    /*
                     * Call Sleep(0) to work around a Winsock timing bug.
                     */
                    Sleep(0);
                    if (FD_ISSET((SOCKET)osfd, &ex))
                    {
                        len = sizeof(err);
                        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
                                (char *) &err, &len) == SOCKET_ERROR)
                        {  
                            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
                            return -1;
                        }
                        if (err != 0)
                            _PR_MD_MAP_CONNECT_ERROR(err);
                        else
                            PR_SetError(PR_UNKNOWN_ERROR, 0);
                        return -1;
                    }
                    if (FD_ISSET((SOCKET)osfd, &rd_wr))
                    {
                        /* it's connected */
                        return 1;
                    }
                    PR_ASSERT(0);
                }
                if (_PR_PENDING_INTERRUPT(me)) {
                    me->flags &= ~_PR_INTERRUPT;
                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
                    rv = -1;
                    break;
                }
                /*
                 * We loop again if _MD_SELECT timed out and the
                 * timeout deadline has not passed yet.
                 */
                if (rv == 0 )
                {
                    if (wait_for_remaining) {
                        elapsed = remaining;
                    } else {
                        elapsed = PR_SecondsToInterval(tv.tv_sec) 
                                    + PR_MicrosecondsToInterval(tv.tv_usec);
                    }
                    if (elapsed >= remaining) {
                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
                        rv = -1;
                        break;
                    } else {
                        remaining = remaining - elapsed;
                    }
                }
            } while (rv == 0 );
            break;
    }
    return(rv);
} /* end socket_io_wait() */

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

HMODULE libWinsock2 = NULL [static]

Definition at line 107 of file w95sock.c.

Definition at line 109 of file w95sock.c.

WSAIOCTLPROC wsaioctlProc = NULL [static]

Definition at line 108 of file w95sock.c.