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

📄 ptio.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Ensured by PR_Writev */    PR_ASSERT(iov_len <= PR_MAX_IOVECTOR_SIZE);    /*     * We can't pass iov to writev because PRIOVec and struct iovec     * may not be binary compatible.  Make osiov a copy of iov and     * pass osiov to writev.  We can modify osiov if we need to     * continue the operation.     */    osiov = osiov_local;    osiov_len = iov_len;    for (iov_index = 0; iov_index < osiov_len; iov_index++)    {        osiov[iov_index].iov_base = iov[iov_index].iov_base;        osiov[iov_index].iov_len = iov[iov_index].iov_len;    }    rv = bytes = writev(fd->secret->md.osfd, osiov, osiov_len);    syserrno = errno;    if (!fd->secret->nonblocking)    {        if (bytes >= 0)        {            /*             * If we moved some bytes, how does that implicate the             * i/o vector list?  In other words, exactly where are             * we within that array?  What are the parameters for             * resumption?  Maybe we're done!             */            for ( ;osiov_len > 0; osiov++, osiov_len--)            {                if (bytes < osiov->iov_len)                {                    /* this one's not done yet */                    osiov->iov_base = (char*)osiov->iov_base + bytes;                    osiov->iov_len -= bytes;                    break;  /* go off and do that */                }                bytes -= osiov->iov_len;  /* this one's done cooked */            }            PR_ASSERT(osiov_len > 0 || bytes == 0);            if (osiov_len > 0)            {                if (PR_INTERVAL_NO_WAIT == timeout)                {                    rv = -1;                    syserrno = ETIMEDOUT;                }                else fNeedContinue = PR_TRUE;            }        }        else if (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        {            if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;            else            {                rv = 0;                fNeedContinue = PR_TRUE;            }        }    }    if (fNeedContinue == PR_TRUE)    {        pt_Continuation op;        op.arg1.osfd = fd->secret->md.osfd;        op.arg2.buffer = (void*)osiov;        op.arg3.amount = osiov_len;        op.timeout = timeout;        op.result.code = rv;        op.function = pt_writev_cont;        op.event = POLLOUT | POLLPRI;        rv = pt_Continue(&op);        syserrno = op.syserrno;    }    if (rv == -1) pt_MapError(_PR_MD_MAP_WRITEV_ERROR, syserrno);    return rv;}  /* pt_Writev */static PRInt32 pt_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence){    return _PR_MD_LSEEK(fd, offset, whence);}  /* pt_Seek */static PRInt64 pt_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence){    return _PR_MD_LSEEK64(fd, offset, whence);}  /* pt_Seek64 */static PRInt32 pt_Available_f(PRFileDesc *fd){    PRInt32 result, cur, end;    cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);    if (cur >= 0)        end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);    if ((cur < 0) || (end < 0)) {        return -1;    }    result = end - cur;    _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);    return result;}  /* pt_Available_f */static PRInt64 pt_Available64_f(PRFileDesc *fd){    PRInt64 result, cur, end;    PRInt64 minus_one;    LL_I2L(minus_one, -1);    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);    if (LL_GE_ZERO(cur))        end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;    LL_SUB(result, end, cur);    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);    return result;}  /* pt_Available64_f */static PRInt32 pt_Available_s(PRFileDesc *fd){    PRInt32 rv, bytes = -1;    if (pt_TestAbort()) return bytes;    rv = ioctl(fd->secret->md.osfd, FIONREAD, &bytes);    if (rv == -1)        pt_MapError(_PR_MD_MAP_SOCKETAVAILABLE_ERROR, errno);    return bytes;}  /* pt_Available_s */static PRInt64 pt_Available64_s(PRFileDesc *fd){    PRInt64 rv;    LL_I2L(rv, pt_Available_s(fd));    return rv;}  /* pt_Available64_s */static PRStatus pt_FileInfo(PRFileDesc *fd, PRFileInfo *info){    PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, info);    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;}  /* pt_FileInfo */static PRStatus pt_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info){    PRInt32 rv = _PR_MD_GETOPENFILEINFO64(fd, info);    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;}  /* pt_FileInfo64 */static PRStatus pt_Synch(PRFileDesc *fd){    return (NULL == fd) ? PR_FAILURE : PR_SUCCESS;} /* pt_Synch */static PRStatus pt_Fsync(PRFileDesc *fd){    PRIntn rv = -1;    if (pt_TestAbort()) return PR_FAILURE;    rv = fsync(fd->secret->md.osfd);    if (rv < 0) {        pt_MapError(_PR_MD_MAP_FSYNC_ERROR, errno);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* pt_Fsync */static PRStatus pt_Connect(    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout){    PRIntn rv = -1, syserrno;    pt_SockLen addr_len;	const PRNetAddr *addrp = addr;#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)	PRUint16 md_af = addr->raw.family;    PRNetAddr addrCopy;#endif    if (pt_TestAbort()) return PR_FAILURE;    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);    addr_len = PR_NETADDR_SIZE(addr);#if defined(_PR_INET6)	if (addr->raw.family == PR_AF_INET6) {		md_af = AF_INET6;#ifndef _PR_HAVE_SOCKADDR_LEN		addrCopy = *addr;		addrCopy.raw.family = AF_INET6;		addrp = &addrCopy;#endif	}#endif#ifdef _PR_HAVE_SOCKADDR_LEN    addrCopy = *addr;    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;    ((struct sockaddr*)&addrCopy)->sa_family = md_af;    rv = connect(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len);#else    rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);#endif    syserrno = errno;    if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking))    {        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;        else        {            pt_Continuation op;            op.arg1.osfd = fd->secret->md.osfd;#ifdef _PR_HAVE_SOCKADDR_LEN            op.arg2.buffer = (void*)&addrCopy;#else            op.arg2.buffer = (void*)addr;#endif            op.arg3.amount = addr_len;            op.timeout = timeout;            op.function = pt_connect_cont;            op.event = POLLOUT | POLLPRI;            rv = pt_Continue(&op);            syserrno = op.syserrno;        }    }    if (-1 == rv) {        pt_MapError(_PR_MD_MAP_CONNECT_ERROR, syserrno);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* pt_Connect */static PRStatus pt_ConnectContinue(    PRFileDesc *fd, PRInt16 out_flags){    int err;    PRInt32 osfd;    if (out_flags & PR_POLL_NVAL)    {        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);        return PR_FAILURE;    }    if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0)    {        PR_ASSERT(out_flags == 0);        PR_SetError(PR_IN_PROGRESS_ERROR, 0);        return PR_FAILURE;    }    osfd = fd->secret->md.osfd;    err = _MD_unix_get_nonblocking_connect_error(osfd);    if (err != 0)    {        _PR_MD_MAP_CONNECT_ERROR(err);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* pt_ConnectContinue */PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd){    /* Find the NSPR layer and invoke its connectcontinue method */    PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);    if (NULL == bottom)    {        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);        return PR_FAILURE;    }    return pt_ConnectContinue(bottom, pd->out_flags);}  /* PR_GetConnectStatus */static PRFileDesc* pt_Accept(    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout){    PRFileDesc *newfd = NULL;    PRIntn syserrno, osfd = -1;    pt_SockLen addr_len = sizeof(PRNetAddr);    if (pt_TestAbort()) return newfd;#ifdef _PR_STRICT_ADDR_LEN    if (addr)    {        /*         * Set addr->raw.family just so that we can use the         * PR_NETADDR_SIZE macro.         */        addr->raw.family = fd->secret->af;        addr_len = PR_NETADDR_SIZE(addr);    }#endif    osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);    syserrno = errno;    if (osfd == -1)    {        if (fd->secret->nonblocking) goto failed;        if (EWOULDBLOCK != syserrno && EAGAIN != syserrno        && ECONNABORTED != syserrno)            goto failed;        else        {            if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;            else            {                pt_Continuation op;                op.arg1.osfd = fd->secret->md.osfd;                op.arg2.buffer = addr;                op.arg3.addr_len = &addr_len;                op.timeout = timeout;                op.function = pt_accept_cont;                op.event = POLLIN | POLLPRI;                osfd = pt_Continue(&op);                syserrno = op.syserrno;            }            if (osfd < 0) goto failed;        }    }#ifdef _PR_HAVE_SOCKADDR_LEN    /* ignore the sa_len field of struct sockaddr */    if (addr)    {        addr->raw.family = ((struct sockaddr*)addr)->sa_family;    }#endif /* _PR_HAVE_SOCKADDR_LEN */#ifdef _PR_INET6	if (addr && (AF_INET6 == addr->raw.family))        addr->raw.family = PR_AF_INET6;#endif    newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_TRUE, PR_FALSE);    if (newfd == NULL) close(osfd);  /* $$$ whoops! this doesn't work $$$ */    else    {        PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);        PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);#ifdef LINUX        /*         * On Linux, experiments showed that the accepted sockets         * inherit the TCP_NODELAY socket option of the listening         * socket.         */        newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay;#endif    }    return newfd;failed:    pt_MapError(_PR_MD_MAP_ACCEPT_ERROR, syserrno);    return NULL;}  /* pt_Accept */static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr){    PRIntn rv;    pt_SockLen addr_len;	const PRNetAddr *addrp = addr;#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)	PRUint16 md_af = addr->raw.family;    PRNetAddr addrCopy;#endif    if (pt_TestAbort()) return PR_FAILURE;    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);    if (addr->raw.family == AF_UNIX)    {        /* Disallow relative pathnames */        if (addr->local.path[0] != '/')        {            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);            return PR_FAILURE;        }    }#if defined(_PR_INET6)	if (addr->raw.family == PR_AF_INET6) {		md_af = AF_INET6;#ifndef _PR_HAVE_SOCKADDR_LEN		addrCopy = *addr;		addrCopy.raw.family = AF_INET6;		addrp = &addrCopy;#endif	}#endif    addr_len = PR_NETADDR_SIZE(addr);#ifdef _PR_HAVE_SOCKADDR_LEN    addrCopy = *addr;    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;    ((struct sockaddr*)&addrCopy)->sa_family = md_af;    rv = bind(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len);#else    rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);#endif    if (rv == -1) {        pt_MapError(_PR_MD_MAP_BIND_ERROR, errno);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* pt_Bind */static PRStatus pt_Listen(PRFileDesc *fd, PRIntn backlog){    PRIntn rv;    if (pt_TestAbort()) return PR_FAILURE;    rv = listen(fd->secret->md.osfd, backlog);    if (rv == -1) {        pt_MapError(_PR_MD_MAP_LISTEN_ERROR, errno);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* pt_Listen */static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how){    PRIntn rv = -1;    if (pt_TestAbort()) return PR_FAILURE;    rv = shutdown(fd->secret->md.osfd, how);    if (rv == -1) {        pt_MapError(_PR_MD_MAP_SHUTDOWN_ERROR, errno);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* pt_Shutdown */static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags){

⌨️ 快捷键说明

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