NS_IMETHODIMP
nsTemporaryFileInputStream::ReadSegments(nsWriteSegmentFun writer,
                                         void *            closure,
                                         uint32_t          count,
                                         uint32_t *        result)
{
  NS_ASSERTION(result, "null ptr");
  NS_ASSERTION(mCurPos <= mEndPos, "bad stream state");
  *result = 0;

  if (mClosed) {
    return NS_BASE_STREAM_CLOSED;
  }

  mozilla::MutexAutoLock lock(mFileDescOwner->FileMutex());
  int64_t offset = PR_Seek64(mFileDescOwner->mFD, mCurPos, PR_SEEK_SET);
  if (offset == -1) {
    return NS_ErrorAccordingToNSPR();
  }

  // Limit requested count to the amount remaining in our section of the file.
  count = std::min(count, uint32_t(mEndPos - mCurPos));

  char buf[4096];
  while (*result < count) {
    uint32_t bufCount = std::min(count - *result, (uint32_t) sizeof(buf));
    int32_t bytesRead = PR_Read(mFileDescOwner->mFD, buf, bufCount);
    if (bytesRead < 0) {
      return NS_ErrorAccordingToNSPR();
    }

    int32_t bytesWritten = 0;
    while (bytesWritten < bytesRead) {
      uint32_t writerCount = 0;
      nsresult rv = writer(this, closure, buf + bytesWritten, *result,
                           bytesRead - bytesWritten, &writerCount);
      if (NS_FAILED(rv) || writerCount == 0) {
        // nsIInputStream::ReadSegments' contract specifies that errors
        // from writer are not propagated to ReadSegments' caller.
        //
        // If writer fails, leaving bytes still in buf, that's okay: we
        // only update mCurPos to reflect successful writes, so the call
        // to PR_Seek64 at the top will restart us at the right spot.
        return NS_OK;
      }
      NS_ASSERTION(writerCount <= (uint32_t) (bytesRead - bytesWritten),
                   "writer should not write more than we asked it to write");
      bytesWritten += writerCount;
      *result += writerCount;
      mCurPos += writerCount;
    }
  }

  return NS_OK;
}
NS_IMETHODIMP
nsMsgFileStream::Seek(PRInt32 whence, PRInt64 offset)
{
    if (mFileDesc == nsnull)
        return NS_BASE_STREAM_CLOSED;

    nsInt64 cnt = PR_Seek64(mFileDesc, offset, (PRSeekWhence)whence);
    if (cnt == nsInt64(-1)) {
        return NS_ErrorAccordingToNSPR();
    }
    return NS_OK;
}
NS_IMETHODIMP
nsMsgFileStream::Tell(PRInt64 *result)
{
    if (mFileDesc == nsnull)
        return NS_BASE_STREAM_CLOSED;

    nsInt64 cnt = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR);
    if (cnt == nsInt64(-1)) {
        return NS_ErrorAccordingToNSPR();
    }
    *result = cnt;
    return NS_OK;
}
NS_IMETHODIMP
MsgFileStream::Tell(int64_t *result)
{
  if (mFileDesc == nullptr)
    return NS_BASE_STREAM_CLOSED;
  
  int64_t cnt = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR);
  if (cnt == int64_t(-1)) {
    return ErrorAccordingToNSPR();
  }
  *result = cnt;
  return NS_OK;
}
nsresult FileBlockCache::Seek(int64_t aOffset)
{
  mFileMonitor.AssertCurrentThreadOwns();

  if (mFDCurrentPos != aOffset) {
    int64_t result = PR_Seek64(mFD, aOffset, PR_SEEK_SET);
    if (result != aOffset) {
      NS_WARNING("Failed to seek media cache file");
      return NS_ERROR_FAILURE;
    }
    mFDCurrentPos = result;
  }
  return NS_OK;
}
Beispiel #6
0
void file_seteof(file_t file) {
#if defined(XP_WIN)
  SetEndOfFile((HANDLE)PR_FileDesc2NativeHandle((PRFileDesc*)file));

#elif defined(XP_UNIX)
  PRInt64 offset = PR_Seek64((PRFileDesc*)file, 0, SEEK_CUR);

  if (offset < 1) {
    return;
  }
  ftruncate(PR_FileDesc2NativeHandle((PRFileDesc*)file), offset);

#else
#error not implemented

#endif
}
NS_IMETHODIMP
MsgFileStream::Seek(int32_t whence, int64_t offset)
{
  if (mFileDesc == nullptr)
    return NS_BASE_STREAM_CLOSED;

  bool seekingToEnd = whence == PR_SEEK_END && offset == 0;
  if (seekingToEnd && mSeekedToEnd)
    return NS_OK;

  int64_t cnt = PR_Seek64(mFileDesc, offset, (PRSeekWhence)whence);
  if (cnt == int64_t(-1)) {
    return ErrorAccordingToNSPR();
  }

  mSeekedToEnd = seekingToEnd;
  return NS_OK;
}
Beispiel #8
0
void * _MD_MemMap(PRFileMap *fmap, PROffset64 offset, PRUint32 len)
{
    PRUint32 rv;
    void *addr;

    /* prevent mappings beyond EOF + remainder of page */
    if (offset + len > fmap->md.maxExtent) {
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
        return NULL;
    }
    if (PR_Seek64(fmap->fd, offset, PR_SEEK_SET) == -1) {
        return NULL;
    }
    /* try for high memory, fall back to low memory if hi-mem fails */
#if defined(MOZ_OS2_HIGH_MEMORY)
    rv = DosAllocMem(&addr, len, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE);
    if (rv)
#endif
    {
        rv = DosAllocMem(&addr, len, PAG_COMMIT | PAG_READ | PAG_WRITE);
        if (rv) {
            PR_SetError(PR_OUT_OF_MEMORY_ERROR, rv);
            return NULL;
        }
    }
    if (PR_Read(fmap->fd, addr, len) == -1) {
        DosFreeMem(addr);
        return NULL;
    }
    /* don't permit writes if readonly */
    if (fmap->prot == PR_PROT_READONLY) {
        rv = DosSetMem(addr, len, PAG_READ);
        if (rv) {
            DosFreeMem(addr);
            PR_SetError(PR_UNKNOWN_ERROR, rv);
            return NULL;
        }
    }
    return addr;
}
NS_IMETHODIMP
nsTemporaryFileInputStream::ReadSegments(nsWriteSegmentFun writer,
                                         void *            closure,
                                         uint32_t          count,
                                         uint32_t *        result)
{
  NS_ASSERTION(result, "null ptr");
  NS_ASSERTION(mStartPos <= mEndPos, "bad stream state");
  *result = 0;

  if (mClosed) {
    return NS_BASE_STREAM_CLOSED;
  }

  mozilla::MutexAutoLock lock(mFileDescOwner->FileMutex());
  PR_Seek64(mFileDescOwner->mFD, mStartPos, PR_SEEK_SET);

  count = std::min(count, uint32_t(mEndPos - mStartPos));
  uint32_t remainBufCount = count;

  char buf[4096];
  while (remainBufCount > 0) {
    uint32_t bufCount = std::min(remainBufCount, (uint32_t)sizeof(buf));
    int32_t read_result = PR_Read(mFileDescOwner->mFD, buf, bufCount);
    if (read_result < 0) {
      return NS_ErrorAccordingToNSPR();
    }
    uint32_t write_result = 0;
    nsresult rv = writer(this, closure, buf,
                         count - remainBufCount, bufCount, &write_result);
    remainBufCount -= bufCount;
    if (NS_SUCCEEDED(rv)) {
      NS_ASSERTION(write_result <= bufCount,
                   "writer should not write more than we asked it to write");
    }
    mStartPos += bufCount;
  }
  *result = count;
  return NS_OK;
}
bool 
mozilla::fallocate(PRFileDesc *aFD, int64_t aLength) 
{
#if defined(HAVE_POSIX_FALLOCATE)
  return posix_fallocate(PR_FileDesc2NativeHandle(aFD), 0, aLength) == 0;
#elif defined(XP_WIN)
  int64_t oldpos = PR_Seek64(aFD, 0, PR_SEEK_CUR);
  if (oldpos == -1)
    return false;

  if (PR_Seek64(aFD, aLength, PR_SEEK_SET) != aLength)
    return false;

  bool retval = (0 != SetEndOfFile((HANDLE)PR_FileDesc2NativeHandle(aFD)));

  PR_Seek64(aFD, oldpos, PR_SEEK_SET);
  return retval;
#elif defined(XP_OS2)
  return aLength <= UINT32_MAX
    && 0 == DosSetFileSize(PR_FileDesc2NativeHandle(aFD), (uint32_t)aLength);
#elif defined(XP_MACOSX)
  int fd = PR_FileDesc2NativeHandle(aFD);
  fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, aLength};
  // Try to get a continous chunk of disk space
  int ret = fcntl(fd, F_PREALLOCATE, &store);
  if (-1 == ret) {
    // OK, perhaps we are too fragmented, allocate non-continuous
    store.fst_flags = F_ALLOCATEALL;
    ret = fcntl(fd, F_PREALLOCATE, &store);
    if (-1 == ret)
      return false;
  }
  return 0 == ftruncate(fd, aLength);
#elif defined(XP_UNIX)
  // The following is copied from fcntlSizeHint in sqlite
  /* If the OS does not have posix_fallocate(), fake it. First use
  ** ftruncate() to set the file size, then write a single byte to
  ** the last byte in each block within the extended region. This
  ** is the same technique used by glibc to implement posix_fallocate()
  ** on systems that do not have a real fallocate() system call.
  */
  int64_t oldpos = PR_Seek64(aFD, 0, PR_SEEK_CUR);
  if (oldpos == -1)
    return false;

  struct stat buf;
  int fd = PR_FileDesc2NativeHandle(aFD);
  if (fstat(fd, &buf))
    return false;

  if (buf.st_size >= aLength)
    return false;

  const int nBlk = buf.st_blksize;

  if (!nBlk)
    return false;

  if (ftruncate(fd, aLength))
    return false;

  int nWrite; // Return value from write()
  int64_t iWrite = ((buf.st_size + 2 * nBlk - 1) / nBlk) * nBlk - 1; // Next offset to write to
  while (iWrite < aLength) {
    nWrite = 0;
    if (PR_Seek64(aFD, iWrite, PR_SEEK_SET) == iWrite)
      nWrite = PR_Write(aFD, "", 1);
    if (nWrite != 1) break;
    iWrite += nBlk;
  }

  PR_Seek64(aFD, oldpos, PR_SEEK_SET);
  return nWrite == 1;
#endif
  return false;
}
Beispiel #11
0
int main(int argc, char **argv)
{
    PRFileDesc *fd;
    PRInt64 offset, position;
    PRInt32 nbytes;
    char buf[MESSAGE_SIZE];
#ifdef _WIN32
    HANDLE hFile;
    LARGE_INTEGER li;
#endif /* _WIN32 */

    LL_I2L(offset, 1);
    LL_SHL(offset, offset, 32);

#ifdef _WIN32
    hFile = CreateFile(TEST_FILE_NAME, GENERIC_WRITE, 0, NULL,
            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateFile failed\n");
        exit(1);
    }
    li.QuadPart = offset;
    li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
    if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
        fprintf(stderr, "SetFilePointer failed\n");
        exit(1);
    }
    PR_ASSERT(li.QuadPart == offset);
    strcpy(buf, MESSAGE);
    if (WriteFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) {
        fprintf(stderr, "WriteFile failed\n");
        exit(1);
    }
    PR_ASSERT(nbytes == sizeof(buf));
    if (CloseHandle(hFile) == 0) {
        fprintf(stderr, "CloseHandle failed\n");
        exit(1);
    }
#endif /* _WIN32 */

    memset(buf, 0, sizeof(buf));

    fd = PR_Open(TEST_FILE_NAME, PR_RDONLY, 0666);
    if (fd == NULL) {
        fprintf(stderr, "PR_Open failed\n");
        exit(1);
    }
    position = PR_Seek64(fd, offset, PR_SEEK_SET);
    if (!LL_GE_ZERO(position)) {
        fprintf(stderr, "PR_Seek64 failed\n");
        exit(1);
    }
    PR_ASSERT(LL_EQ(position, offset));
    nbytes = PR_Read(fd, buf, sizeof(buf));
    if (nbytes != sizeof(buf)) {
        fprintf(stderr, "PR_Read failed\n");
        exit(1);
    }
    if (strcmp(buf, MESSAGE)) {
        fprintf(stderr, "corrupt data:$%s$\n", buf);
        exit(1);
    }
    if (PR_Close(fd) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }

    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
        fprintf(stderr, "PR_Delete failed\n");
        exit(1);
    }

    printf("PASS\n");
    return 0;
}
Beispiel #12
0
nsresult
CacheFileMetadata::SyncReadMetadata(nsIFile *aFile)
{
  LOG(("CacheFileMetadata::SyncReadMetadata() [this=%p]", this));

  MOZ_ASSERT(!mListener);
  MOZ_ASSERT(!mHandle);
  MOZ_ASSERT(!mHashArray);
  MOZ_ASSERT(!mBuf);
  MOZ_ASSERT(!mWriteBuf);
  MOZ_ASSERT(mKey.IsEmpty());

  nsresult rv;

  int64_t fileSize;
  rv = aFile->GetFileSize(&fileSize);
  if (NS_FAILED(rv)) {
    // Don't bloat the console
    return rv;
  }

  PRFileDesc *fd;
  rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0600, &fd);
  NS_ENSURE_SUCCESS(rv, rv);

  int64_t offset = PR_Seek64(fd, fileSize - sizeof(uint32_t), PR_SEEK_SET);
  if (offset == -1) {
    PR_Close(fd);
    return NS_ERROR_FAILURE;
  }

  uint32_t metaOffset;
  int32_t bytesRead = PR_Read(fd, &metaOffset, sizeof(uint32_t));
  if (bytesRead != sizeof(uint32_t)) {
    PR_Close(fd);
    return NS_ERROR_FAILURE;
  }

  metaOffset = NetworkEndian::readUint32(&metaOffset);
  if (metaOffset > fileSize) {
    PR_Close(fd);
    return NS_ERROR_FAILURE;
  }

  mBufSize = fileSize - metaOffset;
  mBuf = static_cast<char *>(moz_xmalloc(mBufSize));

  DoMemoryReport(MemoryUsage());

  offset = PR_Seek64(fd, metaOffset, PR_SEEK_SET);
  if (offset == -1) {
    PR_Close(fd);
    return NS_ERROR_FAILURE;
  }

  bytesRead = PR_Read(fd, mBuf, mBufSize);
  PR_Close(fd);
  if (bytesRead != static_cast<int32_t>(mBufSize)) {
    return NS_ERROR_FAILURE;
  }

  rv = ParseMetadata(metaOffset, 0, false);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
Beispiel #13
0
int file_seek(file_t file, PRInt64 offset) {
  return PR_Seek64((PRFileDesc*)file, offset, PR_SEEK_SET) == offset;
}