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

📄 ptio.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                char **bp = (char**)&(iov[iov_index].iov_base);                iov[iov_index].iov_len -= bytes;  /* there's that much left */                *bp += bytes;  /* starting there */                break;  /* go off and do that */            }            bytes -= iov[iov_index].iov_len;  /* that element's consumed */        }        op->arg2.buffer = &iov[iov_index];  /* new start of array */        op->arg3.amount -= iov_index;  /* and array length */        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;    }    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))    {        op->result.code = -1;        return PR_TRUE;    }    else return PR_FALSE;}  /* pt_writev_cont */static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents){    PRIntn bytes = sendto(        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags,        (struct sockaddr*)op->arg5.addr, PR_NETADDR_SIZE(op->arg5.addr));    op->syserrno = errno;    if (bytes >= 0)  /* this is progress */    {        char *bp = (char*)op->arg2.buffer;        bp += bytes;  /* adjust the buffer pointer */        op->arg2.buffer = bp;        op->result.code += bytes;  /* accumulate the number sent */        op->arg3.amount -= bytes;  /* and reduce the required count */        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;    }    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))    {        op->result.code = -1;        return PR_TRUE;    }    else return PR_FALSE;}  /* pt_sendto_cont */static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents){    pt_SockLen addr_len = sizeof(PRNetAddr);    op->result.code = recvfrom(        op->arg1.osfd, op->arg2.buffer, op->arg3.amount,        op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len);    op->syserrno = errno;    return ((-1 == op->result.code) &&             (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?        PR_FALSE : PR_TRUE;}  /* pt_recvfrom_cont */#ifdef AIXstatic PRBool pt_aix_sendfile_cont(pt_Continuation *op, PRInt16 revents){    struct sf_parms *sf_struct = (struct sf_parms *) op->arg2.buffer;    ssize_t rv;	unsigned long long saved_file_offset;	long long saved_file_bytes;	saved_file_offset = sf_struct->file_offset;	saved_file_bytes = sf_struct->file_bytes;	sf_struct->bytes_sent = 0;	if ((sf_struct->file_bytes > 0) && (sf_struct->file_size > 0))	PR_ASSERT((sf_struct->file_bytes + sf_struct->file_offset) <=									sf_struct->file_size);    rv = AIX_SEND_FILE(&op->arg1.osfd, sf_struct, op->arg4.flags);    op->syserrno = errno;    if (rv != -1) {        op->result.code += sf_struct->bytes_sent;		/*		 * A bug in AIX 4.3.2 prevents the 'file_bytes' field from		 * being updated. So, 'file_bytes' is maintained by NSPR to		 * avoid conflict when this bug is fixed in AIX, in the future.		 */		if (saved_file_bytes != -1)			saved_file_bytes -= (sf_struct->file_offset - saved_file_offset);		sf_struct->file_bytes = saved_file_bytes;    } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {        op->result.code = -1;    } else {        return PR_FALSE;    }    if (rv == 1) {    /* more data to send */        return PR_FALSE;    }    return PR_TRUE;}#endif  /* AIX */#ifdef HPUX11static PRBool pt_hpux_sendfile_cont(pt_Continuation *op, PRInt16 revents){    struct iovec *hdtrl = (struct iovec *) op->arg2.buffer;    int count;    count = sendfile(op->arg1.osfd, op->filedesc, op->arg3.file_spec.offset,			op->arg3.file_spec.nbytes, hdtrl, op->arg4.flags);    PR_ASSERT(count <= op->nbytes_to_send);    op->syserrno = errno;    if (count != -1) {        op->result.code += count;    } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {        op->result.code = -1;    } else {        return PR_FALSE;    }    if (count != -1 && count < op->nbytes_to_send) {        if (count < hdtrl[0].iov_len) {			/* header not sent */            hdtrl[0].iov_base = ((char *) hdtrl[0].iov_len) + count;            hdtrl[0].iov_len -= count;        } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes)) {			/* header sent, file not sent */            PRUint32 file_nbytes_sent = count - hdtrl[0].iov_len;            hdtrl[0].iov_base = NULL;            hdtrl[0].iov_len = 0;            op->arg3.file_spec.offset += file_nbytes_sent;            op->arg3.file_spec.nbytes -= file_nbytes_sent;        } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes +											hdtrl[1].iov_len)) {            PRUint32 trailer_nbytes_sent = count - (hdtrl[0].iov_len +                                         op->arg3.file_spec.nbytes);			/* header sent, file sent, trailer not sent */            hdtrl[0].iov_base = NULL;            hdtrl[0].iov_len = 0;			/*			 * set file offset and len so that no more file data is			 * sent			 */            op->arg3.file_spec.offset = op->arg3.file_spec.st_size;            op->arg3.file_spec.nbytes = 0;            hdtrl[1].iov_base =((char *) hdtrl[1].iov_base)+ trailer_nbytes_sent;            hdtrl[1].iov_len -= trailer_nbytes_sent;		}        op->nbytes_to_send -= count;        return PR_FALSE;    }    return PR_TRUE;}#endif  /* HPUX11 */#ifdef SOLARIS  static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents){    struct sendfilevec *vec = (struct sendfilevec *) op->arg2.buffer;    size_t xferred;    ssize_t count;    count = SOLARIS_SENDFILEV(op->arg1.osfd, vec, op->arg3.amount, &xferred);    op->syserrno = errno;    PR_ASSERT((count == -1) || (count == xferred));    if (count == -1) {        if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN                && op->syserrno != EINTR) {            op->result.code = -1;            return PR_TRUE;        }        count = xferred;    }    PR_ASSERT(count <= op->nbytes_to_send);        op->result.code += count;    if (count < op->nbytes_to_send) {        op->nbytes_to_send -= count;        while (count >= vec->sfv_len) {            count -= vec->sfv_len;            vec++;            op->arg3.amount--;        }        PR_ASSERT(op->arg3.amount > 0);        vec->sfv_off += count;        vec->sfv_len -= count;        PR_ASSERT(vec->sfv_len > 0);        op->arg2.buffer = vec;        return PR_FALSE;    }    return PR_TRUE;}#endif  /* SOLARIS */#ifdef LINUX static PRBool pt_linux_sendfile_cont(pt_Continuation *op, PRInt16 revents){    ssize_t rv;    off_t oldoffset;    oldoffset = op->offset;    rv = sendfile(op->arg1.osfd, op->in_fd, &op->offset, op->count);    op->syserrno = errno;    if (rv == -1) {        if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {            op->result.code = -1;            return PR_TRUE;        }        rv = 0;    }    PR_ASSERT(rv == op->offset - oldoffset);    op->result.code += rv;    if (rv < op->count) {        op->count -= rv;        return PR_FALSE;    }    return PR_TRUE;}#endif  /* LINUX */void _PR_InitIO(void){#if defined(DEBUG)    memset(&pt_debug, 0, sizeof(PTDebug));    pt_debug.timeStarted = PR_Now();#endif    _pr_flock_lock = PR_NewLock();    PR_ASSERT(NULL != _pr_flock_lock);    _pr_flock_cv = PR_NewCondVar(_pr_flock_lock);    PR_ASSERT(NULL != _pr_flock_cv);    _pr_rename_lock = PR_NewLock();    PR_ASSERT(NULL != _pr_rename_lock);     _PR_InitFdCache();  /* do that */       _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE, PR_TRUE);    _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE, PR_TRUE);    _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE, PR_TRUE);    PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr);}  /* _PR_InitIO */void _PR_CleanupIO(void){    _PR_Putfd(_pr_stdin);    _pr_stdin = NULL;    _PR_Putfd(_pr_stdout);    _pr_stdout = NULL;    _PR_Putfd(_pr_stderr);     _pr_stderr = NULL;    _PR_CleanupFdCache();        if (_pr_flock_cv)    {        PR_DestroyCondVar(_pr_flock_cv);        _pr_flock_cv = NULL;    }    if (_pr_flock_lock)    {        PR_DestroyLock(_pr_flock_lock);        _pr_flock_lock = NULL;    }    if (_pr_rename_lock)    {        PR_DestroyLock(_pr_rename_lock);        _pr_rename_lock = NULL;    }}  /* _PR_CleanupIO */PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd){    PRFileDesc *result = NULL;    PR_ASSERT(osfd >= PR_StandardInput && osfd <= PR_StandardError);    if (!_pr_initialized) _PR_ImplicitInitialization();        switch (osfd)    {        case PR_StandardInput: result = _pr_stdin; break;        case PR_StandardOutput: result = _pr_stdout; break;        case PR_StandardError: result = _pr_stderr; break;        default:            (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);    }    return result;}  /* PR_GetSpecialFD *//*****************************************************************************//***************************** I/O private methods ***************************//*****************************************************************************/static PRBool pt_TestAbort(void){    PRThread *me = PR_CurrentThread();    if(_PT_THREAD_INTERRUPTED(me))    {        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);        me->state &= ~PT_THREAD_ABORTED;        return PR_TRUE;    }    return PR_FALSE;}  /* pt_TestAbort */static void pt_MapError(void (*mapper)(PRIntn), PRIntn syserrno){    switch (syserrno)    {        case EINTR:            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); break;        case ETIMEDOUT:            PR_SetError(PR_IO_TIMEOUT_ERROR, 0); break;        default:            mapper(syserrno);    }}  /* pt_MapError */static PRStatus pt_Close(PRFileDesc *fd){    if ((NULL == fd) || (NULL == fd->secret)        || ((_PR_FILEDESC_OPEN != fd->secret->state)        && (_PR_FILEDESC_CLOSED != fd->secret->state)))    {        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);        return PR_FAILURE;    }    if (pt_TestAbort()) return PR_FAILURE;    if (_PR_FILEDESC_OPEN == fd->secret->state)    {        if (-1 == close(fd->secret->md.osfd))        {#ifdef OSF1            /*             * Bug 86941: On Tru64 UNIX V5.0A and V5.1, the close()             * system call, when called to close a TCP socket, may             * return -1 with errno set to EINVAL but the system call             * does close the socket successfully.  An application             * may safely ignore the EINVAL error.  This bug is fixed             * on Tru64 UNIX V5.1A and later.  The defect tracking             * number is QAR 81431.             */            if (PR_DESC_SOCKET_TCP != fd->methods->file_type            || EINVAL != errno)            {                pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno);                return PR_FAILURE;            }#else            pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno);            return PR_FAILURE;#endif        }        fd->secret->state = _PR_FILEDESC_CLOSED;    }    _PR_Putfd(fd);    return PR_SUCCESS;}  /* pt_Close */static PRInt32 pt_Read(PRFileDesc *fd, void *buf, PRInt32 amount){    PRInt32 syserrno, bytes = -1;    if (pt_TestAbort()) return bytes;    bytes = read(fd->secret->md.osfd, buf, amount);    syserrno = errno;    if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        && (!fd->secret->nonblocking))    {        pt_Continuation op;        op.arg1.osfd = fd->secret->md.osfd;        op.arg2.buffer = buf;        op.arg3.amount = amount;        op.timeout = PR_INTERVAL_NO_TIMEOUT;        op.function = pt_read_cont;        op.event = POLLIN | POLLPRI;        bytes = pt_Continue(&op);        syserrno = op.syserrno;    }    if (bytes < 0)        pt_MapError(_PR_MD_MAP_READ_ERROR, syserrno);    return bytes;}  /* pt_Read */static PRInt32 pt_Write(PRFileDesc *fd, const void *buf, PRInt32 amount){    PRInt32 syserrno, bytes = -1;    PRBool fNeedContinue = PR_FALSE;    if (pt_TestAbort()) return bytes;    bytes = write(fd->secret->md.osfd, buf, amount);    syserrno = errno;    if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )    {        buf = (char *) buf + bytes;        amount -= bytes;        fNeedContinue = PR_TRUE;    }    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        && (!fd->secret->nonblocking) )    {        bytes = 0;        fNeedContinue = PR_TRUE;    }    if (fNeedContinue == PR_TRUE)    {        pt_Continuation op;        op.arg1.osfd = fd->secret->md.osfd;        op.arg2.buffer = (void*)buf;        op.arg3.amount = amount;        op.timeout = PR_INTERVAL_NO_TIMEOUT;        op.result.code = bytes;  /* initialize the number sent */        op.function = pt_write_cont;        op.event = POLLOUT | POLLPRI;        bytes = pt_Continue(&op);        syserrno = op.syserrno;    }    if (bytes == -1)        pt_MapError(_PR_MD_MAP_WRITE_ERROR, syserrno);    return bytes;}  /* pt_Write */static PRInt32 pt_Writev(    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_len, PRIntervalTime timeout){    PRIntn iov_index;    PRBool fNeedContinue = PR_FALSE;    PRInt32 syserrno, bytes, rv = -1;    struct iovec osiov_local[PR_MAX_IOVECTOR_SIZE], *osiov;    int osiov_len;    if (pt_TestAbort()) return rv;

⌨️ 快捷键说明

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