152a38012Sejakowatz //---------------------------------------------------------------------- 252a38012Sejakowatz // This software is part of the OpenBeOS distribution and is covered 352a38012Sejakowatz // by the OpenBeOS license. 452a38012Sejakowatz //--------------------------------------------------------------------- 552a38012Sejakowatz /*! 652a38012Sejakowatz \file File.cpp 752a38012Sejakowatz BFile implementation. 852a38012Sejakowatz */ 952a38012Sejakowatz 1052a38012Sejakowatz #include <fsproto.h> 1152a38012Sejakowatz 1252a38012Sejakowatz #include <Entry.h> 1352a38012Sejakowatz #include <File.h> 1452a38012Sejakowatz #include "kernel_interface.h" 1552a38012Sejakowatz 1652a38012Sejakowatz #ifdef USE_OPENBEOS_NAMESPACE 1752a38012Sejakowatz namespace OpenBeOS { 1852a38012Sejakowatz #endif 1952a38012Sejakowatz 2052a38012Sejakowatz // constructor 2152a38012Sejakowatz //! Creates an uninitialized BFile. 2252a38012Sejakowatz BFile::BFile() 2352a38012Sejakowatz : BNode(), 2452a38012Sejakowatz BPositionIO(), 2552a38012Sejakowatz fMode(0) 2652a38012Sejakowatz { 2752a38012Sejakowatz } 2852a38012Sejakowatz 2952a38012Sejakowatz // copy constructor 3052a38012Sejakowatz //! Creates a copy of the supplied BFile. 3152a38012Sejakowatz /*! If \a file is uninitialized, the newly constructed BFile will be, too. 3252a38012Sejakowatz \param file the BFile object to be copied 3352a38012Sejakowatz */ 3452a38012Sejakowatz BFile::BFile(const BFile &file) 3552a38012Sejakowatz : BNode(), 3652a38012Sejakowatz BPositionIO(), 3752a38012Sejakowatz fMode(0) 3852a38012Sejakowatz { 3952a38012Sejakowatz *this = file; 4052a38012Sejakowatz } 4152a38012Sejakowatz 4252a38012Sejakowatz // constructor 4352a38012Sejakowatz /*! \brief Creates a BFile and initializes it to the file referred to by 4452a38012Sejakowatz the supplied entry_ref and according to the specified open mode. 4552a38012Sejakowatz \param ref the entry_ref referring to the file 4652a38012Sejakowatz \param openMode the mode in which the file should be opened 4752a38012Sejakowatz \see SetTo() for values for \a openMode 4852a38012Sejakowatz */ 4952a38012Sejakowatz BFile::BFile(const entry_ref *ref, uint32 openMode) 5052a38012Sejakowatz : BNode(), 5152a38012Sejakowatz BPositionIO(), 5252a38012Sejakowatz fMode(0) 5352a38012Sejakowatz { 5452a38012Sejakowatz SetTo(ref, openMode); 5552a38012Sejakowatz } 5652a38012Sejakowatz 5752a38012Sejakowatz // constructor 5852a38012Sejakowatz /*! \brief Creates a BFile and initializes it to the file referred to by 5952a38012Sejakowatz the supplied BEntry and according to the specified open mode. 6052a38012Sejakowatz \param entry the BEntry referring to the file 6152a38012Sejakowatz \param openMode the mode in which the file should be opened 6252a38012Sejakowatz \see SetTo() for values for \a openMode 6352a38012Sejakowatz */ 6452a38012Sejakowatz BFile::BFile(const BEntry *entry, uint32 openMode) 6552a38012Sejakowatz : BNode(), 6652a38012Sejakowatz BPositionIO(), 6752a38012Sejakowatz fMode(0) 6852a38012Sejakowatz { 6952a38012Sejakowatz SetTo(entry, openMode); 7052a38012Sejakowatz } 7152a38012Sejakowatz 7252a38012Sejakowatz // constructor 7352a38012Sejakowatz /*! \brief Creates a BFile and initializes it to the file referred to by 7452a38012Sejakowatz the supplied path name and according to the specified open mode. 7552a38012Sejakowatz \param path the file's path name 7652a38012Sejakowatz \param openMode the mode in which the file should be opened 7752a38012Sejakowatz \see SetTo() for values for \a openMode 7852a38012Sejakowatz */ 7952a38012Sejakowatz BFile::BFile(const char *path, uint32 openMode) 8052a38012Sejakowatz : BNode(), 8152a38012Sejakowatz BPositionIO(), 8252a38012Sejakowatz fMode(0) 8352a38012Sejakowatz { 8452a38012Sejakowatz SetTo(path, openMode); 8552a38012Sejakowatz } 8652a38012Sejakowatz 8752a38012Sejakowatz // constructor 8852a38012Sejakowatz /*! \brief Creates a BFile and initializes it to the file referred to by 8952a38012Sejakowatz the supplied path name relative to the specified BDirectory and 9052a38012Sejakowatz according to the specified open mode. 9152a38012Sejakowatz \param dir the BDirectory, relative to which the file's path name is 9252a38012Sejakowatz given 9352a38012Sejakowatz \param path the file's path name relative to \a dir 9452a38012Sejakowatz \param openMode the mode in which the file should be opened 9552a38012Sejakowatz \see SetTo() for values for \a openMode 9652a38012Sejakowatz */ 9723d36867Sbeveloper BFile::BFile(const BDirectory *dir, const char *path, uint32 openMode) 9852a38012Sejakowatz : BNode(), 9952a38012Sejakowatz BPositionIO(), 10052a38012Sejakowatz fMode(0) 10152a38012Sejakowatz { 10252a38012Sejakowatz SetTo(dir, path, openMode); 10352a38012Sejakowatz } 10452a38012Sejakowatz 10552a38012Sejakowatz // destructor 10652a38012Sejakowatz //! Frees all allocated resources. 10752a38012Sejakowatz /*! If the file is properly initialized, the file's file descriptor is closed. 10852a38012Sejakowatz */ 10952a38012Sejakowatz BFile::~BFile() 11052a38012Sejakowatz { 11152a38012Sejakowatz // Also called by the BNode destructor, but we rather try to avoid 11252a38012Sejakowatz // problems with calling virtual functions in the base class destructor. 11352a38012Sejakowatz // Depending on the compiler implementation an object may be degraded to 11452a38012Sejakowatz // an object of the base class after the destructor of the derived class 11552a38012Sejakowatz // has been executed. 11652a38012Sejakowatz close_fd(); 11752a38012Sejakowatz } 11852a38012Sejakowatz 11952a38012Sejakowatz // SetTo 12052a38012Sejakowatz /*! \brief Re-initializes the BFile to the file referred to by the 12152a38012Sejakowatz supplied entry_ref and according to the specified open mode. 12252a38012Sejakowatz \param ref the entry_ref referring to the file 12352a38012Sejakowatz \param openMode the mode in which the file should be opened 12452a38012Sejakowatz \a openMode must be a bitwise or of exactly one of the flags 12552a38012Sejakowatz - \c B_READ_ONLY: The file is opened read only. 12652a38012Sejakowatz - \c B_WRITE_ONLY: The file is opened write only. 12752a38012Sejakowatz - \c B_READ_WRITE: The file is opened for random read/write access. 12852a38012Sejakowatz and any number of the flags 12952a38012Sejakowatz - \c B_CREATE_FILE: A new file will be created, if it does not already 13052a38012Sejakowatz exist. 13152a38012Sejakowatz - \c B_FAIL_IF_EXISTS: If the file does already exist and B_CREATE_FILE is 13252a38012Sejakowatz set, SetTo() fails. 13352a38012Sejakowatz - \c B_ERASE_FILE: An already existing file is truncated to zero size. 13452a38012Sejakowatz - \c B_OPEN_AT_END: Seek() to the end of the file after opening. 13552a38012Sejakowatz \return 13652a38012Sejakowatz - \c B_OK: Everything went fine. 13752a38012Sejakowatz - \c B_BAD_VALUE: \c NULL \a ref or bad \a openMode. 13852a38012Sejakowatz - \c B_ENTRY_NOT_FOUND: File not found or failed to create file. 13952a38012Sejakowatz - \c B_FILE_EXISTS: File exists and \c B_FAIL_IF_EXISTS was passed. 14052a38012Sejakowatz - \c B_PERMISSION_DENIED: File permissions didn't allow operation. 14152a38012Sejakowatz - \c B_NO_MEMORY: Insufficient memory for operation. 14252a38012Sejakowatz - \c B_LINK_LIMIT: Indicates a cyclic loop within the file system. 14352a38012Sejakowatz - \c B_BUSY: A node was busy. 14452a38012Sejakowatz - \c B_FILE_ERROR: A general file error. 14552a38012Sejakowatz - \c B_NO_MORE_FDS: The application has run out of file descriptors. 14609d84e61STyler Dauwalder \todo Currently implemented using BPrivate::Storage::entry_ref_to_path(). 14752a38012Sejakowatz Reimplement! 14852a38012Sejakowatz */ 14952a38012Sejakowatz status_t 15052a38012Sejakowatz BFile::SetTo(const entry_ref *ref, uint32 openMode) 15152a38012Sejakowatz { 15252a38012Sejakowatz Unset(); 1539a17c3cfSIngo Weinhold char path[B_PATH_NAME_LENGTH]; 15452a38012Sejakowatz status_t error = (ref ? B_OK : B_BAD_VALUE); 15552a38012Sejakowatz if (error == B_OK) { 15609d84e61STyler Dauwalder error = BPrivate::Storage::entry_ref_to_path(ref, path, 1579a17c3cfSIngo Weinhold B_PATH_NAME_LENGTH); 15852a38012Sejakowatz } 15952a38012Sejakowatz if (error == B_OK) 16052a38012Sejakowatz error = SetTo(path, openMode); 16152a38012Sejakowatz set_status(error); 16252a38012Sejakowatz return error; 16352a38012Sejakowatz } 16452a38012Sejakowatz 16552a38012Sejakowatz // SetTo 16652a38012Sejakowatz /*! \brief Re-initializes the BFile to the file referred to by the 16752a38012Sejakowatz supplied BEntry and according to the specified open mode. 16852a38012Sejakowatz \param entry the BEntry referring to the file 16952a38012Sejakowatz \param openMode the mode in which the file should be opened 17052a38012Sejakowatz \return 17152a38012Sejakowatz - \c B_OK: Everything went fine. 17252a38012Sejakowatz - \c B_BAD_VALUE: \c NULL \a entry or bad \a openMode. 17352a38012Sejakowatz - \c B_ENTRY_NOT_FOUND: File not found or failed to create file. 17452a38012Sejakowatz - \c B_FILE_EXISTS: File exists and \c B_FAIL_IF_EXISTS was passed. 17552a38012Sejakowatz - \c B_PERMISSION_DENIED: File permissions didn't allow operation. 17652a38012Sejakowatz - \c B_NO_MEMORY: Insufficient memory for operation. 17752a38012Sejakowatz - \c B_LINK_LIMIT: Indicates a cyclic loop within the file system. 17852a38012Sejakowatz - \c B_BUSY: A node was busy. 17952a38012Sejakowatz - \c B_FILE_ERROR: A general file error. 18052a38012Sejakowatz - \c B_NO_MORE_FDS: The application has run out of file descriptors. 18152a38012Sejakowatz \todo Implemented using SetTo(entry_ref*, uint32). Check, if necessary 18252a38012Sejakowatz to reimplement! 18352a38012Sejakowatz */ 18452a38012Sejakowatz status_t 18552a38012Sejakowatz BFile::SetTo(const BEntry *entry, uint32 openMode) 18652a38012Sejakowatz { 18752a38012Sejakowatz Unset(); 18852a38012Sejakowatz entry_ref ref; 18952a38012Sejakowatz status_t error = (entry ? B_OK : B_BAD_VALUE); 19052a38012Sejakowatz if (error == B_OK) 19152a38012Sejakowatz error = entry->GetRef(&ref); 19252a38012Sejakowatz if (error == B_OK) 19352a38012Sejakowatz error = SetTo(&ref, openMode); 19452a38012Sejakowatz set_status(error); 19552a38012Sejakowatz return error; 19652a38012Sejakowatz } 19752a38012Sejakowatz 19852a38012Sejakowatz // SetTo 19952a38012Sejakowatz /*! \brief Re-initializes the BFile to the file referred to by the 20052a38012Sejakowatz supplied path name and according to the specified open mode. 20152a38012Sejakowatz \param path the file's path name 20252a38012Sejakowatz \param openMode the mode in which the file should be opened 20352a38012Sejakowatz \return 20452a38012Sejakowatz - \c B_OK: Everything went fine. 20552a38012Sejakowatz - \c B_BAD_VALUE: \c NULL \a path or bad \a openMode. 20652a38012Sejakowatz - \c B_ENTRY_NOT_FOUND: File not found or failed to create file. 20752a38012Sejakowatz - \c B_FILE_EXISTS: File exists and \c B_FAIL_IF_EXISTS was passed. 20852a38012Sejakowatz - \c B_PERMISSION_DENIED: File permissions didn't allow operation. 20952a38012Sejakowatz - \c B_NO_MEMORY: Insufficient memory for operation. 21052a38012Sejakowatz - \c B_LINK_LIMIT: Indicates a cyclic loop within the file system. 21152a38012Sejakowatz - \c B_BUSY: A node was busy. 21252a38012Sejakowatz - \c B_FILE_ERROR: A general file error. 21352a38012Sejakowatz - \c B_NO_MORE_FDS: The application has run out of file descriptors. 21452a38012Sejakowatz */ 21552a38012Sejakowatz status_t 21652a38012Sejakowatz BFile::SetTo(const char *path, uint32 openMode) 21752a38012Sejakowatz { 21852a38012Sejakowatz Unset(); 21952a38012Sejakowatz status_t result = B_OK; 22009d84e61STyler Dauwalder BPrivate::Storage::FileDescriptor newFd = BPrivate::Storage::NullFd; 22152a38012Sejakowatz if (path) { 22252a38012Sejakowatz // analyze openMode 22352a38012Sejakowatz // Well, it's a bit schizophrenic to convert the B_* style openMode 22452a38012Sejakowatz // to POSIX style openFlags, but to use O_RWMASK to filter openMode. 225a04efc92SIngo Weinhold BPrivate::Storage::OpenFlags openFlags = 0; 22652a38012Sejakowatz switch (openMode & O_RWMASK) { 22752a38012Sejakowatz case B_READ_ONLY: 22852a38012Sejakowatz openFlags = O_RDONLY; 22952a38012Sejakowatz break; 23052a38012Sejakowatz case B_WRITE_ONLY: 23152a38012Sejakowatz openFlags = O_WRONLY; 23252a38012Sejakowatz break; 23352a38012Sejakowatz case B_READ_WRITE: 23452a38012Sejakowatz openFlags = O_RDWR; 23552a38012Sejakowatz break; 23652a38012Sejakowatz default: 23752a38012Sejakowatz result = B_BAD_VALUE; 23852a38012Sejakowatz break; 23952a38012Sejakowatz } 24052a38012Sejakowatz if (result == B_OK) { 24152a38012Sejakowatz if (openMode & B_ERASE_FILE) 24252a38012Sejakowatz openFlags |= O_TRUNC; 24352a38012Sejakowatz if (openMode & B_OPEN_AT_END) 24452a38012Sejakowatz openFlags |= O_APPEND; 24552a38012Sejakowatz if (openMode & B_CREATE_FILE) { 24652a38012Sejakowatz openFlags |= O_CREAT; 24752a38012Sejakowatz if (openMode & B_FAIL_IF_EXISTS) 24852a38012Sejakowatz openFlags |= O_EXCL; 24909d84e61STyler Dauwalder result = BPrivate::Storage::open(path, openFlags, S_IREAD | S_IWRITE, 25052a38012Sejakowatz newFd); 25152a38012Sejakowatz } else 25209d84e61STyler Dauwalder result = BPrivate::Storage::open(path, openFlags, newFd); 25352a38012Sejakowatz if (result == B_OK) 25452a38012Sejakowatz fMode = openFlags; 25552a38012Sejakowatz } 25652a38012Sejakowatz } else 25752a38012Sejakowatz result = B_BAD_VALUE; 25852a38012Sejakowatz // set the new file descriptor 25952a38012Sejakowatz if (result == B_OK) { 26052a38012Sejakowatz result = set_fd(newFd); 26152a38012Sejakowatz if (result != B_OK) 26209d84e61STyler Dauwalder BPrivate::Storage::close(newFd); 26352a38012Sejakowatz } 26452a38012Sejakowatz // finally set the BNode status 26552a38012Sejakowatz set_status(result); 26652a38012Sejakowatz return result; 26752a38012Sejakowatz } 26852a38012Sejakowatz 26952a38012Sejakowatz // SetTo 27052a38012Sejakowatz /*! \brief Re-initializes the BFile to the file referred to by the 27152a38012Sejakowatz supplied path name relative to the specified BDirectory and 27252a38012Sejakowatz according to the specified open mode. 27352a38012Sejakowatz \param dir the BDirectory, relative to which the file's path name is 27452a38012Sejakowatz given 27552a38012Sejakowatz \param path the file's path name relative to \a dir 27652a38012Sejakowatz \param openMode the mode in which the file should be opened 27752a38012Sejakowatz - \c B_OK: Everything went fine. 27852a38012Sejakowatz - \c B_BAD_VALUE: \c NULL \a dir or \a path or bad \a openMode. 27952a38012Sejakowatz - \c B_ENTRY_NOT_FOUND: File not found or failed to create file. 28052a38012Sejakowatz - \c B_FILE_EXISTS: File exists and \c B_FAIL_IF_EXISTS was passed. 28152a38012Sejakowatz - \c B_PERMISSION_DENIED: File permissions didn't allow operation. 28252a38012Sejakowatz - \c B_NO_MEMORY: Insufficient memory for operation. 28352a38012Sejakowatz - \c B_LINK_LIMIT: Indicates a cyclic loop within the file system. 28452a38012Sejakowatz - \c B_BUSY: A node was busy. 28552a38012Sejakowatz - \c B_FILE_ERROR: A general file error. 28652a38012Sejakowatz - \c B_NO_MORE_FDS: The application has run out of file descriptors. 28752a38012Sejakowatz \todo Implemented using SetTo(BEntry*, uint32). Check, if necessary 28852a38012Sejakowatz to reimplement! 28952a38012Sejakowatz */ 29052a38012Sejakowatz status_t 29152a38012Sejakowatz BFile::SetTo(const BDirectory *dir, const char *path, uint32 openMode) 29252a38012Sejakowatz { 29352a38012Sejakowatz Unset(); 29452a38012Sejakowatz status_t error = (dir && path ? B_OK : B_BAD_VALUE); 29552a38012Sejakowatz BEntry entry; 29652a38012Sejakowatz if (error == B_OK) 29752a38012Sejakowatz error = entry.SetTo(dir, path); 29852a38012Sejakowatz if (error == B_OK) 29952a38012Sejakowatz error = SetTo(&entry, openMode); 30052a38012Sejakowatz set_status(error); 30152a38012Sejakowatz return error; 30252a38012Sejakowatz } 30352a38012Sejakowatz 30452a38012Sejakowatz // IsReadable 30552a38012Sejakowatz //! Returns whether the file is readable. 30652a38012Sejakowatz /*! \return 30752a38012Sejakowatz - \c true, if the BFile has been initialized properly and the file has 30852a38012Sejakowatz been been opened for reading, 30952a38012Sejakowatz - \c false, otherwise. 31052a38012Sejakowatz */ 31152a38012Sejakowatz bool 31252a38012Sejakowatz BFile::IsReadable() const 31352a38012Sejakowatz { 31452a38012Sejakowatz return (InitCheck() == B_OK 31552a38012Sejakowatz && ((fMode & O_RWMASK) == O_RDONLY 31652a38012Sejakowatz || (fMode & O_RWMASK) == O_RDWR)); 31752a38012Sejakowatz } 31852a38012Sejakowatz 31952a38012Sejakowatz // IsWritable 32052a38012Sejakowatz //! Returns whether the file is writable. 32152a38012Sejakowatz /*! \return 32252a38012Sejakowatz - \c true, if the BFile has been initialized properly and the file has 32352a38012Sejakowatz been opened for writing, 32452a38012Sejakowatz - \c false, otherwise. 32552a38012Sejakowatz */ 32652a38012Sejakowatz bool 32752a38012Sejakowatz BFile::IsWritable() const 32852a38012Sejakowatz { 32952a38012Sejakowatz return (InitCheck() == B_OK 33052a38012Sejakowatz && ((fMode & O_RWMASK) == O_WRONLY 33152a38012Sejakowatz || (fMode & O_RWMASK) == O_RDWR)); 33252a38012Sejakowatz } 33352a38012Sejakowatz 33452a38012Sejakowatz // Read 33552a38012Sejakowatz //! Reads a number of bytes from the file into a buffer. 33652a38012Sejakowatz /*! \param buffer the buffer the data from the file shall be written to 33752a38012Sejakowatz \param size the number of bytes that shall be read 33852a38012Sejakowatz \return the number of bytes actually read or an error code 33952a38012Sejakowatz */ 34052a38012Sejakowatz ssize_t 34152a38012Sejakowatz BFile::Read(void *buffer, size_t size) 34252a38012Sejakowatz { 34352a38012Sejakowatz ssize_t result = InitCheck(); 34452a38012Sejakowatz if (result == B_OK) 34509d84e61STyler Dauwalder result = BPrivate::Storage::read(get_fd(), buffer, size); 34652a38012Sejakowatz return result; 34752a38012Sejakowatz } 34852a38012Sejakowatz 34952a38012Sejakowatz // ReadAt 35052a38012Sejakowatz /*! \brief Reads a number of bytes from a certain position within the file 35152a38012Sejakowatz into a buffer. 35252a38012Sejakowatz \param location the position (in bytes) within the file from which the 35352a38012Sejakowatz data shall be read 35452a38012Sejakowatz \param buffer the buffer the data from the file shall be written to 35552a38012Sejakowatz \param size the number of bytes that shall be read 35652a38012Sejakowatz \return the number of bytes actually read or an error code 35752a38012Sejakowatz */ 35852a38012Sejakowatz ssize_t 35952a38012Sejakowatz BFile::ReadAt(off_t location, void *buffer, size_t size) 36052a38012Sejakowatz { 36152a38012Sejakowatz ssize_t result = InitCheck(); 36252a38012Sejakowatz if (result == B_OK) 36309d84e61STyler Dauwalder result = BPrivate::Storage::read(get_fd(), buffer, location, size); 36452a38012Sejakowatz return result; 36552a38012Sejakowatz } 36652a38012Sejakowatz 36752a38012Sejakowatz // Write 36852a38012Sejakowatz //! Writes a number of bytes from a buffer into the file. 36952a38012Sejakowatz /*! \param buffer the buffer containing the data to be written to the file 37052a38012Sejakowatz \param size the number of bytes that shall be written 37152a38012Sejakowatz \return the number of bytes actually written or an error code 37252a38012Sejakowatz */ 37352a38012Sejakowatz ssize_t 37452a38012Sejakowatz BFile::Write(const void *buffer, size_t size) 37552a38012Sejakowatz { 37652a38012Sejakowatz ssize_t result = InitCheck(); 37752a38012Sejakowatz if (result == B_OK) 37809d84e61STyler Dauwalder result = BPrivate::Storage::write(get_fd(), buffer, size); 37952a38012Sejakowatz return result; 38052a38012Sejakowatz } 38152a38012Sejakowatz 38252a38012Sejakowatz // WriteAt 38352a38012Sejakowatz /*! \brief Writes a number of bytes from a buffer at a certain position 38452a38012Sejakowatz into the file. 38552a38012Sejakowatz \param location the position (in bytes) within the file at which the data 38652a38012Sejakowatz shall be written 38752a38012Sejakowatz \param buffer the buffer containing the data to be written to the file 38852a38012Sejakowatz \param size the number of bytes that shall be written 38952a38012Sejakowatz \return the number of bytes actually written or an error code 39052a38012Sejakowatz */ 39152a38012Sejakowatz ssize_t 39252a38012Sejakowatz BFile::WriteAt(off_t location, const void *buffer, size_t size) 39352a38012Sejakowatz { 39452a38012Sejakowatz ssize_t result = InitCheck(); 39552a38012Sejakowatz if (result == B_OK) 39609d84e61STyler Dauwalder result = BPrivate::Storage::write(get_fd(), buffer, location, size); 39752a38012Sejakowatz return result; 39852a38012Sejakowatz } 39952a38012Sejakowatz 40052a38012Sejakowatz // Seek 40152a38012Sejakowatz //! Seeks to another read/write position within the file. 40252a38012Sejakowatz /*! It is allowed to seek past the end of the file. A subsequent call to 40352a38012Sejakowatz Write() will pad the file with undefined data. Seeking before the 40452a38012Sejakowatz beginning of the file will fail and the behavior of subsequent Read() 40552a38012Sejakowatz or Write() invocations will be undefined. 40652a38012Sejakowatz \param offset new read/write position, depending on \a seekMode relative 40752a38012Sejakowatz to the beginning or the end of the file or the current position 40852a38012Sejakowatz \param seekMode: 40952a38012Sejakowatz - \c SEEK_SET: move relative to the beginning of the file 41052a38012Sejakowatz - \c SEEK_CUR: move relative to the current position 41152a38012Sejakowatz - \c SEEK_END: move relative to the end of the file 41252a38012Sejakowatz \return 41352a38012Sejakowatz - the new read/write position relative to the beginning of the file 41452a38012Sejakowatz - \c B_ERROR when trying to seek before the beginning of the file 41552a38012Sejakowatz - \c B_FILE_ERROR, if the file is not properly initialized 41652a38012Sejakowatz */ 41752a38012Sejakowatz off_t 41852a38012Sejakowatz BFile::Seek(off_t offset, uint32 seekMode) 41952a38012Sejakowatz { 42052a38012Sejakowatz off_t result = (InitCheck() == B_OK ? B_OK : B_FILE_ERROR); 42152a38012Sejakowatz if (result == B_OK) 42209d84e61STyler Dauwalder result = BPrivate::Storage::seek(get_fd(), offset, seekMode); 42352a38012Sejakowatz return result; 42452a38012Sejakowatz } 42552a38012Sejakowatz 42652a38012Sejakowatz // Position 42752a38012Sejakowatz //! Returns the current read/write position within the file. 42852a38012Sejakowatz /*! \return 42952a38012Sejakowatz - the current read/write position relative to the beginning of the file 43052a38012Sejakowatz - \c B_ERROR, after a Seek() before the beginning of the file 43152a38012Sejakowatz - \c B_FILE_ERROR, if the file has not been initialized 43252a38012Sejakowatz */ 43352a38012Sejakowatz off_t 43452a38012Sejakowatz BFile::Position() const 43552a38012Sejakowatz { 43652a38012Sejakowatz off_t result = (InitCheck() == B_OK ? B_OK : B_FILE_ERROR); 43752a38012Sejakowatz if (result == B_OK) 43809d84e61STyler Dauwalder result = BPrivate::Storage::get_position(get_fd()); 43952a38012Sejakowatz return result; 44052a38012Sejakowatz } 44152a38012Sejakowatz 44252a38012Sejakowatz // SetSize 44352a38012Sejakowatz //! Sets the size of the file. 44452a38012Sejakowatz /*! If the file is shorter than \a size bytes it will be padded with 44552a38012Sejakowatz unspecified data to the requested size. If it is larger, it will be 44652a38012Sejakowatz truncated. 44752a38012Sejakowatz Note: There's no problem with setting the size of a BFile opened in 44852a38012Sejakowatz \c B_READ_ONLY mode, unless the file resides on a read only volume. 44952a38012Sejakowatz \param size the new file size 45052a38012Sejakowatz \return 45152a38012Sejakowatz - \c B_OK, if everything went fine 45252a38012Sejakowatz - \c B_NOT_ALLOWED, if trying to set the size of a file on a read only 45352a38012Sejakowatz volume 45452a38012Sejakowatz - \c B_DEVICE_FULL, if there's not enough space left on the volume 45552a38012Sejakowatz */ 45652a38012Sejakowatz status_t 45752a38012Sejakowatz BFile::SetSize(off_t size) 45852a38012Sejakowatz { 45952a38012Sejakowatz status_t result = InitCheck(); 46052a38012Sejakowatz if (result == B_OK && size < 0) 46152a38012Sejakowatz result = B_BAD_VALUE; 46252a38012Sejakowatz struct stat statData; 46352a38012Sejakowatz if (result == B_OK) { 46452a38012Sejakowatz statData.st_size = size; 46552a38012Sejakowatz result = set_stat(statData, WSTAT_SIZE); 46652a38012Sejakowatz } 46752a38012Sejakowatz return result; 46852a38012Sejakowatz } 46952a38012Sejakowatz 47052a38012Sejakowatz // = 47152a38012Sejakowatz //! Assigns another BFile to this BFile. 47252a38012Sejakowatz /*! If the other BFile is uninitialized, this one will be too. Otherwise it 47352a38012Sejakowatz will refer to the same file using the same mode, unless an error occurs. 47452a38012Sejakowatz \param file the original BFile 47552a38012Sejakowatz \return a reference to this BFile 47652a38012Sejakowatz */ 47752a38012Sejakowatz BFile & 47852a38012Sejakowatz BFile::operator=(const BFile &file) 47952a38012Sejakowatz { 48052a38012Sejakowatz if (&file != this) { // no need to assign us to ourselves 48152a38012Sejakowatz Unset(); 48252a38012Sejakowatz if (file.InitCheck() == B_OK) { 48352a38012Sejakowatz // duplicate the file descriptor 48409d84e61STyler Dauwalder BPrivate::Storage::FileDescriptor fd = -1; 48509d84e61STyler Dauwalder status_t status = BPrivate::Storage::dup(file.get_fd(), fd); 48652a38012Sejakowatz // set it 48752a38012Sejakowatz if (status == B_OK) { 48852a38012Sejakowatz status = set_fd(fd); 48952a38012Sejakowatz if (status == B_OK) 49052a38012Sejakowatz fMode = file.fMode; 49152a38012Sejakowatz else 49209d84e61STyler Dauwalder BPrivate::Storage::close(fd); 49352a38012Sejakowatz } 49452a38012Sejakowatz set_status(status); 49552a38012Sejakowatz } 49652a38012Sejakowatz } 49752a38012Sejakowatz return *this; 49852a38012Sejakowatz } 49952a38012Sejakowatz 50052a38012Sejakowatz 50152a38012Sejakowatz // FBC 502*7c44680aSIngo Weinhold void BFile::_PhiloFile1() {} 503*7c44680aSIngo Weinhold void BFile::_PhiloFile2() {} 504*7c44680aSIngo Weinhold void BFile::_PhiloFile3() {} 505*7c44680aSIngo Weinhold void BFile::_PhiloFile4() {} 506*7c44680aSIngo Weinhold void BFile::_PhiloFile5() {} 507*7c44680aSIngo Weinhold void BFile::_PhiloFile6() {} 50852a38012Sejakowatz 50952a38012Sejakowatz 51052a38012Sejakowatz // get_fd 51152a38012Sejakowatz /*! Returns the file descriptor. 51252a38012Sejakowatz To be used instead of accessing the BNode's private \c fFd member directly. 51352a38012Sejakowatz \return the file descriptor, or -1, if not properly initialized. 51452a38012Sejakowatz */ 51509d84e61STyler Dauwalder BPrivate::Storage::FileDescriptor 51652a38012Sejakowatz BFile::get_fd() const 51752a38012Sejakowatz { 51852a38012Sejakowatz return fFd; 51952a38012Sejakowatz } 52052a38012Sejakowatz 52152a38012Sejakowatz 52252a38012Sejakowatz #ifdef USE_OPENBEOS_NAMESPACE 52352a38012Sejakowatz }; // namespace OpenBeOS 52452a38012Sejakowatz #endif 52552a38012Sejakowatz 52609d84e61STyler Dauwalder 52709d84e61STyler Dauwalder 52809d84e61STyler Dauwalder 529