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

📄 unix.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
     * On pre-2.6 Solaris, send() is much slower than write().     * On 2.6 and beyond, with in-kernel sockets, send() and     * write() are fairly equivalent in performance.     */#if defined(SOLARIS)    PR_ASSERT(0 == flags);    while ((rv = write(osfd,buf,tmp_amount)) == -1) {#else    while ((rv = send(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_WRITE, timeout)) < 0)                    goto done;            } else {                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)                    goto done;            }        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){            continue;        } else {#if defined(SOLARIS)			/*			 * The write system call has been reported to return the ERANGE			 * error on occasion. Try to write in smaller chunks to workaround			 * this bug.			 */			if (err == ERANGE) {				if (tmp_amount > 1) {					tmp_amount = tmp_amount/2;	/* half the bytes */					continue;				}			}#endif            break;        }    }        /*         * optimization; if bytes sent is less than "amount" call         * select before returning. This is because it is likely that         * the next send() call will return EWOULDBLOCK.         */    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)            && (timeout != PR_INTERVAL_NO_WAIT)) {        if (_PR_IS_NATIVE_THREAD(me)) {			if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) {				rv = -1;				goto done;			}        } else {			if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {				rv = -1;				goto done;			}        }    }    if (rv < 0) {        _PR_MD_MAP_SEND_ERROR(err);    }done:    return(rv);}PRInt32 _MD_sendto(    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,    const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout){    PRInt32 osfd = fd->secret->md.osfd;    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();#ifdef _PR_HAVE_SOCKADDR_LEN    PRNetAddr addrCopy;    addrCopy = *addr;    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;    while ((rv = sendto(osfd, buf, amount, flags,            (struct sockaddr *) &addrCopy, addrlen)) == -1) {#else    while ((rv = sendto(osfd, buf, amount, flags,            (struct sockaddr *) addr, addrlen)) == -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_WRITE, timeout)) < 0)					goto done;            } else {                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)                    goto done;            }        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){            continue;        } else {            break;        }    }    if (rv < 0) {        _PR_MD_MAP_SENDTO_ERROR(err);    }done:    return(rv);}PRInt32 _MD_writev(    PRFileDesc *fd, const PRIOVec *iov,    PRInt32 iov_size, PRIntervalTime timeout){    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRInt32 index, amount = 0;    PRInt32 osfd = fd->secret->md.osfd;    /*     * Calculate the total number of bytes to be sent; needed for     * optimization later.     * We could avoid this if this number was passed in; but it is     * probably not a big deal because iov_size is usually small (less than     * 3)     */    if (!fd->secret->nonblocking) {        for (index=0; index<iov_size; index++) {            amount += iov[index].iov_len;        }    }    while ((rv = writev(osfd, (const struct iovec*)iov, iov_size)) == -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_WRITE, timeout)) < 0)					goto done;            } else {                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)                    goto done;            }        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){            continue;        } else {            break;        }    }    /*     * optimization; if bytes sent is less than "amount" call     * select before returning. This is because it is likely that     * the next writev() call will return EWOULDBLOCK.     */    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)            && (timeout != PR_INTERVAL_NO_WAIT)) {        if (_PR_IS_NATIVE_THREAD(me)) {            if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {				rv = -1;                goto done;			}        } else {			if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {				rv = -1;				goto done;			}        }    }    if (rv < 0) {        _PR_MD_MAP_WRITEV_ERROR(err);    }done:    return(rv);}PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,                            PRUint32 *addrlen, PRIntervalTime timeout){    PRInt32 osfd = fd->secret->md.osfd;    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();    while ((rv = accept(osfd, (struct sockaddr *) addr,                                        (_PRSockLen_t *)addrlen)) == -1) {        err = _MD_ERRNO();        if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == ECONNABORTED)) {            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_ACCEPT_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);}extern int _connect (int s, const struct sockaddr *name, int namelen);PRInt32 _MD_connect(    PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout){    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRInt32 osfd = fd->secret->md.osfd;#ifdef IRIXextern PRInt32 _MD_irix_connect(        PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout);#endif#ifdef _PR_HAVE_SOCKADDR_LEN    PRNetAddr addrCopy;    addrCopy = *addr;    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;#endif    /*     * We initiate the connection setup by making a nonblocking connect()     * call.  If the connect() call fails, there are two cases we handle     * specially:     * 1. The connect() call was interrupted by a signal.  In this case     *    we simply retry connect().     * 2. The NSPR socket is nonblocking and connect() fails with     *    EINPROGRESS.  We first wait until the socket becomes writable.     *    Then we try to find out whether the connection setup succeeded     *    or failed.     */retry:#ifdef IRIX    if ((rv = _MD_irix_connect(osfd, addr, addrlen, timeout)) == -1) {#else#ifdef _PR_HAVE_SOCKADDR_LEN    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {#else    if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {#endif#endif        err = _MD_ERRNO();        if (err == EINTR) {            if (_PR_PENDING_INTERRUPT(me)) {                me->flags &= ~_PR_INTERRUPT;                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);                return -1;            }            goto retry;        }        if (!fd->secret->nonblocking && (err == EINPROGRESS)) {            if (!_PR_IS_NATIVE_THREAD(me)) {				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)                    return -1;            } else {                /*                 * socket_io_wait() may return -1 or 1.                 */                rv = socket_io_wait(osfd, WRITE_FD, timeout);                if (rv == -1) {                    return -1;                }            }            PR_ASSERT(rv == 1);            if (_PR_PENDING_INTERRUPT(me)) {                me->flags &= ~_PR_INTERRUPT;                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);                return -1;            }            err = _MD_unix_get_nonblocking_connect_error(osfd);            if (err != 0) {                _PR_MD_MAP_CONNECT_ERROR(err);                return -1;            }            return 0;        }        _PR_MD_MAP_CONNECT_ERROR(err);    }    return rv;}  /* _MD_connect */PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen){    PRInt32 rv, err;#ifdef _PR_HAVE_SOCKADDR_LEN    PRNetAddr addrCopy;    addrCopy = *addr;    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;    rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);#else    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);#endif    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_BIND_ERROR(err);    }    return(rv);}PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog){    PRInt32 rv, err;    rv = listen(fd->secret->md.osfd, backlog);    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_LISTEN_ERROR(err);    }    return(rv);}PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how){    PRInt32 rv, err;    rv = shutdown(fd->secret->md.osfd, how);    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_SHUTDOWN_ERROR(err);    }    return(rv);}PRInt32 _MD_socketpair(int af, int type, int flags,                                                        PRInt32 *osfd){    PRInt32 rv, err;    rv = socketpair(af, type, flags, osfd);    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_SOCKETPAIR_ERROR(err);    }    return rv;}PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,                                                PRUint32 *addrlen){    PRInt32 rv, err;    rv = getsockname(fd->secret->md.osfd,            (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);#ifdef _PR_HAVE_SOCKADDR_LEN    if (rv == 0) {        /* ignore the sa_len field of struct sockaddr */        if (addr) {            addr->raw.family = ((struct sockaddr *) addr)->sa_family;        }    }#endif /* _PR_HAVE_SOCKADDR_LEN */    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_GETSOCKNAME_ERROR(err);    }    return rv==0?PR_SUCCESS:PR_FAILURE;}PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,                                        PRUint32 *addrlen){    PRInt32 rv, err;    rv = getpeername(fd->secret->md.osfd,            (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);#ifdef _PR_HAVE_SOCKADDR_LEN    if (rv == 0) {        /* ignore the sa_len field of struct sockaddr */        if (addr) {            addr->raw.family = ((struct sockaddr *) addr)->sa_family;        }    }#endif /* _PR_HAVE_SOCKADDR_LEN */    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_GETPEERNAME_ERROR(err);    }    return rv==0?PR_SUCCESS:PR_FAILURE;}PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,                        PRInt32 optname, char* optval, PRInt32* optlen){    PRInt32 rv, err;    rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (_PRSockLen_t *)optlen);    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_GETSOCKOPT_ERROR(err);    }    return rv==0?PR_SUCCESS:PR_FAILURE;}PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,                       PRInt32 optname, const char* optval, PRInt32 optlen){    PRInt32 rv, err;    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);    if (rv < 0) {        err = _MD_ERRNO();        _PR_MD_MAP_SETSOCKOPT_ERROR(err);    }    return rv==0?PR_SUCCESS:PR_FAILURE;}PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable){    int rv;    rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);

⌨️ 快捷键说明

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