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