[haiku-commits] haiku: hrev47488 - src/kits/package/hpkg headers/private/package/hpkg docs/user/support src/kits/storage src/kits/support

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 12 Jul 2014 15:50:49 +0200 (CEST)

hrev47488 adds 5 changesets to branch 'master'
old head: 57f444065f2636eb024651e1b55e56d4d4106034
new head: e527b796319f21ca025f68e1964df140daa6de35
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=e527b79+%5E57f4440

----------------------------------------------------------------------------

1b50eb7: Remove unnecessary zlib build feature dependency

8546c41: BPositionIO: Add {Read,Write}AtExactly()
  
  Analoguous to {Read,Write}Exactly(), just for the *At() versions.

c55a060: Add private class BFdIO
  
  Simple BPositionIO implementation using the POSIX API on a FD. In effect
  similar to BFile, but more easily ported to kernel and boot loader (and
  the FD is reusable).

01e6d68: boot loader: Add pwrite(), lseek(), ftruncate()
  
  ftruncate() is just a stub (needed for BFdIO).

e527b79: Switch package file accessor classes to use BPositionIO
  
  * PackageFileHeap{Reader,Writer} as well as Package{Reader,Writer} and
    their implementation and super classes do now internally use a
    BPositionIO instead of a FD to access the package file. This provides
    more flexibility needed for features to come.
  * BPackageReader has already grown a new Init() version with a
    BPositionIO* parameter.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

30 files changed, 564 insertions(+), 142 deletions(-)
docs/user/support/DataIO.dox                     |  56 +++++++++
headers/build/private/storage/FdIO.h             |   1 +
headers/os/package/hpkg/PackageReader.h          |   7 +-
headers/os/support/DataIO.h                      |   6 +
.../package/hpkg/PackageFileHeapAccessorBase.h   |  10 +-
.../private/package/hpkg/PackageFileHeapReader.h |   2 +-
.../private/package/hpkg/PackageFileHeapWriter.h |   2 +-
headers/private/package/hpkg/PackageReaderImpl.h |  10 +-
headers/private/package/hpkg/ReaderImplBase.h    |  53 ++++----
.../private/package/hpkg/RepositoryReaderImpl.h  |   1 +
headers/private/package/hpkg/WriterImplBase.h    |  10 +-
headers/private/storage/FdIO.h                   |  45 +++++++
.../kernel/file_systems/packagefs/Jamfile        |   7 ++
.../file_systems/packagefs/package/Package.cpp   |  28 ++++-
src/build/libbe/storage/Jamfile                  |   1 +
.../package/hpkg/PackageFileHeapAccessorBase.cpp |  19 ++-
src/kits/package/hpkg/PackageFileHeapReader.cpp  |   9 +-
src/kits/package/hpkg/PackageFileHeapWriter.cpp  |  25 ++--
src/kits/package/hpkg/PackageReader.cpp          |  18 ++-
src/kits/package/hpkg/PackageReaderImpl.cpp      |  18 ++-
src/kits/package/hpkg/PackageWriterImpl.cpp      |   5 +-
src/kits/package/hpkg/ReaderImplBase.cpp         |  41 +++----
src/kits/package/hpkg/RepositoryReaderImpl.cpp   |  19 ++-
src/kits/package/hpkg/WriterImplBase.cpp         |  30 +++--
src/kits/storage/FdIO.cpp                        | 122 +++++++++++++++++++
src/kits/storage/Jamfile                         |   1 +
src/kits/support/DataIO.cpp                      |  64 ++++++++++
.../boot/loader/file_systems/packagefs/Jamfile   |  11 +-
.../loader/file_systems/packagefs/packagefs.cpp  |  23 ++--
src/system/boot/loader/vfs.cpp                   |  62 ++++++++++

############################################################################

Commit:      1b50eb7d911b76b7afbdc85e7c87204146754bba
URL:         http://cgit.haiku-os.org/haiku/commit/?id=1b50eb7
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 12 09:49:42 2014 UTC

Remove unnecessary zlib build feature dependency

----------------------------------------------------------------------------

diff --git a/src/system/boot/loader/file_systems/packagefs/Jamfile 
b/src/system/boot/loader/file_systems/packagefs/Jamfile
index d935bbe..45b5873 100644
--- a/src/system/boot/loader/file_systems/packagefs/Jamfile
+++ b/src/system/boot/loader/file_systems/packagefs/Jamfile
@@ -49,6 +49,6 @@ BootStaticLibrary boot_packagefs :
        : -fno-pic
 ;
 
-Includes [ FGristFiles CompressionAlgorithm.cpp ZlibCompressionAlgorithm.cpp ]
+Includes [ FGristFiles ZlibCompressionAlgorithm.cpp ]
        : [ BuildFeatureAttribute zlib : headers ] ;
 

############################################################################

Commit:      8546c4160e158b5a7d17008fb5691e829886060d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=8546c41
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 12 11:18:18 2014 UTC

BPositionIO: Add {Read,Write}AtExactly()

Analoguous to {Read,Write}Exactly(), just for the *At() versions.

----------------------------------------------------------------------------

diff --git a/docs/user/support/DataIO.dox b/docs/user/support/DataIO.dox
index 52f2015..af398f1 100644
--- a/docs/user/support/DataIO.dox
+++ b/docs/user/support/DataIO.dox
@@ -270,6 +270,62 @@
 
 
 /*!
+       \fn virtual status_t BPositionIO::ReadAtExactly(off_t position, void* 
buffer, size_t size, size_t* _bytesRead)
+       \brief Reads an exact amount of data from the object at the specified
+               position into a buffer.
+
+       This is a convenience wrapper method for ReadAt() for code that expects 
the
+       exact number of bytes requested to be read. This method calls ReadAt() 
in a
+       loop to read the data. It fails when ReadAt() returns an error or fails 
to
+       read any more data (i.e. returns 0).
+
+       \param position The object position at which to read the data.
+       \param buffer Pointer to pre-allocated storage of at least \a size bytes
+              into which the data shall be read. Won't be dereferenced, when
+              \a size is 0.
+       \param size The number of bytes to be read.
+       \param _bytesRead Optional pointer to a pre-allocated size_t into which 
the
+              number of bytes actually read will be written. When the method
+              returns \c B_OK this will always be \a size. Can be \c NULL.
+
+       \return An error code indicating whether or not the method succeeded.
+       \retval B_OK All data have been read.
+       \retval B_PARTIAL_READ ReadAt() didn't fail, but couldn't provide as 
many
+               bytes as requested.
+
+       \since Haiku R1
+*/
+
+
+/*!
+       \fn virtual status_t BPositionIO::WriteAtExactly(off_t position, const 
void* buffer, size_t size,
+               size_t* _bytesWritten)
+       \brief Writes an exact amount of data from a buffer to the object at the
+               specified position.
+
+       This is a convenience wrapper method for WriteAt() for code that 
expects the
+       exact number of bytes given to be written. This method calls WriteAt() 
in a
+       loop to write the data. It fails when WriteAt() returns an error or 
fails to
+       write any more data (i.e. returns 0).
+
+       \param position The object position at which to write the data.
+       \param buffer Pointer to a buffer of at least \a size bytes containing 
the
+              data to be written. Won't be dereferenced, when \a size is 0.
+       \param size The number of bytes to be written.
+       \param _bytesWritten Optional pointer to a pre-allocated size_t into 
which
+              the number of bytes actually written will be written. When the
+              method returns \c B_OK this will always be \a size. Can be \c 
NULL.
+
+       \return An error code indicated whether the method succeeded.
+       \retval B_OK All data have been written.
+       \retval B_PARTIAL_READ WriteAt() didn't fail, but couldn't write as many
+               bytes as provided.
+
+       \since Haiku R1
+*/
+
+
+/*!
        \fn virtual off_t BPositionIO::Seek(off_t position, uint32 seekMode) = 0
        \brief Pure virtual to move the cursor to a certain position.
 
diff --git a/headers/os/support/DataIO.h b/headers/os/support/DataIO.h
index 5e3d9bc..d05a4c8 100644
--- a/headers/os/support/DataIO.h
+++ b/headers/os/support/DataIO.h
@@ -60,6 +60,12 @@ public:
        virtual ssize_t                         WriteAt(off_t position, const 
void* buffer,
                                                                        size_t 
size) = 0;
 
+                       status_t                        ReadAtExactly(off_t 
position, void* buffer,
+                                                                       size_t 
size, size_t* _bytesRead = NULL);
+                       status_t                        WriteAtExactly(off_t 
position,
+                                                                       const 
void* buffer, size_t size,
+                                                                       size_t* 
_bytesWritten = NULL);
+
        virtual off_t                           Seek(off_t position, uint32 
seekMode) = 0;
        virtual off_t                           Position() const = 0;
 
diff --git a/src/kits/support/DataIO.cpp b/src/kits/support/DataIO.cpp
index 55e65b4..e7033ab 100644
--- a/src/kits/support/DataIO.cpp
+++ b/src/kits/support/DataIO.cpp
@@ -200,6 +200,70 @@ BPositionIO::Write(const void* buffer, size_t size)
 
 
 status_t
+BPositionIO::ReadAtExactly(off_t position, void* buffer, size_t size,
+       size_t* _bytesRead)
+{
+       uint8* out = (uint8*)buffer;
+       size_t bytesRemaining = size;
+       status_t error = B_OK;
+
+       while (bytesRemaining > 0) {
+               ssize_t bytesRead = ReadAt(position, out, bytesRemaining);
+               if (bytesRead < 0) {
+                       error = bytesRead;
+                       break;
+               }
+
+               if (bytesRead == 0) {
+                       error = B_PARTIAL_READ;
+                       break;
+               }
+
+               out += bytesRead;
+               bytesRemaining -= bytesRead;
+               position += bytesRead;
+       }
+
+       if (_bytesRead != NULL)
+               *_bytesRead = size - bytesRemaining;
+
+       return error;
+}
+
+
+status_t
+BPositionIO::WriteAtExactly(off_t position, const void* buffer, size_t size,
+       size_t* _bytesWritten)
+{
+       const uint8* in = (const uint8*)buffer;
+       size_t bytesRemaining = size;
+       status_t error = B_OK;
+
+       while (bytesRemaining > 0) {
+               ssize_t bytesWritten = WriteAt(position, in, bytesRemaining);
+               if (bytesWritten < 0) {
+                       error = bytesWritten;
+                       break;
+               }
+
+               if (bytesWritten == 0) {
+                       error = B_PARTIAL_WRITE;
+                       break;
+               }
+
+               in += bytesWritten;
+               bytesRemaining -= bytesWritten;
+               position += bytesWritten;
+       }
+
+       if (_bytesWritten != NULL)
+               *_bytesWritten = size - bytesRemaining;
+
+       return error;
+}
+
+
+status_t
 BPositionIO::SetSize(off_t size)
 {
        return B_ERROR;

############################################################################

Commit:      c55a06055f7c2523d188ce382806fe98eaa06bb6
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c55a060
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 12 11:23:31 2014 UTC

Add private class BFdIO

Simple BPositionIO implementation using the POSIX API on a FD. In effect
similar to BFile, but more easily ported to kernel and boot loader (and
the FD is reusable).

----------------------------------------------------------------------------

diff --git a/headers/build/private/storage/FdIO.h 
b/headers/build/private/storage/FdIO.h
new file mode 100644
index 0000000..d61b0a0
--- /dev/null
+++ b/headers/build/private/storage/FdIO.h
@@ -0,0 +1 @@
+#include <../private/storage/FdIO.h>
diff --git a/headers/private/storage/FdIO.h b/headers/private/storage/FdIO.h
new file mode 100644
index 0000000..ca531d0
--- /dev/null
+++ b/headers/private/storage/FdIO.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _FD_IO_H_
+#define _FD_IO_H_
+
+
+#include <DataIO.h>
+
+
+class BFdIO : public BPositionIO {
+public:
+                                                               BFdIO();
+                                                               BFdIO(int fd, 
bool keepFd);
+       virtual                                         ~BFdIO();
+
+                       void                            SetTo(int fd, bool 
keepFd);
+                       void                            Unset();
+
+       virtual ssize_t                         Read(void* buffer, size_t size);
+       virtual ssize_t                         Write(const void* buffer, 
size_t size);
+
+       virtual ssize_t                         ReadAt(off_t position, void* 
buffer,
+                                                                       size_t 
size);
+       virtual ssize_t                         WriteAt(off_t position, const 
void* buffer,
+                                                                       size_t 
size);
+
+       virtual off_t                           Seek(off_t position, uint32 
seekMode);
+       virtual off_t                           Position() const;
+
+       virtual status_t                        SetSize(off_t size);
+       virtual status_t                        GetSize(off_t* _size) const;
+
+private:
+                                                               BFdIO(const 
BFdIO& other);
+                       BFdIO&                          operator=(const BFdIO& 
other);
+
+private:
+                       int                                     fFd;
+                       bool                            fOwnsFd;
+};
+
+
+#endif // _FD_IO_H_
diff --git a/src/build/libbe/storage/Jamfile b/src/build/libbe/storage/Jamfile
index da3e194..f4a5dfd 100644
--- a/src/build/libbe/storage/Jamfile
+++ b/src/build/libbe/storage/Jamfile
@@ -14,6 +14,7 @@ BuildPlatformMergeObjectPIC <libbe_build>storage_kit.o :
        DriverSettings.cpp
        Entry.cpp
        EntryList.cpp
+       FdIO.cpp
        File.cpp
        FileIO.cpp
        FindDirectory.cpp
diff --git a/src/kits/storage/FdIO.cpp b/src/kits/storage/FdIO.cpp
new file mode 100644
index 0000000..19e83b3
--- /dev/null
+++ b/src/kits/storage/FdIO.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2014, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <FdIO.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+BFdIO::BFdIO()
+       :
+       BPositionIO(),
+       fFd(-1),
+       fOwnsFd(false)
+{
+}
+
+
+BFdIO::BFdIO(int fd, bool keepFd)
+       :
+       BPositionIO(),
+       fFd(fd),
+       fOwnsFd(keepFd)
+{
+}
+
+
+BFdIO::~BFdIO()
+{
+       Unset();
+}
+
+
+void
+BFdIO::SetTo(int fd, bool keepFd)
+{
+       Unset();
+
+       fFd = fd;
+       fOwnsFd = keepFd;
+}
+
+
+void
+BFdIO::Unset()
+{
+       if (fOwnsFd && fFd >= 0)
+               close(fFd);
+
+       fFd = -1;
+       fOwnsFd = false;
+}
+
+
+ssize_t
+BFdIO::Read(void* buffer, size_t size)
+{
+       ssize_t bytesRead = read(fFd, buffer, size);
+       return bytesRead >= 0 ? bytesRead : errno;
+}
+
+
+ssize_t
+BFdIO::Write(const void* buffer, size_t size)
+{
+       ssize_t bytesWritten = write(fFd, buffer, size);
+       return bytesWritten >= 0 ? bytesWritten : errno;
+}
+
+
+ssize_t
+BFdIO::ReadAt(off_t position, void* buffer, size_t size)
+{
+       ssize_t bytesRead = pread(fFd, buffer, size, position);
+       return bytesRead >= 0 ? bytesRead : errno;
+}
+
+
+ssize_t
+BFdIO::WriteAt(off_t position, const void* buffer, size_t size)
+{
+       ssize_t bytesWritten = pwrite(fFd, buffer, size, position);
+       return bytesWritten >= 0 ? bytesWritten : errno;
+}
+
+
+off_t
+BFdIO::Seek(off_t position, uint32 seekMode)
+{
+       off_t newPosition = lseek(fFd, position, seekMode);
+       return newPosition >= 0 ? newPosition : errno;
+}
+
+
+off_t
+BFdIO::Position() const
+{
+       return const_cast<BFdIO*>(this)->BFdIO::Seek(0, SEEK_CUR);
+}
+
+
+status_t
+BFdIO::SetSize(off_t size)
+{
+       return ftruncate(fFd, size) == 0 ? B_OK : errno;
+}
+
+
+status_t
+BFdIO::GetSize(off_t* _size) const
+{
+       struct stat st;
+       if (fstat(fFd, &st) != 0)
+               return errno;
+
+       *_size = st.st_size;
+       return B_OK;
+}
diff --git a/src/kits/storage/Jamfile b/src/kits/storage/Jamfile
index f7703a3..2343954 100644
--- a/src/kits/storage/Jamfile
+++ b/src/kits/storage/Jamfile
@@ -27,6 +27,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
                        Entry.cpp
                        EntryList.cpp
                        EntryOperationEngineBase.cpp
+                       FdIO.cpp
                        File.cpp
                        FileDescriptorIO.cpp
                        FileIO.cpp

############################################################################

Commit:      01e6d687c03d9148783a67a53789e5e96f617a5a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=01e6d68
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 12 11:27:11 2014 UTC

boot loader: Add pwrite(), lseek(), ftruncate()

ftruncate() is just a stub (needed for BFdIO).

----------------------------------------------------------------------------

diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp
index 02e5d60..8408970 100644
--- a/src/system/boot/loader/vfs.cpp
+++ b/src/system/boot/loader/vfs.cpp
@@ -57,6 +57,7 @@ class Descriptor {
                ssize_t Write(const void *buffer, size_t bufferSize);
 
                void Stat(struct stat &stat);
+               status_t Seek(off_t position, int mode);
 
                off_t Offset() const { return fOffset; }
                int32 RefCount() const { return fRefCount; }
@@ -392,6 +393,37 @@ Descriptor::Stat(struct stat &stat)
 
 
 status_t
+Descriptor::Seek(off_t position, int mode)
+{
+       off_t newPosition;
+       switch (mode)
+       {
+               case SEEK_SET:
+                       newPosition = position;
+                       break;
+               case SEEK_CUR:
+                       newPosition = fOffset + position;
+                       break;
+               case SEEK_END:
+               {
+                       struct stat st;
+                       Stat(st);
+                       newPosition = st.st_size + position;
+                       break;
+               }
+               default:
+                       return B_BAD_VALUE;
+       }
+
+       if (newPosition < 0)
+               return B_BAD_VALUE;
+
+       fOffset = newPosition;
+       return B_OK;
+}
+
+
+status_t
 Descriptor::Acquire()
 {
        fRefCount++;
@@ -866,6 +898,29 @@ dup(int fd)
 }
 
 
+off_t
+lseek(int fd, off_t offset, int whence)
+{
+       Descriptor* descriptor = get_descriptor(fd);
+       if (descriptor == NULL)
+               RETURN_AND_SET_ERRNO(B_FILE_ERROR);
+
+       status_t error = descriptor->Seek(offset, whence);
+       if (error != B_OK)
+               RETURN_AND_SET_ERRNO(B_FILE_ERROR);
+
+       return descriptor->Offset();
+}
+
+
+int
+ftruncate(int fd, off_t newSize)
+{
+       dprintf("ftruncate() not implemented!\n");
+       RETURN_AND_SET_ERRNO(B_FILE_ERROR);
+}
+
+
 ssize_t
 read_pos(int fd, off_t offset, void *buffer, size_t bufferSize)
 {
@@ -907,6 +962,13 @@ write_pos(int fd, off_t offset, const void *buffer, size_t 
bufferSize)
 
 
 ssize_t
+pwrite(int fd, const void* buffer, size_t bufferSize, off_t offset)
+{
+       return write_pos(fd, offset, buffer, bufferSize);
+}
+
+
+ssize_t
 write(int fd, const void *buffer, size_t bufferSize)
 {
        Descriptor *descriptor = get_descriptor(fd);

############################################################################

Revision:    hrev47488
Commit:      e527b796319f21ca025f68e1964df140daa6de35
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e527b79
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 12 11:34:56 2014 UTC

Switch package file accessor classes to use BPositionIO

* PackageFileHeap{Reader,Writer} as well as Package{Reader,Writer} and
  their implementation and super classes do now internally use a
  BPositionIO instead of a FD to access the package file. This provides
  more flexibility needed for features to come.
* BPackageReader has already grown a new Init() version with a
  BPositionIO* parameter.

----------------------------------------------------------------------------

diff --git a/headers/os/package/hpkg/PackageReader.h 
b/headers/os/package/hpkg/PackageReader.h
index 7ab4976..dec10d1 100644
--- a/headers/os/package/hpkg/PackageReader.h
+++ b/headers/os/package/hpkg/PackageReader.h
@@ -9,6 +9,9 @@
 #include <SupportDefs.h>
 
 
+class BPositionIO;
+
+
 namespace BPackageKit {
 
 namespace BHPKG {
@@ -34,12 +37,14 @@ public:
 
                        status_t                        Init(const char* 
fileName, uint32 flags = 0);
                        status_t                        Init(int fd, bool 
keepFD, uint32 flags = 0);
+                       status_t                        Init(BPositionIO* file, 
bool keepFile,
+                                                                       uint32 
flags = 0);
                        status_t                        ParseContent(
                                                                        
BPackageContentHandler* contentHandler);
                        status_t                        
ParseContent(BLowLevelPackageContentHandler*
                                                                                
contentHandler);
 
-                       int                                     PackageFileFD();
+                       BPositionIO*            PackageFile() const;
 
                        BAbstractBufferedDataReader* HeapReader() const;
                                                                        // Only 
valid as long as the reader lives.
diff --git a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h 
b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h
index b5463dd..b302188 100644
--- a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h
+++ b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h
@@ -71,8 +71,8 @@ public:
 
 public:
                                                                
PackageFileHeapAccessorBase(
-                                                                       
BErrorOutput* errorOutput, int fd,
-                                                                       off_t 
heapOffset,
+                                                                       
BErrorOutput* errorOutput,
+                                                                       
BPositionIO* file, off_t heapOffset,
                                                                        
DecompressionAlgorithmOwner*
                                                                                
decompressionAlgorithm);
        virtual                                         
~PackageFileHeapAccessorBase();
@@ -89,8 +89,8 @@ public:
                        // normally used after cloning a PackageFileHeapReader 
only
                        void                            
SetErrorOutput(BErrorOutput* errorOutput)
                                                                        { 
fErrorOutput = errorOutput; }
-                       void                            SetFD(int fd)
-                                                                       { fFD = 
fd; }
+                       void                            SetFile(BPositionIO* 
file)
+                                                                       { fFile 
= file; }
 
                        uint64                          HeapOverhead(uint64 
uncompressedSize) const;
                                                                        // 
additional bytes needed when storing
@@ -122,7 +122,7 @@ protected:
 
 protected:
                        BErrorOutput*           fErrorOutput;
-                       int                                     fFD;
+                       BPositionIO*            fFile;
                        off_t                           fHeapOffset;
                        uint64                          fCompressedHeapSize;
                        uint64                          fUncompressedHeapSize;
diff --git a/headers/private/package/hpkg/PackageFileHeapReader.h 
b/headers/private/package/hpkg/PackageFileHeapReader.h
index 2f64af0..00206ef 100644
--- a/headers/private/package/hpkg/PackageFileHeapReader.h
+++ b/headers/private/package/hpkg/PackageFileHeapReader.h
@@ -25,7 +25,7 @@ namespace BPrivate {
 class PackageFileHeapReader : public PackageFileHeapAccessorBase {
 public:
                                                                
PackageFileHeapReader(BErrorOutput* errorOutput,
-                                                                       int fd, 
off_t heapOffset,
+                                                                       
BPositionIO* file, off_t heapOffset,
                                                                        off_t 
compressedHeapSize,
                                                                        uint64 
uncompressedHeapSize,
                                                                        
DecompressionAlgorithmOwner*
diff --git a/headers/private/package/hpkg/PackageFileHeapWriter.h 
b/headers/private/package/hpkg/PackageFileHeapWriter.h
index 154e6d5..49588f1 100644
--- a/headers/private/package/hpkg/PackageFileHeapWriter.h
+++ b/headers/private/package/hpkg/PackageFileHeapWriter.h
@@ -35,7 +35,7 @@ class PackageFileHeapReader;
 class PackageFileHeapWriter : public PackageFileHeapAccessorBase {
 public:
                                                                
PackageFileHeapWriter(BErrorOutput* errorOutput,
-                                                                       int fd, 
off_t heapOffset,
+                                                                       
BPositionIO* file, off_t heapOffset,
                                                                        
CompressionAlgorithmOwner*
                                                                                
compressionAlgorithm,
                                                                        
DecompressionAlgorithmOwner*
diff --git a/headers/private/package/hpkg/PackageReaderImpl.h 
b/headers/private/package/hpkg/PackageReaderImpl.h
index 3f7522b..51a3999 100644
--- a/headers/private/package/hpkg/PackageReaderImpl.h
+++ b/headers/private/package/hpkg/PackageReaderImpl.h
@@ -33,12 +33,14 @@ public:
 
                        status_t                        Init(const char* 
fileName, uint32 flags);
                        status_t                        Init(int fd, bool 
keepFD, uint32 flags);
+                       status_t                        Init(BPositionIO* file, 
bool keepFile,
+                                                                       uint32 
flags);
                        status_t                        ParseContent(
                                                                        
BPackageContentHandler* contentHandler);
                        status_t                        
ParseContent(BLowLevelPackageContentHandler*
                                                                                
contentHandler);
 
-                       int                                     PackageFileFD() 
const;
+                       BPositionIO*            PackageFile() const;
 
                        uint64                          HeapOffset() const;
                        uint64                          HeapSize() const;
@@ -77,10 +79,10 @@ private:
 };
 
 
-inline int
-PackageReaderImpl::PackageFileFD() const
+inline BPositionIO*
+PackageReaderImpl::PackageFile() const
 {
-       return FD();
+       return File();
 }
 
 
diff --git a/headers/private/package/hpkg/ReaderImplBase.h 
b/headers/private/package/hpkg/ReaderImplBase.h
index b546cae..e6f1314 100644
--- a/headers/private/package/hpkg/ReaderImplBase.h
+++ b/headers/private/package/hpkg/ReaderImplBase.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
  * Distributed under the terms of the MIT License.
  */
@@ -11,7 +11,7 @@
 #include <sys/stat.h>
 
 #include <ByteOrder.h>
-#include <SupportDefs.h>
+#include <DataIO.h>
 
 #include <Array.h>
 #include <util/SinglyLinkedList.h>
@@ -77,7 +77,7 @@ protected:
                                                                        
BErrorOutput* errorOutput);
        virtual                                         ~ReaderImplBase();
 
-                       int                                     FD() const;
+                       BPositionIO*            File() const;
 
                        BErrorOutput*           ErrorOutput() const;
 
@@ -93,14 +93,14 @@ protected:
                                                                        // 
equals RawHeapReader(), if uncached
 
                        BAbstractBufferedDataReader* DetachHeapReader(
-                                                                       
PackageFileHeapReader** _rawHeapReader
-                                                                               
= NULL);
+                                                                       
PackageFileHeapReader*& _rawHeapReader);
                                                                        // 
Detaches both raw and (if applicable)
                                                                        // 
cached heap reader. The called gains
-                                                                       // 
ownership. The FD may need to be set on
-                                                                       // the 
raw heap reader, if it shall be used
-                                                                       // 
after destroying this object and Init()
-                                                                       // has 
been called with keepFD == true.
+                                                                       // 
ownership of both. The file may need to
+                                                                       // be 
set on the raw heap reader, if it
+                                                                       // 
shall be used after destroying this
+                                                                       // 
object and Init() has been called with
+                                                                       // 
keepFile == true.
 
 protected:
                        class AttributeHandlerContext;
@@ -122,8 +122,8 @@ protected:
 protected:
                        template<typename Header, uint32 kMagic, uint16 
kVersion,
                                uint16 kMinorVersion>
-                       status_t                        Init(int fd, bool 
keepFD, Header& header,
-                                                                       uint32 
flags);
+                       status_t                        Init(BPositionIO* file, 
bool keepFile,
+                                                                       Header& 
header, uint32 flags);
                        status_t                        InitHeapReader(uint32 
compression,
                                                                        uint32 
chunkSize, off_t offset,
                                                                        uint64 
compressedSize,
@@ -169,7 +169,7 @@ protected:
                        PackageFileSection      fPackageAttributesSection;
 
 private:
-                       status_t                        _Init(int fd, bool 
keepFD);
+                       status_t                        _Init(BPositionIO* 
file, bool keepFile);
 
                        status_t                        _ParseAttributeTree(
                                                                        
AttributeHandlerContext* context);
@@ -190,8 +190,8 @@ private:
 private:
                        const char*                     fFileType;
                        BErrorOutput*           fErrorOutput;
-                       int                                     fFD;
-                       bool                            fOwnsFD;
+                       BPositionIO*            fFile;
+                       bool                            fOwnsFile;
                        uint16                          fMinorFormatVersion;
                        uint16                          
fCurrentMinorFormatVersion;
 
@@ -429,17 +429,18 @@ private:
 
 template<typename Header, uint32 kMagic, uint16 kVersion, uint16 kMinorVersion>
 status_t
-ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags)
+ReaderImplBase::Init(BPositionIO* file, bool keepFile, Header& header, uint32 
flags)
 {
-       status_t error = _Init(fd, keepFD);
+       status_t error = _Init(file, keepFile);
        if (error != B_OK)
                return error;
 
-       // stat the file
-       struct stat st;
-       if (fstat(FD(), &st) < 0) {
-               ErrorOutput()->PrintError("Error: Failed to access %s file: 
%s\n",
-                       fFileType, strerror(errno));
+       // get the file size
+       off_t fileSize;
+       error = fFile->GetSize(&fileSize);
+       if (error != B_OK) {
+               ErrorOutput()->PrintError("Error: Failed to get size of %s 
file: %s\n",
+                       fFileType, strerror(error));
                return errno;
        }
 
@@ -479,10 +480,10 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, 
uint32 flags)
 
        // total size
        uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
-       if (totalSize != (uint64)st.st_size) {
+       if (totalSize != (uint64)fileSize) {
                ErrorOutput()->PrintError("Error: Invalid %s file: Total size 
in "
                        "header (%" B_PRIu64 ") doesn't agree with total file 
size (%"
-                       B_PRIdOFF ")\n", fFileType, totalSize, st.st_size);
+                       B_PRIdOFF ")\n", fFileType, totalSize, fileSize);
                return B_BAD_DATA;
        }
 
@@ -510,10 +511,10 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, 
uint32 flags)
 }
 
 
-inline int
-ReaderImplBase::FD() const
+inline BPositionIO*
+ReaderImplBase::File() const
 {
-       return fFD;
+       return fFile;
 }
 
 
diff --git a/headers/private/package/hpkg/RepositoryReaderImpl.h 
b/headers/private/package/hpkg/RepositoryReaderImpl.h
index ab40431..335dcab 100644
--- a/headers/private/package/hpkg/RepositoryReaderImpl.h
+++ b/headers/private/package/hpkg/RepositoryReaderImpl.h
@@ -30,6 +30,7 @@ public:
 
                        status_t                        Init(const char* 
fileName);
                        status_t                        Init(int fd, bool 
keepFD);
+                       status_t                        Init(BPositionIO* file, 
bool keepFile);
 
                        status_t                        GetRepositoryInfo(
                                                                        
BRepositoryInfo* _repositoryInfo) const;
diff --git a/headers/private/package/hpkg/WriterImplBase.h 
b/headers/private/package/hpkg/WriterImplBase.h
index 38496c4..2f2e326 100644
--- a/headers/private/package/hpkg/WriterImplBase.h
+++ b/headers/private/package/hpkg/WriterImplBase.h
@@ -149,7 +149,7 @@ protected:
                                                                        off_t 
offset);
                                                                        // 
writes to the file directly
 
-       inline  int                                     FD() const;
+       inline  BPositionIO*            File() const;
        inline  uint32                          Flags() const;
        inline  const BPackageWriterParameters& Parameters() const;
 
@@ -187,7 +187,7 @@ private:
                        BErrorOutput*           fErrorOutput;
                        const char*                     fFileName;
                        BPackageWriterParameters fParameters;
-                       int                                     fFD;
+                       BPositionIO*            fFile;
                        bool                            fFinished;
 
                        StringCache                     fPackageStringCache;
@@ -217,10 +217,10 @@ WriterImplBase::WriteBuffer(const void* data, size_t size)
 }
 
 
-inline int
-WriterImplBase::FD() const
+inline BPositionIO*
+WriterImplBase::File() const
 {
-       return fFD;
+       return fFile;
 }
 
 
diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile 
b/src/add-ons/kernel/file_systems/packagefs/Jamfile
index f97d56b..9766a8a 100644
--- a/src/add-ons/kernel/file_systems/packagefs/Jamfile
+++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile
@@ -110,6 +110,10 @@ local libSharedSources =
        NaturalCompare.cpp
 ;
 
+local storageKitSources =
+       FdIO.cpp
+;
+
 local supportKitSources =
        CompressionAlgorithm.cpp
        ZlibCompressionAlgorithm.cpp
@@ -122,6 +126,7 @@ KernelAddon packagefs
        $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES)
        $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1)
        $(libSharedSources)
+       $(storageKitSources)
        $(supportKitSources)
 
        : $(TARGET_KERNEL_LIBSUPC++) kernel_libz.a
@@ -136,5 +141,7 @@ SEARCH on [ FGristFiles 
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1) ]
        += [ FDirName $(HAIKU_TOP) src kits package hpkg v1 ] ;
 SEARCH on [ FGristFiles $(libSharedSources) ]
        += [ FDirName $(HAIKU_TOP) src kits shared ] ;
+SEARCH on [ FGristFiles $(storageKitSources) ]
+       += [ FDirName $(HAIKU_TOP) src kits storage ] ;
 SEARCH on [ FGristFiles $(supportKitSources) ]
        += [ FDirName $(HAIKU_TOP) src kits support ] ;
diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
index b546632..4bf5c30 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
@@ -20,6 +20,7 @@
 #include <package/hpkg/v1/PackageEntryAttribute.h>
 
 #include <AutoDeleter.h>
+#include <FdIO.h>
 #include <package/hpkg/PackageFileHeapReader.h>
 #include <package/hpkg/PackageReaderImpl.h>
 #include <package/hpkg/v1/PackageReaderImpl.h>
@@ -687,7 +688,7 @@ private:
 
 
 struct Package::HeapReaderV2 : public HeapReader, public CachedDataReader,
-       private BErrorOutput {
+       private BErrorOutput, private BFdIO {
 public:
        HeapReaderV2()
                :
@@ -706,8 +707,10 @@ public:
                if (fHeapReader == NULL)
                        return B_NO_MEMORY;
 
+               BFdIO::SetTo(fd, false);
+
                fHeapReader->SetErrorOutput(this);
-               fHeapReader->SetFD(fd);
+               fHeapReader->SetFile(this);
 
                status_t error = CachedDataReader::Init(fHeapReader,
                        fHeapReader->UncompressedHeapSize());
@@ -719,7 +722,7 @@ public:
 
        virtual void UpdateFD(int fd)
        {
-               fHeapReader->SetFD(fd);
+               BFdIO::SetTo(fd, false);
        }
 
        virtual status_t CreateDataReader(const PackageData& data,
@@ -749,7 +752,8 @@ struct Package::CachingPackageReader : public 
PackageReaderImpl {
        CachingPackageReader(BErrorOutput* errorOutput)
                :
                PackageReaderImpl(errorOutput),
-               fCachedHeapReader(NULL)
+               fCachedHeapReader(NULL),
+               fFD(-1)
        {
        }
 
@@ -757,6 +761,12 @@ struct Package::CachingPackageReader : public 
PackageReaderImpl {
        {
        }
 
+       status_t Init(int fd, bool keepFD, uint32 flags)
+       {
+               fFD = fd;
+               return PackageReaderImpl::Init(fd, keepFD, flags);
+       }
+
        virtual status_t CreateCachedHeapReader(
                PackageFileHeapReader* rawHeapReader,
                BAbstractBufferedDataReader*& _cachedReader)
@@ -765,7 +775,7 @@ struct Package::CachingPackageReader : public 
PackageReaderImpl {
                if (fCachedHeapReader == NULL)
                        RETURN_ERROR(B_NO_MEMORY);
 
-               status_t error = fCachedHeapReader->Init(rawHeapReader, FD());
+               status_t error = fCachedHeapReader->Init(rawHeapReader, fFD);
                if (error != B_OK)
                        RETURN_ERROR(error);
 
@@ -775,7 +785,12 @@ struct Package::CachingPackageReader : public 
PackageReaderImpl {
 
        HeapReaderV2* DetachCachedHeapReader()
        {
-               DetachHeapReader();
+               PackageFileHeapReader* rawHeapReader;
+               DetachHeapReader(rawHeapReader);
+
+               // We don't need the raw heap reader anymore, since the cached 
reader
+               // is not a wrapper around it, but completely independent from 
it.
+               delete rawHeapReader;
 
                HeapReaderV2* cachedHeapReader = fCachedHeapReader;
                fCachedHeapReader = NULL;
@@ -784,6 +799,7 @@ struct Package::CachingPackageReader : public 
PackageReaderImpl {
 
 private:
        HeapReaderV2*   fCachedHeapReader;
+       int                             fFD;
 };
 
 
diff --git a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp 
b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp
index b8981e1..f8bd2da 100644
--- a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp
+++ b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp
@@ -6,7 +6,6 @@
 
 #include <package/hpkg/PackageFileHeapAccessorBase.h>
 
-#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -122,11 +121,11 @@ PackageFileHeapAccessorBase::OffsetArray::Init(size_t 
totalChunkCount,
 
 
 PackageFileHeapAccessorBase::PackageFileHeapAccessorBase(
-       BErrorOutput* errorOutput, int fd, off_t heapOffset,
+       BErrorOutput* errorOutput, BPositionIO* file, off_t heapOffset,
        DecompressionAlgorithmOwner* decompressionAlgorithm)
        :
        fErrorOutput(errorOutput),
-       fFD(fd),
+       fFile(file),
        fHeapOffset(heapOffset),
        fCompressedHeapSize(0),
        fUncompressedHeapSize(0),
@@ -252,16 +251,12 @@ status_t
 PackageFileHeapAccessorBase::ReadFileData(uint64 offset, void* buffer,
        size_t size)
 {
-       ssize_t bytesRead = pread(fFD, buffer, size, fHeapOffset + 
(off_t)offset);
-       if (bytesRead < 0) {
+       status_t error = fFile->ReadAtExactly(fHeapOffset + (off_t)offset, 
buffer,
+               size);
+       if (error != B_OK) {
                fErrorOutput->PrintError("ReadFileData(%" B_PRIu64 ", %p, %zu) 
failed "
-                       "to read data: %s\n", offset, buffer, size, 
strerror(errno));
-               return errno;
-       }
-       if ((size_t)bytesRead != size) {
-               fErrorOutput->PrintError("ReadFileData(%" B_PRIu64 ", %p, %zu) 
could "
-                       "read only %zd bytes\n", offset, buffer, size, 
bytesRead);
-               return B_ERROR;
+                       "to read data: %s\n", offset, buffer, size, 
strerror(error));
+               return error;
        }
 
        return B_OK;
diff --git a/src/kits/package/hpkg/PackageFileHeapReader.cpp 
b/src/kits/package/hpkg/PackageFileHeapReader.cpp
index 056ca4d..9af47d0 100644
--- a/src/kits/package/hpkg/PackageFileHeapReader.cpp
+++ b/src/kits/package/hpkg/PackageFileHeapReader.cpp
@@ -23,11 +23,12 @@ namespace BHPKG {
 namespace BPrivate {
 
 
-PackageFileHeapReader::PackageFileHeapReader(BErrorOutput* errorOutput, int fd,
-       off_t heapOffset, off_t compressedHeapSize, uint64 uncompressedHeapSize,
+PackageFileHeapReader::PackageFileHeapReader(BErrorOutput* errorOutput,
+       BPositionIO* file, off_t heapOffset, off_t compressedHeapSize,
+       uint64 uncompressedHeapSize,
        DecompressionAlgorithmOwner* decompressionAlgorithm)
        :
-       PackageFileHeapAccessorBase(errorOutput, fd, heapOffset,
+       PackageFileHeapAccessorBase(errorOutput, file, heapOffset,
                decompressionAlgorithm),
        fOffsets()
 {
@@ -118,7 +119,7 @@ PackageFileHeapReader*
 PackageFileHeapReader::Clone() const
 {
        PackageFileHeapReader* clone = new(std::nothrow) PackageFileHeapReader(
-               fErrorOutput, fFD, fHeapOffset, fCompressedHeapSize,
+               fErrorOutput, fFile, fHeapOffset, fCompressedHeapSize,
                fUncompressedHeapSize, fDecompressionAlgorithm);
        if (clone == NULL)
                return NULL;
diff --git a/src/kits/package/hpkg/PackageFileHeapWriter.cpp 
b/src/kits/package/hpkg/PackageFileHeapWriter.cpp
index 9712042..1a17ef1 100644
--- a/src/kits/package/hpkg/PackageFileHeapWriter.cpp
+++ b/src/kits/package/hpkg/PackageFileHeapWriter.cpp
@@ -6,8 +6,6 @@
 
 #include <package/hpkg/PackageFileHeapWriter.h>
 
-#include <errno.h>
-
 #include <algorithm>
 #include <new>
 
@@ -196,11 +194,12 @@ private:
 };
 
 
-PackageFileHeapWriter::PackageFileHeapWriter(BErrorOutput* errorOutput, int fd,
-       off_t heapOffset, CompressionAlgorithmOwner* compressionAlgorithm,
+PackageFileHeapWriter::PackageFileHeapWriter(BErrorOutput* errorOutput,
+       BPositionIO* file, off_t heapOffset,
+       CompressionAlgorithmOwner* compressionAlgorithm,
        DecompressionAlgorithmOwner* decompressionAlgorithm)
        :
-       PackageFileHeapAccessorBase(errorOutput, fd, heapOffset,
+       PackageFileHeapAccessorBase(errorOutput, file, heapOffset,
                decompressionAlgorithm),
        fPendingDataBuffer(NULL),
        fCompressedDataBuffer(NULL),
@@ -580,18 +579,14 @@ PackageFileHeapWriter::_WriteDataCompressed(const void* 
data, size_t size)
 status_t
 PackageFileHeapWriter::_WriteDataUncompressed(const void* data, size_t size)
 {
-       ssize_t bytesWritten = pwrite(fFD, data, size,
-               fHeapOffset + (off_t)fCompressedHeapSize);
-       if (bytesWritten < 0) {
-               fErrorOutput->PrintError("Failed to write data: %s\n", 
strerror(errno));
-               return errno;
-       }
-       if ((size_t)bytesWritten != size) {
-               fErrorOutput->PrintError("Failed to write all data\n");
-               return B_ERROR;
+       status_t error = fFile->WriteAtExactly(
+               fHeapOffset + (off_t)fCompressedHeapSize, data, size);
+       if (error != B_OK) {
+               fErrorOutput->PrintError("Failed to write data: %s\n", 
strerror(error));
+               return error;
        }
 
-       fCompressedHeapSize += bytesWritten;
+       fCompressedHeapSize += size;
 
        return B_OK;
 }
diff --git a/src/kits/package/hpkg/PackageReader.cpp 
b/src/kits/package/hpkg/PackageReader.cpp
index 1ddeb15..527f851 100644
--- a/src/kits/package/hpkg/PackageReader.cpp
+++ b/src/kits/package/hpkg/PackageReader.cpp
@@ -53,6 +53,16 @@ BPackageReader::Init(int fd, bool keepFD, uint32 flags)
 
 
 status_t
+BPackageReader::Init(BPositionIO* file, bool keepFile, uint32 flags)
+{
+       if (fImpl == NULL)
+               return B_NO_INIT;
+
+       return fImpl->Init(file, keepFile, flags);
+}
+
+
+status_t
 BPackageReader::ParseContent(BPackageContentHandler* contentHandler)
 {
        if (fImpl == NULL)
@@ -72,13 +82,13 @@ 
BPackageReader::ParseContent(BLowLevelPackageContentHandler* contentHandler)
 }
 
 
-int
-BPackageReader::PackageFileFD()
+BPositionIO*
+BPackageReader::PackageFile() const
 {
        if (fImpl == NULL)
-               return -1;
+               return NULL;
 
-       return fImpl->PackageFileFD();
+       return fImpl->PackageFile();
 }
 
 
diff --git a/src/kits/package/hpkg/PackageReaderImpl.cpp 
b/src/kits/package/hpkg/PackageReaderImpl.cpp
index 06d4069..4bc0073 100644
--- a/src/kits/package/hpkg/PackageReaderImpl.cpp
+++ b/src/kits/package/hpkg/PackageReaderImpl.cpp
@@ -20,6 +20,8 @@
 
 #include <ByteOrder.h>
 
+#include <FdIO.h>
+
 #include <package/hpkg/HPKGDefsPrivate.h>
 
 #include <package/hpkg/PackageData.h>
@@ -332,9 +334,23 @@ PackageReaderImpl::Init(const char* fileName, uint32 flags)
 status_t
 PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags)
 {
+       BFdIO* file = new(std::nothrow) BFdIO(fd, keepFD);
+       if (file == NULL) {
+               if (keepFD && fd >= 0)
+                       close(fd);
+               return B_NO_MEMORY;
+       }
+
+       return Init(file, true, flags);
+}
+
+
+status_t
+PackageReaderImpl::Init(BPositionIO* file, bool keepFile, uint32 flags)
+{
        hpkg_header header;
        status_t error = inherited::Init<hpkg_header, B_HPKG_MAGIC, 
B_HPKG_VERSION,
-               B_HPKG_MINOR_VERSION>(fd, keepFD, header, flags);
+               B_HPKG_MINOR_VERSION>(file, keepFile, header, flags);
        if (error != B_OK)
                return error;
        fHeapSize = UncompressedHeapSize();
diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp 
b/src/kits/package/hpkg/PackageWriterImpl.cpp
index 740f454..e009636 100644
--- a/src/kits/package/hpkg/PackageWriterImpl.cpp
+++ b/src/kits/package/hpkg/PackageWriterImpl.cpp
@@ -648,7 +648,7 @@ PackageWriterImpl::_Init(const char* fileName,
        // in update mode, parse the TOC
        if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) {
                PackageReaderImpl packageReader(fListener);
-               result = packageReader.Init(FD(), false, 0);
+               result = packageReader.Init(File(), false, 0);
                if (result != B_OK)
                        return result;
 
@@ -716,7 +716,8 @@ PackageWriterImpl::_Finish()
        // can be greater when one or more files are shrunk. In creation mode it
        // should already have the correct size.
        off_t totalSize = fHeapWriter->HeapOffset() + (off_t)compressedHeapSize;
-       if (ftruncate(FD(), totalSize) != 0) {
+       error = File()->SetSize(totalSize);
+       if (error != B_OK) {
                fListener->PrintError("Failed to truncate package file to new "
                        "size: %s\n", strerror(errno));
                return errno;
diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp 
b/src/kits/package/hpkg/ReaderImplBase.cpp
index 491a923..eb301f7 100644
--- a/src/kits/package/hpkg/ReaderImplBase.cpp
+++ b/src/kits/package/hpkg/ReaderImplBase.cpp
@@ -764,8 +764,8 @@ ReaderImplBase::ReaderImplBase(const char* fileType, 
BErrorOutput* errorOutput)
        fPackageAttributesSection("package attributes"),
        fFileType(fileType),
        fErrorOutput(errorOutput),
-       fFD(-1),
-       fOwnsFD(false),
+       fFile(NULL),
+       fOwnsFile(false),
        fRawHeapReader(NULL),
        fHeapReader(NULL),
        fCurrentSection(NULL)
@@ -779,8 +779,8 @@ ReaderImplBase::~ReaderImplBase()
        if (fRawHeapReader != fHeapReader)
                delete fRawHeapReader;
 
-       if (fOwnsFD && fFD >= 0)
-               close(fFD);
+       if (fOwnsFile)
+               delete fFile;
 }
 
 
@@ -792,13 +792,11 @@ ReaderImplBase::UncompressedHeapSize() const
 
 
 BAbstractBufferedDataReader*
-ReaderImplBase::DetachHeapReader(PackageFileHeapReader** _rawHeapReader)
+ReaderImplBase::DetachHeapReader(PackageFileHeapReader*& _rawHeapReader)
 {
        BAbstractBufferedDataReader* heapReader = fHeapReader;
+       _rawHeapReader = fRawHeapReader;
        fHeapReader = NULL;
-
-       if (_rawHeapReader != NULL)
-               *_rawHeapReader = fRawHeapReader;
        fRawHeapReader = NULL;
 
        return heapReader;
@@ -827,8 +825,9 @@ ReaderImplBase::InitHeapReader(uint32 compression, uint32 
chunkSize,
                return B_NO_MEMORY;
        }
 
-       fRawHeapReader = new(std::nothrow) PackageFileHeapReader(fErrorOutput, 
fFD,
-               offset, compressedSize, uncompressedSize, 
decompressionAlgorithm);
+       fRawHeapReader = new(std::nothrow) PackageFileHeapReader(fErrorOutput,
+               fFile, offset, compressedSize, uncompressedSize,
+               decompressionAlgorithm);
        if (fRawHeapReader == NULL)
                return B_NO_MEMORY;
 
@@ -1059,12 +1058,11 @@ 
ReaderImplBase::ParseAttributeTree(AttributeHandlerContext* context,
 
 
 status_t
-ReaderImplBase::_Init(int fd, bool keepFD)
+ReaderImplBase::_Init(BPositionIO* file, bool keepFile)
 {
-       fFD = fd;
-       fOwnsFD = keepFD;
-
-       return B_OK;
+       fFile = file;
+       fOwnsFile = keepFile;
+       return fFile != NULL ? B_OK : B_BAD_VALUE;
 }
 
 
@@ -1341,16 +1339,11 @@ ReaderImplBase::_ReadSectionBuffer(void* buffer, size_t 
size)
 status_t
 ReaderImplBase::ReadBuffer(off_t offset, void* buffer, size_t size)
 {
-       ssize_t bytesRead = pread(fFD, buffer, size, offset);
-       if (bytesRead < 0) {
+       status_t error = fFile->ReadAtExactly(offset, buffer, size);
+       if (error != B_OK) {
                fErrorOutput->PrintError("_ReadBuffer(%p, %lu) failed to read 
data: "
-                       "%s\n", buffer, size, strerror(errno));
-               return errno;
-       }
-       if ((size_t)bytesRead != size) {
-               fErrorOutput->PrintError("_ReadBuffer(%p, %lu) failed to read 
all "
-                       "data\n", buffer, size);
-               return B_ERROR;
+                       "%s\n", buffer, size, strerror(error));
+               return error;
        }
 
        return B_OK;
diff --git a/src/kits/package/hpkg/RepositoryReaderImpl.cpp 
b/src/kits/package/hpkg/RepositoryReaderImpl.cpp
index 4758782..362ec7a 100644
--- a/src/kits/package/hpkg/RepositoryReaderImpl.cpp
+++ b/src/kits/package/hpkg/RepositoryReaderImpl.cpp
@@ -18,6 +18,8 @@
 #include <ByteOrder.h>
 #include <Message.h>
 
+#include <FdIO.h>
+
 #include <package/hpkg/HPKGDefsPrivate.h>
 #include <package/hpkg/RepositoryContentHandler.h>
 
@@ -197,9 +199,24 @@ RepositoryReaderImpl::Init(const char* fileName)
 status_t
 RepositoryReaderImpl::Init(int fd, bool keepFD)
 {
+       BFdIO* file = new(std::nothrow) BFdIO(fd, keepFD);
+       if (file == NULL) {
+               if (keepFD && fd >= 0)
+                       close(fd);
+               return B_NO_MEMORY;
+       }
+
+       return Init(file, true);
+}
+
+
+status_t
+RepositoryReaderImpl::Init(BPositionIO* file, bool keepFile)
+{
        hpkg_repo_header header;
        status_t error = inherited::Init<hpkg_repo_header, B_HPKG_REPO_MAGIC,
-               B_HPKG_REPO_VERSION, B_HPKG_REPO_MINOR_VERSION>(fd, keepFD, 
header, 0);
+               B_HPKG_REPO_VERSION, B_HPKG_REPO_MINOR_VERSION>(file, keepFile, 
header,
+               0);
        if (error != B_OK)
                return error;
 
diff --git a/src/kits/package/hpkg/WriterImplBase.cpp 
b/src/kits/package/hpkg/WriterImplBase.cpp
index b70eeb7..51fdabb 100644
--- a/src/kits/package/hpkg/WriterImplBase.cpp
+++ b/src/kits/package/hpkg/WriterImplBase.cpp
@@ -16,6 +16,7 @@
 #include <new>
 
 #include <ByteOrder.h>
+#include <File.h>
 
 #include <AutoDeleter.h>
 #include <ZlibCompressionAlgorithm.h>
@@ -226,7 +227,7 @@ WriterImplBase::WriterImplBase(const char* fileType, 
BErrorOutput* errorOutput)
        fErrorOutput(errorOutput),
        fFileName(NULL),
        fParameters(),
-       fFD(-1),
+       fFile(NULL),
        fFinished(false)
 {
 }
@@ -240,8 +241,7 @@ WriterImplBase::~WriterImplBase()
        delete fDecompressionAlgorithm;
        delete fDecompressionParameters;
 
-       if (fFD >= 0)
-               close(fFD);
+       delete fFile;
 
        if (!fFinished && fFileName != NULL
                && (Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) {
@@ -264,13 +264,16 @@ WriterImplBase::Init(const char* fileName, size_t 
headerSize,
        if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0)
                openMode |= O_CREAT | O_TRUNC;
 
-       fFD = open(fileName, openMode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-       if (fFD < 0) {
+       BFile* file = new BFile;
+       status_t error = file->SetTo(fileName, openMode);
+       if (error != B_OK) {
                fErrorOutput->PrintError("Failed to open %s file \"%s\": %s\n",
                        fFileType, fileName, strerror(errno));
-               return errno;
+               delete file;
+               return error;
        }
 
+       fFile = file;
        fFileName = fileName;
 
        DecompressionAlgorithmOwner* decompressionAlgorithm
@@ -305,7 +308,7 @@ WriterImplBase::Init(const char* fileName, size_t 
headerSize,
                compressionAlgorithm, true);
 
        // create heap writer
-       fHeapWriter = new PackageFileHeapWriter(fErrorOutput, FD(), headerSize,
+       fHeapWriter = new PackageFileHeapWriter(fErrorOutput, fFile, headerSize,
                compressionAlgorithm, decompressionAlgorithm);
        fHeapWriter->Init();
 
@@ -717,17 +720,12 @@ WriterImplBase::WriteUnsignedLEB128(uint64 value)
 void
 WriterImplBase::RawWriteBuffer(const void* buffer, size_t size, off_t offset)
 {
-       ssize_t bytesWritten = pwrite(fFD, buffer, size, offset);
-       if (bytesWritten < 0) {
+       status_t error = fFile->WriteAtExactly(offset, buffer, size);
+       if (error != B_OK) {
                fErrorOutput->PrintError(
                        "RawWriteBuffer(%p, %lu) failed to write data: %s\n", 
buffer, size,
-                       strerror(errno));
-               throw status_t(errno);
-       }
-       if ((size_t)bytesWritten != size) {
-               fErrorOutput->PrintError(
-                       "RawWriteBuffer(%p, %lu) failed to write all data\n", 
buffer, size);
-               throw status_t(B_ERROR);
+                       strerror(error));
+               throw error;
        }
 }
 
diff --git a/src/system/boot/loader/file_systems/packagefs/Jamfile 
b/src/system/boot/loader/file_systems/packagefs/Jamfile
index 45b5873..8ef09b5 100644
--- a/src/system/boot/loader/file_systems/packagefs/Jamfile
+++ b/src/system/boot/loader/file_systems/packagefs/Jamfile
@@ -1,7 +1,7 @@
 SubDir HAIKU_TOP src system boot loader file_systems packagefs ;
 
 UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ;
-UsePrivateHeaders kernel shared support ;
+UsePrivateHeaders kernel shared storage support ;
 UseBuildFeatureHeaders zlib ;
 
 DEFINES += _BOOT_MODE ;
@@ -13,6 +13,7 @@ SubDirC++Flags -fno-rtti -include $(kernelC++Header) ;
 
 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package ] ;
 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg ] ;
+SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits storage ] ;
 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits support ] ;
 
 
@@ -20,8 +21,6 @@ BootStaticLibrary boot_packagefs :
        packagefs.cpp
        PackageSettingsItem.cpp
 
-       # package kit
-
        # package kit/hpkg
        BlockBufferPool.cpp
        BlockBufferPoolImpl.cpp
@@ -41,8 +40,10 @@ BootStaticLibrary boot_packagefs :
        PackageReaderImpl.cpp
        ReaderImplBase.cpp
 
-       # support kit
+       # storage kit
+       FdIO.cpp
 
+       # support kit
        CompressionAlgorithm.cpp
        ZlibCompressionAlgorithm.cpp
 
diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp 
b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp
index 5223662..52be867 100644
--- a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp
+++ b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2011-2014, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -18,6 +18,7 @@
 #include <package/hpkg/PackageReaderImpl.h>
 
 #include <AutoDeleter.h>
+#include <FdIO.h>
 
 #include <util/DoublyLinkedList.h>
 
@@ -299,16 +300,14 @@ struct PackageVolume : BReferenceable, private 
PackageLoaderErrorOutput {
                fNextNodeID(1),
                fRootDirectory(this, S_IFDIR),
                fHeapReader(NULL),
-               fFD(-1)
+               fFile(NULL)
        {
        }
 
        ~PackageVolume()
        {
                delete fHeapReader;
-
-               if (fFD >= 0)
-                       close(fFD);
+               delete fFile;
        }
 
        status_t Init(int fd, const PackageFileHeapReader* heapReader)
@@ -318,17 +317,23 @@ struct PackageVolume : BReferenceable, private 
PackageLoaderErrorOutput {
                if (error != B_OK)
                        return error;
 
-               fFD = dup(fd);
-               if (fFD < 0)
+               fd = dup(fd);
+               if (fd < 0)
                        return errno;
 
+               fFile = new(std::nothrow) BFdIO(fd, true);
+               if (fFile == NULL) {
+                       close(fd);
+                       return B_NO_MEMORY;
+               }
+
                // clone a heap reader and adjust it for our use
                fHeapReader = heapReader->Clone();
                if (fHeapReader == NULL)
                        return B_NO_MEMORY;
 
                fHeapReader->SetErrorOutput(this);
-               fHeapReader->SetFD(fFD);
+               fHeapReader->SetFile(fFile);
 
                return B_OK;
        }
@@ -354,7 +359,7 @@ private:
        ino_t                                           fNextNodeID;
        PackageDirectory                        fRootDirectory;
        PackageFileHeapReader*          fHeapReader;
-       int                                                     fFD;
+       BPositionIO*                            fFile;
 };
 
 


Other related posts:

  • » [haiku-commits] haiku: hrev47488 - src/kits/package/hpkg headers/private/package/hpkg docs/user/support src/kits/storage src/kits/support - ingo_weinhold