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

📄 priometh.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote));        *nd = accepted;        return rv;    }    PR_Close(accepted);    return rv;}/* * PR_EmulateSendFile * *    Send file sfd->fd across socket sd. If header/trailer are specified *    they 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 * */#if defined(XP_UNIX) || defined(WIN32)/* * An implementation based on memory-mapped files */#define SENDFILE_MMAP_CHUNK	(256 * 1024)PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(    PRFileDesc *sd, PRSendFileData *sfd,    PRTransmitFileFlags flags, PRIntervalTime timeout){    PRInt32 rv, count = 0;    PRInt32 len, file_bytes, index = 0;    PRFileInfo info;    PRIOVec iov[3];    PRFileMap *mapHandle = NULL;    void *addr = (void*)0; /* initialized to some arbitrary value. Keeps compiler warnings down. */    PRUint32 file_mmap_offset, alignment;    PRInt64 zero64;    PROffset64 file_mmap_offset64;    PRUint32 addr_offset, mmap_len;    /* Get file size */    if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) {        count = -1;        goto done;    }    if (sfd->file_nbytes &&            (info.size < (sfd->file_offset + sfd->file_nbytes))) {        /*         * there are fewer bytes in file to send than specified         */        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);        count = -1;        goto done;    }    if (sfd->file_nbytes)        file_bytes = sfd->file_nbytes;    else        file_bytes = info.size - sfd->file_offset;    alignment = PR_GetMemMapAlignment();    /* number of initial bytes to skip in mmap'd segment */    addr_offset = sfd->file_offset % alignment;    /* find previous mmap alignment boundary */    file_mmap_offset = sfd->file_offset - addr_offset;    /*     * If the file is large, mmap and send the file in chunks so as     * to not consume too much virtual address space     */    mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK);    len = mmap_len - addr_offset;    /*     * Map in (part of) file. Take care of zero-length files.     */    if (len) {        LL_I2L(zero64, 0);        mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY);        if (!mapHandle) {            count = -1;            goto done;        }        LL_I2L(file_mmap_offset64, file_mmap_offset);        addr = PR_MemMap(mapHandle, file_mmap_offset64, mmap_len);        if (!addr) {            count = -1;            goto done;        }    }    /*     * send headers first, followed by the file     */    if (sfd->hlen) {        iov[index].iov_base = (char *) sfd->header;        iov[index].iov_len = sfd->hlen;        index++;    }    if (len) {        iov[index].iov_base = (char*)addr + addr_offset;        iov[index].iov_len = len;        index++;    }    if ((file_bytes == len) && (sfd->tlen)) {        /*         * all file data is mapped in; send the trailer too         */        iov[index].iov_base = (char *) sfd->trailer;        iov[index].iov_len = sfd->tlen;        index++;    }    rv = PR_Writev(sd, iov, index, timeout);    if (len)        PR_MemUnmap(addr, mmap_len);    if (rv < 0) {        count = -1;        goto done;    }    PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0));    file_bytes -= len;    count += rv;    if (!file_bytes)    /* header, file and trailer are sent */        goto done;    /*     * send remaining bytes of the file, if any     */    len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);    while (len > 0) {        /*         * Map in (part of) file         */        file_mmap_offset = sfd->file_offset + count - sfd->hlen;        PR_ASSERT((file_mmap_offset % alignment) == 0);        LL_I2L(file_mmap_offset64, file_mmap_offset);        addr = PR_MemMap(mapHandle, file_mmap_offset64, len);        if (!addr) {            count = -1;            goto done;        }        rv = PR_Send(sd, addr, len, 0, timeout);        PR_MemUnmap(addr, len);        if (rv < 0) {            count = -1;            goto done;        }        PR_ASSERT(rv == len);        file_bytes -= rv;        count += rv;        len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);    }    PR_ASSERT(0 == file_bytes);    if (sfd->tlen) {        rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);        if (rv >= 0) {            PR_ASSERT(rv == sfd->tlen);            count += rv;        } else            count = -1;    }done:    if (mapHandle)        PR_CloseFileMap(mapHandle);    if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))        PR_Close(sd);    return count;}#elsePR_IMPLEMENT(PRInt32) PR_EmulateSendFile(    PRFileDesc *sd, PRSendFileData *sfd,    PRTransmitFileFlags flags, PRIntervalTime timeout){    PRInt32 rv, count = 0;    PRInt32 rlen;    const void * buffer;    PRInt32 buflen;    PRInt32 sendbytes, readbytes;    char *buf;#define _SENDFILE_BUFSIZE   (16 * 1024)    buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE);    if (buf == NULL) {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return -1;    }    /*     * send header first     */    buflen = sfd->hlen;    buffer = sfd->header;    while (buflen) {        rv = PR_Send(sd, buffer, buflen, 0, timeout);        if (rv < 0) {            /* PR_Send() has invoked PR_SetError(). */            rv = -1;            goto done;        } else {            count += rv;            buffer = (const void*) ((const char*)buffer + rv);            buflen -= rv;        }    }    /*     * send file next     */    if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) {        rv = -1;        goto done;    }    sendbytes = sfd->file_nbytes;    if (sendbytes == 0) {        /* send entire file */        while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) {            while (rlen) {                char *bufptr = buf;                rv =  PR_Send(sd, bufptr, rlen, 0, timeout);                if (rv < 0) {                    /* PR_Send() has invoked PR_SetError(). */                    rv = -1;                    goto done;                } else {                    count += rv;                    bufptr = ((char*)bufptr + rv);                    rlen -= rv;                }            }        }        if (rlen < 0) {            /* PR_Read() has invoked PR_SetError(). */            rv = -1;            goto done;        }    } else {        readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);        while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) {            while (rlen) {                char *bufptr = buf;                rv =  PR_Send(sd, bufptr, rlen, 0, timeout);                if (rv < 0) {                    /* PR_Send() has invoked PR_SetError(). */                    rv = -1;                    goto done;                } else {                    count += rv;                    sendbytes -= rv;                    bufptr = ((char*)bufptr + rv);                    rlen -= rv;                }            }            readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);        }        if (rlen < 0) {            /* PR_Read() has invoked PR_SetError(). */            rv = -1;            goto done;        } else if (sendbytes != 0) {            /*             * there are fewer bytes in file to send than specified             */            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);            rv = -1;            goto done;        }    }    /*     * send trailer last     */    buflen = sfd->tlen;    buffer = sfd->trailer;    while (buflen) {        rv =  PR_Send(sd, buffer, buflen, 0, timeout);        if (rv < 0) {            /* PR_Send() has invoked PR_SetError(). */            rv = -1;            goto done;        } else {            count += rv;            buffer = (const void*) ((const char*)buffer + rv);            buflen -= rv;        }    }    rv = count;done:    if (buf)        PR_DELETE(buf);    if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))        PR_Close(sd);    return rv;}#endif/* priometh.c */

⌨️ 快捷键说明

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