1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved. 2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be 3*1a96fba6SXin Li // found in the LICENSE file. 4*1a96fba6SXin Li 5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_STREAMS_FILE_STREAM_H_ 6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_STREAMS_FILE_STREAM_H_ 7*1a96fba6SXin Li 8*1a96fba6SXin Li #include <sys/types.h> 9*1a96fba6SXin Li 10*1a96fba6SXin Li #include <memory> 11*1a96fba6SXin Li 12*1a96fba6SXin Li #include <base/files/file_path.h> 13*1a96fba6SXin Li #include <base/macros.h> 14*1a96fba6SXin Li #include <brillo/brillo_export.h> 15*1a96fba6SXin Li #include <brillo/streams/stream.h> 16*1a96fba6SXin Li 17*1a96fba6SXin Li namespace brillo { 18*1a96fba6SXin Li 19*1a96fba6SXin Li // FileStream class provides the implementation of brillo::Stream for files 20*1a96fba6SXin Li // and file-descriptor-based streams, such as pipes and sockets. 21*1a96fba6SXin Li // The FileStream class cannot be instantiated by clients directly. However 22*1a96fba6SXin Li // they should use the static factory methods such as: 23*1a96fba6SXin Li // - FileStream::Open(): to open a file by name. 24*1a96fba6SXin Li // - FileStream::CreateTemporary(): to create a temporary file stream. 25*1a96fba6SXin Li // - FileStream::FromFileDescriptor(): to create a stream using an existing 26*1a96fba6SXin Li // file descriptor. 27*1a96fba6SXin Li class BRILLO_EXPORT FileStream : public Stream { 28*1a96fba6SXin Li public: 29*1a96fba6SXin Li // See comments for FileStream::Open() for detailed description of this enum. 30*1a96fba6SXin Li enum class Disposition { 31*1a96fba6SXin Li OPEN_EXISTING, // Open existing file only. Fail if doesn't exist. 32*1a96fba6SXin Li CREATE_ALWAYS, // Create empty file, possibly overwriting existing file. 33*1a96fba6SXin Li CREATE_NEW_ONLY, // Create new file if doesn't exist already. 34*1a96fba6SXin Li TRUNCATE_EXISTING, // Open/truncate existing file. Fail if doesn't exist. 35*1a96fba6SXin Li }; 36*1a96fba6SXin Li 37*1a96fba6SXin Li // Simple interface to wrap native library calls so that they can be mocked 38*1a96fba6SXin Li // out for testing. 39*1a96fba6SXin Li struct FileDescriptorInterface { 40*1a96fba6SXin Li using DataCallback = base::Callback<void(Stream::AccessMode)>; 41*1a96fba6SXin Li 42*1a96fba6SXin Li virtual ~FileDescriptorInterface() = default; 43*1a96fba6SXin Li 44*1a96fba6SXin Li virtual bool IsOpen() const = 0; 45*1a96fba6SXin Li virtual ssize_t Read(void* buf, size_t nbyte) = 0; 46*1a96fba6SXin Li virtual ssize_t Write(const void* buf, size_t nbyte) = 0; 47*1a96fba6SXin Li virtual off64_t Seek(off64_t offset, int whence) = 0; 48*1a96fba6SXin Li virtual mode_t GetFileMode() const = 0; 49*1a96fba6SXin Li virtual uint64_t GetSize() const = 0; 50*1a96fba6SXin Li virtual int Truncate(off64_t length) const = 0; 51*1a96fba6SXin Li virtual int Close() = 0; 52*1a96fba6SXin Li virtual bool WaitForData(AccessMode mode, 53*1a96fba6SXin Li const DataCallback& data_callback, 54*1a96fba6SXin Li ErrorPtr* error) = 0; 55*1a96fba6SXin Li virtual int WaitForDataBlocking(AccessMode in_mode, 56*1a96fba6SXin Li base::TimeDelta timeout, 57*1a96fba6SXin Li AccessMode* out_mode) = 0; 58*1a96fba6SXin Li virtual void CancelPendingAsyncOperations() = 0; 59*1a96fba6SXin Li }; 60*1a96fba6SXin Li 61*1a96fba6SXin Li // == Construction ========================================================== 62*1a96fba6SXin Li 63*1a96fba6SXin Li // Opens a file at specified |path| for reading, writing or both as indicated 64*1a96fba6SXin Li // by |mode|. The |disposition| specifies how the file must be opened/created: 65*1a96fba6SXin Li // - OPEN_EXISTING - opens the existing file and keeps its content intact. 66*1a96fba6SXin Li // The seek pointer is at the beginning of the file. 67*1a96fba6SXin Li // - CREATE_ALWAYS - creates the file always. If it exists, the file is 68*1a96fba6SXin Li // truncated. 69*1a96fba6SXin Li // - CREATE_NEW_ONLY - creates a new file only if it doesn't exist. Fails 70*1a96fba6SXin Li // otherwise. This can be useful for creating lock files. 71*1a96fba6SXin Li // - TRUNCATE_EXISTING - opens existing file and truncates it to zero length. 72*1a96fba6SXin Li // Fails if the file doesn't already exist. 73*1a96fba6SXin Li // If successful, the open file stream is returned. Otherwise returns the 74*1a96fba6SXin Li // stream pointer containing nullptr and fills in the details of the error 75*1a96fba6SXin Li // in |error| object, if provided. 76*1a96fba6SXin Li static StreamPtr Open(const base::FilePath& path, 77*1a96fba6SXin Li AccessMode mode, 78*1a96fba6SXin Li Disposition disposition, 79*1a96fba6SXin Li ErrorPtr* error); 80*1a96fba6SXin Li 81*1a96fba6SXin Li // Creates a temporary unnamed file and returns a stream to it. The file will 82*1a96fba6SXin Li // be deleted when the stream is destroyed. 83*1a96fba6SXin Li static StreamPtr CreateTemporary(ErrorPtr* error); 84*1a96fba6SXin Li 85*1a96fba6SXin Li // Creates a file stream based on existing file descriptor. The file 86*1a96fba6SXin Li // descriptor will be set into non-blocking mode and will be owned by the 87*1a96fba6SXin Li // resulting stream (and closed when the stream is destroyed). 88*1a96fba6SXin Li // If the function fails, returns a null stream pointer and sets the error 89*1a96fba6SXin Li // details to |error| object. Also note that it is the caller's responsibility 90*1a96fba6SXin Li // to close the file descriptor if this function fails, since the stream 91*1a96fba6SXin Li // hasn't been created yet and didn't take ownership of the file descriptor. 92*1a96fba6SXin Li // |own_descriptor| indicates whether the stream must close the underlying 93*1a96fba6SXin Li // file descriptor when its CloseBlocking() method is called. This should be 94*1a96fba6SXin Li // set to false for file descriptors that shouldn't be closed (e.g. stdin). 95*1a96fba6SXin Li static StreamPtr FromFileDescriptor(int file_descriptor, 96*1a96fba6SXin Li bool own_descriptor, 97*1a96fba6SXin Li ErrorPtr* error); 98*1a96fba6SXin Li 99*1a96fba6SXin Li // == Stream capabilities =================================================== 100*1a96fba6SXin Li bool IsOpen() const override; 101*1a96fba6SXin Li bool CanRead() const override; 102*1a96fba6SXin Li bool CanWrite() const override; 103*1a96fba6SXin Li bool CanSeek() const override; 104*1a96fba6SXin Li bool CanGetSize() const override; 105*1a96fba6SXin Li 106*1a96fba6SXin Li // == Stream size operations ================================================ 107*1a96fba6SXin Li uint64_t GetSize() const override; 108*1a96fba6SXin Li bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override; 109*1a96fba6SXin Li uint64_t GetRemainingSize() const override; 110*1a96fba6SXin Li 111*1a96fba6SXin Li // == Seek operations ======================================================= 112*1a96fba6SXin Li uint64_t GetPosition() const override; 113*1a96fba6SXin Li bool Seek(int64_t offset, 114*1a96fba6SXin Li Whence whence, 115*1a96fba6SXin Li uint64_t* new_position, 116*1a96fba6SXin Li ErrorPtr* error) override; 117*1a96fba6SXin Li 118*1a96fba6SXin Li // == Read operations ======================================================= 119*1a96fba6SXin Li bool ReadNonBlocking(void* buffer, 120*1a96fba6SXin Li size_t size_to_read, 121*1a96fba6SXin Li size_t* size_read, 122*1a96fba6SXin Li bool* end_of_stream, 123*1a96fba6SXin Li ErrorPtr* error) override; 124*1a96fba6SXin Li 125*1a96fba6SXin Li // == Write operations ====================================================== 126*1a96fba6SXin Li bool WriteNonBlocking(const void* buffer, 127*1a96fba6SXin Li size_t size_to_write, 128*1a96fba6SXin Li size_t* size_written, 129*1a96fba6SXin Li ErrorPtr* error) override; 130*1a96fba6SXin Li 131*1a96fba6SXin Li // == Finalizing/closing streams =========================================== 132*1a96fba6SXin Li bool FlushBlocking(ErrorPtr* error) override; 133*1a96fba6SXin Li bool CloseBlocking(ErrorPtr* error) override; 134*1a96fba6SXin Li 135*1a96fba6SXin Li // == Data availability monitoring ========================================== 136*1a96fba6SXin Li 137*1a96fba6SXin Li // Override for Stream::WaitForData to start watching the associated file 138*1a96fba6SXin Li // descriptor for non-blocking read/write operations. 139*1a96fba6SXin Li bool WaitForData(AccessMode mode, 140*1a96fba6SXin Li const base::Callback<void(AccessMode)>& callback, 141*1a96fba6SXin Li ErrorPtr* error) override; 142*1a96fba6SXin Li 143*1a96fba6SXin Li // Runs select() on the file descriptor to wait until we can do non-blocking 144*1a96fba6SXin Li // I/O on it. 145*1a96fba6SXin Li bool WaitForDataBlocking(AccessMode in_mode, 146*1a96fba6SXin Li base::TimeDelta timeout, 147*1a96fba6SXin Li AccessMode* out_mode, 148*1a96fba6SXin Li ErrorPtr* error) override; 149*1a96fba6SXin Li 150*1a96fba6SXin Li // Cancels pending asynchronous read/write operations. 151*1a96fba6SXin Li void CancelPendingAsyncOperations() override; 152*1a96fba6SXin Li 153*1a96fba6SXin Li private: 154*1a96fba6SXin Li friend class FileStreamTest; 155*1a96fba6SXin Li 156*1a96fba6SXin Li // Internal constructor used by the factory methods Open(), CreateTemporary(), 157*1a96fba6SXin Li // and FromFileDescriptor(). 158*1a96fba6SXin Li FileStream(std::unique_ptr<FileDescriptorInterface> fd_interface, 159*1a96fba6SXin Li AccessMode mode); 160*1a96fba6SXin Li 161*1a96fba6SXin Li // Wrapper for the file descriptor. Used in testing to mock out the real 162*1a96fba6SXin Li // file system APIs. 163*1a96fba6SXin Li std::unique_ptr<FileDescriptorInterface> fd_interface_; 164*1a96fba6SXin Li 165*1a96fba6SXin Li // The access mode this stream is open with. 166*1a96fba6SXin Li AccessMode access_mode_{AccessMode::READ_WRITE}; 167*1a96fba6SXin Li 168*1a96fba6SXin Li // Set to false for streams that are guaranteed non-seekable. 169*1a96fba6SXin Li bool seekable_{true}; 170*1a96fba6SXin Li 171*1a96fba6SXin Li // Set to false for streams that have unknown size. 172*1a96fba6SXin Li bool can_get_size_{false}; 173*1a96fba6SXin Li 174*1a96fba6SXin Li DISALLOW_COPY_AND_ASSIGN(FileStream); 175*1a96fba6SXin Li }; 176*1a96fba6SXin Li 177*1a96fba6SXin Li } // namespace brillo 178*1a96fba6SXin Li 179*1a96fba6SXin Li #endif // LIBBRILLO_BRILLO_STREAMS_FILE_STREAM_H_ 180