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; }   buflen = sfd->hlen; buffer = sfd->header; while (buflen) { rv = PR_Send(sd, buffer, buflen, 0, timeout); if (rv < 0) {  rv = -1; goto done; } else { count += rv; buffer = (const void*) ((const char*)buffer + rv); buflen -= rv; } }   if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) { rv = -1; goto done; } sendbytes = sfd->file_nbytes; if (sendbytes == 0) {  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) {  rv = -1; goto done; } else { count += rv; bufptr = ((char*)bufptr + rv); rlen -= rv; } } } if (rlen < 0) {  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) {  rv = -1; goto done; } else { count += rv; sendbytes -= rv; bufptr = ((char*)bufptr + rv); rlen -= rv; } } readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); } if (rlen < 0) {  rv = -1; goto done; } else if (sendbytes != 0) {  PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); rv = -1; goto done; } }   buflen = sfd->tlen; buffer = sfd->trailer; while (buflen) { rv =  PR_Send(sd, buffer, buflen, 0, timeout); if (rv < 0) {  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;
return file->methods->file_type;
PR_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;}