xref: /aosp_15_r20/external/libbrillo/brillo/streams/file_stream.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
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