コード例 #1
0
ファイル: httpget.c プロジェクト: bringhurst/vbox
PRStatus FastFetchFile(PRFileDesc *in, PRFileDesc *out, PRUint32 size)
{
    PRInt32 nBytes;
    PRFileMap *outfMap;
    void *addr;
    char *start;
    PRUint32 rem;
    PRUint32 bytesToRead;
    PRStatus rv;
    PRInt64 sz64;

    LL_UI2L(sz64, size);
    outfMap = PR_CreateFileMap(out, sz64, PR_PROT_READWRITE);
    PR_ASSERT(outfMap);
    addr = PR_MemMap(outfMap, LL_ZERO, size);
    if (addr == (void *) -1) {
	fprintf(stderr, "cannot memory-map file: (%d, %d)\n", PR_GetError(),
		PR_GetOSError());

	PR_CloseFileMap(outfMap);
	return PR_FAILURE;
    }
    PR_ASSERT(addr != (void *) -1);
    start = (char *) addr;
    rem = size;
    while ((nBytes = DrainInputBuffer(start, rem)) > 0) {
	start += nBytes;
	rem -= nBytes;
    }
    if (nBytes < 0) {
	/* Input buffer is empty and end of stream */
	return PR_SUCCESS;
    }
    bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE;
    while (rem > 0 && (nBytes = PR_Read(in, start, bytesToRead)) > 0) {
	start += nBytes;
	rem -= nBytes;
        bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE;
    }
    if (nBytes < 0) {
	fprintf(stderr, "httpget: cannot read from socket\n");
	return PR_FAILURE;
    }
    rv = PR_MemUnmap(addr, size);
    PR_ASSERT(rv == PR_SUCCESS);
    rv = PR_CloseFileMap(outfMap);
    PR_ASSERT(rv == PR_SUCCESS);
    return PR_SUCCESS;
}
コード例 #2
0
int main(int argc, char **argv)
{
  ScopedXPCOM xpcom("TestMimeCrash");
  if (xpcom.failed())
    return 1;

  // We cannot use malloc() since this crashes depends on memory allocation.
  // By using mmap()/PR_MemMap(), end of buffer that is last in the page
  // sets LF.

  PRUint32 bufsize = PR_GetPageSize();
  PRFileMap *fm = PR_OpenAnonFileMap(".", bufsize, PR_PROT_READWRITE);
  if (!fm)
    return 1;
  char *addr = (char *) PR_MemMap(fm, 0, bufsize);
  if (!addr)
    return 1;
  memset(addr, '\r', bufsize);

  nsresult rv = do_test(addr, bufsize);

  PR_MemUnmap(addr, bufsize);
  PR_CloseFileMap(fm);

  if (NS_FAILED(rv)) {
    fail("cannot use nsIMimeConverter error=%08x\n", rv);
    return -1;
  }

  passed("no crash");

  return 0;
}
コード例 #3
0
ファイル: AutoMemMap.cpp プロジェクト: Danielzac/gecko-dev
AutoMemMap::~AutoMemMap()
{
  if (addr) {
    NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
    addr = nullptr;
  }

  if (fileMap) {
    NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
    fileMap = nullptr;
  }

  if (fd) {
    NS_WARN_IF(PR_Close(fd) != PR_SUCCESS);
    fd = nullptr;
  }
}
コード例 #4
0
 ~FileMapAutoCloser() { PR_CloseFileMap(mMap); }
コード例 #5
0
ファイル: priometh.c プロジェクト: AtulKumar2/gecko-dev
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;
}