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

📄 unix.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    rv = fsync(fd->secret->md.osfd);    if (rv == -1) {        err = _MD_ERRNO();        _PR_MD_MAP_FSYNC_ERROR(err);    }    return(rv);}PRInt32 _MD_close(PRInt32 osfd){PRInt32 rv, err;    rv = close(osfd);    if (rv == -1) {        err = _MD_ERRNO();        _PR_MD_MAP_CLOSE_ERROR(err);    }    return(rv);}PRInt32 _MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto){    PRInt32 osfd, err;    osfd = socket(domain, type, proto);    if (osfd == -1) {        err = _MD_ERRNO();        _PR_MD_MAP_SOCKET_ERROR(err);        return(osfd);    }    return(osfd);}PRInt32 _MD_socketavailable(PRFileDesc *fd){    PRInt32 result;    if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {        _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());        return -1;    }    return result;}PRInt64 _MD_socketavailable64(PRFileDesc *fd){    PRInt64 result;    LL_I2L(result, _MD_socketavailable(fd));    return result;}  /* _MD_socketavailable64 */#define READ_FD        1#define WRITE_FD    2/* * socket_io_wait -- * * wait for socket i/o, periodically checking for interrupt * * The first implementation uses select(), for platforms without * poll().  The second (preferred) implementation uses poll(). */#ifndef _PR_USE_POLLstatic PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,    PRIntervalTime timeout){    PRInt32 rv = -1;    struct timeval tv;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRIntervalTime epoch, now, elapsed, remaining;    PRBool wait_for_remaining;    PRInt32 syserror;    fd_set rd_wr;    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);            do {                FD_SET(osfd, &rd_wr);                if (fd_type == READ_FD)                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);                else                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {                    _PR_MD_MAP_SELECT_ERROR(syserror);                    break;                }                if (_PR_PENDING_INTERRUPT(me)) {                    me->flags &= ~_PR_INTERRUPT;                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);                    rv = -1;                    break;                }            } while (rv == 0 || (rv == -1 && syserror == EINTR));            break;        default:            now = epoch = PR_IntervalNow();            remaining = timeout;            FD_ZERO(&rd_wr);            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);                if (fd_type == READ_FD)                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);                else                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);                /*                 * we don't consider EINTR a real error                 */                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {                    _PR_MD_MAP_SELECT_ERROR(syserror);                    break;                }                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 or got interrupted                 * by a signal, and the timeout deadline has not passed yet.                 */                if (rv == 0 || (rv == -1 && syserror == EINTR)) {                    /*                     * If _MD_SELECT timed out, we know how much time                     * we spent in blocking, so we can avoid a                     * PR_IntervalNow() call.                     */                    if (rv == 0) {                        if (wait_for_remaining) {                            now += remaining;                        } else {                            now += PR_SecondsToInterval(tv.tv_sec)                                + PR_MicrosecondsToInterval(tv.tv_usec);                        }                    } else {                        now = PR_IntervalNow();                    }                    elapsed = (PRIntervalTime) (now - epoch);                    if (elapsed >= timeout) {                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);                        rv = -1;                        break;                    } else {                        remaining = timeout - elapsed;                    }                }            } while (rv == 0 || (rv == -1 && syserror == EINTR));            break;    }    return(rv);}#else /* _PR_USE_POLL */static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,    PRIntervalTime timeout){    PRInt32 rv = -1;    int msecs;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRIntervalTime epoch, now, elapsed, remaining;    PRBool wait_for_remaining;    PRInt32 syserror;    struct pollfd pfd;    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.             */            msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;            pfd.fd = osfd;            if (fd_type == READ_FD) {                pfd.events = POLLIN;            } else {                pfd.events = POLLOUT;            }            do {                rv = _MD_POLL(&pfd, 1, msecs);                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {                    _PR_MD_MAP_POLL_ERROR(syserror);                    break;                }				/*				 * If POLLERR is set, don't process it; retry the operation				 */                if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {					rv = -1;                    _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);                    break;                }                if (_PR_PENDING_INTERRUPT(me)) {                    me->flags &= ~_PR_INTERRUPT;                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);                    rv = -1;                    break;                }            } while (rv == 0 || (rv == -1 && syserror == EINTR));            break;        default:            now = epoch = PR_IntervalNow();            remaining = timeout;            pfd.fd = osfd;            if (fd_type == READ_FD) {                pfd.events = POLLIN;            } else {                pfd.events = POLLOUT;            }            do {                /*                 * We block in _MD_POLL 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;                msecs = PR_IntervalToMilliseconds(remaining);                if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {                    wait_for_remaining = PR_FALSE;                    msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;                }                rv = _MD_POLL(&pfd, 1, msecs);                /*                 * we don't consider EINTR a real error                 */                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {                    _PR_MD_MAP_POLL_ERROR(syserror);                    break;                }                if (_PR_PENDING_INTERRUPT(me)) {                    me->flags &= ~_PR_INTERRUPT;                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);                    rv = -1;                    break;                }				/*				 * If POLLERR is set, don't process it; retry the operation				 */                if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {					rv = -1;                    _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);                    break;                }                /*                 * We loop again if _MD_POLL timed out or got interrupted                 * by a signal, and the timeout deadline has not passed yet.                 */                if (rv == 0 || (rv == -1 && syserror == EINTR)) {                    /*                     * If _MD_POLL timed out, we know how much time                     * we spent in blocking, so we can avoid a                     * PR_IntervalNow() call.                     */                    if (rv == 0) {                        if (wait_for_remaining) {                            now += remaining;                        } else {                            now += PR_MillisecondsToInterval(msecs);                        }                    } else {                        now = PR_IntervalNow();                    }                    elapsed = (PRIntervalTime) (now - epoch);                    if (elapsed >= timeout) {                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);                        rv = -1;                        break;                    } else {                        remaining = timeout - elapsed;                    }                }            } while (rv == 0 || (rv == -1 && syserror == EINTR));            break;    }    return(rv);}#endif /* _PR_USE_POLL */static PRInt32 local_io_wait(    PRInt32 osfd,    PRInt32 wait_flag,    PRIntervalTime timeout){    _PRUnixPollDesc pd;    PRInt32 rv;    PR_LOG(_pr_io_lm, PR_LOG_MIN,       ("waiting to %s on osfd=%d",        (wait_flag == _PR_UNIX_POLL_READ) ? "read" : "write",        osfd));    if (timeout == PR_INTERVAL_NO_WAIT) return 0;    pd.osfd = osfd;    pd.in_flags = wait_flag;    pd.out_flags = 0;    rv = _PR_WaitForMultipleFDs(&pd, 1, timeout);    if (rv == 0) {        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);        rv = -1;    }    return rv;}PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,                                PRInt32 flags, PRIntervalTime timeout){    PRInt32 osfd = fd->secret->md.osfd;    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();/* * Many OS's (Solaris, Unixware) have a broken recv which won't read * from socketpairs.  As long as we don't use flags on socketpairs, this * is a decent fix. - mikep */#if defined(UNIXWARE) || defined(SOLARIS) || defined(NCR)    while ((rv = read(osfd,buf,amount)) == -1) {#else    while ((rv = recv(osfd,buf,amount,flags)) == -1) {#endif        err = _MD_ERRNO();        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {            if (fd->secret->nonblocking) {                break;            }            if (!_PR_IS_NATIVE_THREAD(me)) {				if ((rv = local_io_wait(osfd,_PR_UNIX_POLL_READ,timeout)) < 0)					goto done;            } else {                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)                    goto done;            }        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){            continue;        } else {            break;        }    }    if (rv < 0) {        _PR_MD_MAP_RECV_ERROR(err);    }done:    return(rv);}PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,                        PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,                        PRIntervalTime timeout){    PRInt32 osfd = fd->secret->md.osfd;    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();    while ((*addrlen = PR_NETADDR_SIZE(addr)),                ((rv = recvfrom(osfd, buf, amount, flags,                        (struct sockaddr *) addr, (_PRSockLen_t *)addrlen)) == -1)) {        err = _MD_ERRNO();        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {            if (fd->secret->nonblocking) {                break;            }            if (!_PR_IS_NATIVE_THREAD(me)) {                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)                    goto done;            } else {                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)                    goto done;            }        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){            continue;        } else {            break;        }    }    if (rv < 0) {        _PR_MD_MAP_RECVFROM_ERROR(err);    }done:#ifdef _PR_HAVE_SOCKADDR_LEN    if (rv != -1) {        /* ignore the sa_len field of struct sockaddr */        if (addr) {            addr->raw.family = ((struct sockaddr *) addr)->sa_family;        }    }#endif /* _PR_HAVE_SOCKADDR_LEN */    return(rv);}PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,                            PRInt32 flags, PRIntervalTime timeout){    PRInt32 osfd = fd->secret->md.osfd;    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();#if defined(SOLARIS)	PRInt32 tmp_amount = amount;#endif    /*

⌨️ 快捷键说明

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