⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w95sock.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    {        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);}PRInt32_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout){    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;}PRInt32_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how){PRInt32 rv;    rv = shutdown(fd->secret->md.osfd, how);    if (rv < 0)        _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());    return rv;}PRStatus_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len){    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;    }}PRStatus_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len){    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;    }}PRStatus_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen){    PRInt32 rv;    rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);    if (rv==0) {        return PR_SUCCESS;    } else {        _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());        return PR_FAILURE;    }}PRStatus_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen){    PRInt32 rv;    rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);    if (rv==0) {        return PR_SUCCESS;    } else {        _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError());        return PR_FAILURE;    }}void_MD_MakeNonblock(PRFileDesc *f){    return; /* do nothing */}/* * socket_io_wait -- * * Wait for socket i/o, periodically checking for interrupt. * * This function returns 1 on success.  On failure, it returns * -1 and sets the error codes.  It never returns 0. */#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5static PRInt32 socket_io_wait(    PRInt32 osfd,     PRInt32 fd_type,    PRIntervalTime timeout){    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() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -