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

📄 ptio.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    *out_flags = 0;    return in_flags;}  /* pt_Poll */static PRInt32 pt_Recv(    PRFileDesc *fd, void *buf, PRInt32 amount,    PRIntn flags, PRIntervalTime timeout){    PRInt32 syserrno, bytes = -1;    PRIntn osflags;    if (0 == flags)        osflags = 0;    else if (PR_MSG_PEEK == flags)        osflags = MSG_PEEK;    else    {        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);        return bytes;    }    if (pt_TestAbort()) return bytes;    /* recv() is a much slower call on pre-2.6 Solaris than read(). */#if defined(SOLARIS)    if (0 == osflags)        bytes = read(fd->secret->md.osfd, buf, amount);    else        bytes = recv(fd->secret->md.osfd, buf, amount, osflags);#else    bytes = recv(fd->secret->md.osfd, buf, amount, osflags);#endif    syserrno = errno;    if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        && (!fd->secret->nonblocking))    {        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;        else        {            pt_Continuation op;            op.arg1.osfd = fd->secret->md.osfd;            op.arg2.buffer = buf;            op.arg3.amount = amount;            op.arg4.flags = osflags;            op.timeout = timeout;            op.function = pt_recv_cont;            op.event = POLLIN | POLLPRI;            bytes = pt_Continue(&op);            syserrno = op.syserrno;        }    }    if (bytes < 0)        pt_MapError(_PR_MD_MAP_RECV_ERROR, syserrno);    return bytes;}  /* pt_Recv */static PRInt32 pt_SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount){    return pt_Recv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);}  /* pt_SocketRead */static PRInt32 pt_Send(    PRFileDesc *fd, const void *buf, PRInt32 amount,    PRIntn flags, PRIntervalTime timeout){    PRInt32 syserrno, bytes = -1;    PRBool fNeedContinue = PR_FALSE;#if defined(SOLARIS)	PRInt32 tmp_amount = amount;#endif    /*     * Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h,     * which has the following:     *     #  define send        cma_send     *     extern int  cma_send (int , void *, int, int );     * So we need to cast away the 'const' of argument #2 for send().     */#if defined (HPUX) && defined(_PR_DCETHREADS)#define PT_SENDBUF_CAST (void *)#else#define PT_SENDBUF_CAST#endif    if (pt_TestAbort()) return bytes;    /*     * 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);retry:    bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount);#else    bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags);#endif    syserrno = errno;#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 ((bytes == -1) && (syserrno == ERANGE))    {        if (tmp_amount > 1)        {            tmp_amount = tmp_amount/2;  /* half the bytes */            goto retry;        }    }#endif    if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )    {        if (PR_INTERVAL_NO_WAIT == timeout)        {            bytes = -1;            syserrno = ETIMEDOUT;        }        else        {            buf = (char *) buf + bytes;            amount -= bytes;            fNeedContinue = PR_TRUE;        }    }    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        && (!fd->secret->nonblocking) )    {        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;        else        {            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.arg4.flags = flags;        op.timeout = timeout;        op.result.code = bytes;  /* initialize the number sent */        op.function = pt_send_cont;        op.event = POLLOUT | POLLPRI;        bytes = pt_Continue(&op);        syserrno = op.syserrno;    }    if (bytes == -1)        pt_MapError(_PR_MD_MAP_SEND_ERROR, syserrno);    return bytes;}  /* pt_Send */static PRInt32 pt_SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount){    return pt_Send(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);}  /* pt_SocketWrite */static PRInt32 pt_SendTo(    PRFileDesc *fd, const void *buf,    PRInt32 amount, PRIntn flags, const PRNetAddr *addr,    PRIntervalTime timeout){    PRInt32 syserrno, bytes = -1;    PRBool fNeedContinue = PR_FALSE;    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 bytes;    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);#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;    bytes = sendto(        fd->secret->md.osfd, buf, amount, flags,        (struct sockaddr*)&addrCopy, addr_len);#else    bytes = sendto(        fd->secret->md.osfd, buf, amount, flags,        (struct sockaddr*)addrp, addr_len);#endif    syserrno = errno;    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        && (!fd->secret->nonblocking) )    {        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;        else 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.arg4.flags = flags;#ifdef _PR_HAVE_SOCKADDR_LEN        op.arg5.addr = (PRNetAddr*)&addrCopy;#else        op.arg5.addr = (PRNetAddr*)addr;#endif        op.timeout = timeout;        op.result.code = 0;  /* initialize the number sent */        op.function = pt_sendto_cont;        op.event = POLLOUT | POLLPRI;        bytes = pt_Continue(&op);        syserrno = op.syserrno;    }    if (bytes < 0)        pt_MapError(_PR_MD_MAP_SENDTO_ERROR, syserrno);    return bytes;}  /* pt_SendTo */static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout){    PRBool fNeedContinue = PR_FALSE;    PRInt32 syserrno, bytes = -1;    pt_SockLen addr_len = sizeof(PRNetAddr);    if (pt_TestAbort()) return bytes;    bytes = recvfrom(        fd->secret->md.osfd, buf, amount, flags,        (struct sockaddr*)addr, &addr_len);    syserrno = errno;    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)        && (!fd->secret->nonblocking) )    {        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;        else fNeedContinue = PR_TRUE;    }    if (fNeedContinue == PR_TRUE)    {        pt_Continuation op;        op.arg1.osfd = fd->secret->md.osfd;        op.arg2.buffer = buf;        op.arg3.amount = amount;        op.arg4.flags = flags;        op.arg5.addr = addr;        op.timeout = timeout;        op.function = pt_recvfrom_cont;        op.event = POLLIN | POLLPRI;        bytes = pt_Continue(&op);        syserrno = op.syserrno;    }#ifdef _PR_HAVE_SOCKADDR_LEN    if (bytes >= 0)    {        /* 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    if (bytes < 0)        pt_MapError(_PR_MD_MAP_RECVFROM_ERROR, syserrno);    return bytes;}  /* pt_RecvFrom */#ifdef AIX#ifndef HAVE_SEND_FILEstatic pthread_once_t pt_aix_sendfile_once_block = PTHREAD_ONCE_INIT;static void pt_aix_sendfile_init_routine(void){    void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);    pt_aix_sendfile_fptr = (ssize_t (*)()) dlsym(handle, "send_file");    dlclose(handle);}/*  * pt_AIXDispatchSendFile */static PRInt32 pt_AIXDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd,	  PRTransmitFileFlags flags, PRIntervalTime timeout){    int rv;    rv = pthread_once(&pt_aix_sendfile_once_block,            pt_aix_sendfile_init_routine);    PR_ASSERT(0 == rv);    if (pt_aix_sendfile_fptr) {        return pt_AIXSendFile(sd, sfd, flags, timeout);    } else {        return PR_EmulateSendFile(sd, sfd, flags, timeout);    }}#endif /* !HAVE_SEND_FILE *//* * pt_AIXSendFile * *    Send file sfd->fd across socket sd. If specified, header and trailer *    buffers are sent before and after the file, respectively.  * *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file *     *    return number of bytes sent or -1 on error * *      This implementation takes advantage of the send_file() system *      call available in AIX 4.3.2. */static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd, 		PRTransmitFileFlags flags, PRIntervalTime timeout){    struct sf_parms sf_struct;    uint_t send_flags;    ssize_t rv;    int syserrno;    PRInt32 count;	unsigned long long saved_file_offset;	long long saved_file_bytes;    sf_struct.header_data = (void *) sfd->header;  /* cast away the 'const' */    sf_struct.header_length = sfd->hlen;    sf_struct.file_descriptor = sfd->fd->secret->md.osfd;    sf_struct.file_size = 0;    sf_struct.file_offset = sfd->file_offset;    if (sfd->file_nbytes == 0)    	sf_struct.file_bytes = -1;	else    	sf_struct.file_bytes = sfd->file_nbytes;    sf_struct.trailer_data = (void *) sfd->trailer;    sf_struct.trailer_length = sfd->tlen;    sf_struct.bytes_sent = 0;	saved_file_offset = sf_struct.file_offset;    saved_file_bytes = sf_struct.file_bytes;    send_flags = 0;			/* flags processed at the end */    /* The first argument to send_file() is int*. */    PR_ASSERT(sizeof(int) == sizeof(sd->secret->md.osfd));    do {        rv = AIX_SEND_FILE(&sd->secret->md.osfd, &sf_struct, send_flags);    } while (rv == -1 && (syserrno = errno) == EINTR);    if (rv == -1) {        if (syserrno == EAGAIN || syserrno == EWOULDBLOCK) {            count = 0; /* Not a real error.  Need to continue. */        } else {            count = -1;        }    } else {        count = 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;    }    if ((rv == 1) || ((rv == -1) && (count == 0))) {        pt_Continuation op;        op.arg1.osfd = sd->secret->md.osfd;        op.arg2.buffer = &sf_struct;        op.arg4.flags = send_flags;        op.result.code = count;        op.timeout = timeout;        op.function = pt_aix_sendfile_cont;        op.event = POLLOUT | POLLPRI;        count = pt_Continue(&op);        syserrno = op.syserrno;    }    if (count == -1) {        pt_MapError(_MD_aix_map_sendfile_error, syserrno);        return -1;    }    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {        PR_Close(sd);    }	PR_ASSERT(count == (sfd->hlen + sfd->tlen +						((sfd->file_nbytes ==  0) ?						sf_struct.file_size - sfd->file_offset :						sfd->file_nbytes)));    return count;}#endif /* AIX */#ifdef HPUX11/* * pt_HPUXSendFile * *    Send file sfd->fd across socket sd. If specified, header and trailer *    buffers are sent before and after the file, respectively. * *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file *     *    return number of bytes sent or -1 on error * *      This implementation takes advantage of the sendfile() system *      call available in HP-UX B.11.00. */static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, 		PRTransmitFileFlags flags, PRIntervalTime timeout){    struct stat statbuf;    size_t nbytes_to_send, file_nbytes_to_send;    struct iovec hdtrl[2];  /* optional header and trailer buffers */    int send_flags;    PRInt32 count;    int syserrno;    if (sfd->file_nbytes == 0) {        /* Get file size */        if (fstat(sfd->

⌨️ 快捷键说明

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