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; };