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