1 //===-- File.h --------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef liblldb_File_h_
10 #define liblldb_File_h_
11 
12 #include "lldb/Host/PosixApi.h"
13 #include "lldb/Utility/IOObject.h"
14 #include "lldb/Utility/Status.h"
15 #include "lldb/lldb-private.h"
16 
17 #include <mutex>
18 #include <stdarg.h>
19 #include <stdio.h>
20 #include <sys/types.h>
21 
22 namespace lldb_private {
23 
24 /// \class File File.h "lldb/Host/File.h"
25 /// A file class.
26 ///
27 /// A file class that divides abstracts the LLDB core from host file
28 /// functionality.
29 class File : public IOObject {
30 public:
31   static int kInvalidDescriptor;
32   static FILE *kInvalidStream;
33 
34   // NB this enum is used in the lldb platform gdb-remote packet
35   // vFile:open: and existing values cannot be modified.
36   enum OpenOptions {
37     eOpenOptionRead = (1u << 0),  // Open file for reading
38     eOpenOptionWrite = (1u << 1), // Open file for writing
39     eOpenOptionAppend =
40         (1u << 2), // Don't truncate file when opening, append to end of file
41     eOpenOptionTruncate = (1u << 3),    // Truncate file when opening
42     eOpenOptionNonBlocking = (1u << 4), // File reads
43     eOpenOptionCanCreate = (1u << 5),   // Create file if doesn't already exist
44     eOpenOptionCanCreateNewOnly =
45         (1u << 6), // Can create file only if it doesn't already exist
46     eOpenOptionDontFollowSymlinks = (1u << 7),
47     eOpenOptionCloseOnExec =
48         (1u << 8) // Close the file when executing a new process
49   };
50 
51   static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options);
52 
53   File()
54       : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
55         m_stream(kInvalidStream), m_options(0), m_own_stream(false),
56         m_is_interactive(eLazyBoolCalculate),
57         m_is_real_terminal(eLazyBoolCalculate),
58         m_supports_colors(eLazyBoolCalculate) {}
59 
60   File(FILE *fh, bool transfer_ownership)
61       : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
62         m_stream(fh), m_options(0), m_own_stream(transfer_ownership),
63         m_is_interactive(eLazyBoolCalculate),
64         m_is_real_terminal(eLazyBoolCalculate),
65         m_supports_colors(eLazyBoolCalculate) {}
66 
67   File(int fd, bool transfer_ownership)
68       : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd),
69         m_stream(kInvalidStream), m_options(0), m_own_stream(false),
70         m_is_interactive(eLazyBoolCalculate),
71         m_is_real_terminal(eLazyBoolCalculate) {}
72 
73   /// Destructor.
74   ///
75   /// The destructor is virtual in case this class is subclassed.
76   ~File() override;
77 
78   bool IsValid() const override {
79     return DescriptorIsValid() || StreamIsValid();
80   }
81 
82   /// Convert to pointer operator.
83   ///
84   /// This allows code to check a File object to see if it contains anything
85   /// valid using code such as:
86   ///
87   /// \code
88   /// File file(...);
89   /// if (file)
90   /// { ...
91   /// \endcode
92   ///
93   /// \return
94   ///     A pointer to this object if either the directory or filename
95   ///     is valid, nullptr otherwise.
96   operator bool() const { return DescriptorIsValid() || StreamIsValid(); }
97 
98   /// Logical NOT operator.
99   ///
100   /// This allows code to check a File object to see if it is invalid using
101   /// code such as:
102   ///
103   /// \code
104   /// File file(...);
105   /// if (!file)
106   /// { ...
107   /// \endcode
108   ///
109   /// \return
110   ///     Returns \b true if the object has an empty directory and
111   ///     filename, \b false otherwise.
112   bool operator!() const { return !DescriptorIsValid() && !StreamIsValid(); }
113 
114   /// Get the file spec for this file.
115   ///
116   /// \return
117   ///     A reference to the file specification object.
118   Status GetFileSpec(FileSpec &file_spec) const;
119 
120   Status Close() override;
121 
122   void Clear();
123 
124   int GetDescriptor() const;
125 
126   WaitableHandle GetWaitableHandle() override;
127 
128   void SetDescriptor(int fd, bool transfer_ownership);
129 
130   FILE *GetStream();
131 
132   void SetStream(FILE *fh, bool transfer_ownership);
133 
134   /// Read bytes from a file from the current file position.
135   ///
136   /// NOTE: This function is NOT thread safe. Use the read function
137   /// that takes an "off_t &offset" to ensure correct operation in multi-
138   /// threaded environments.
139   ///
140   /// \param[in] buf
141   ///     A buffer where to put the bytes that are read.
142   ///
143   /// \param[in,out] num_bytes
144   ///     The number of bytes to read form the current file position
145   ///     which gets modified with the number of bytes that were read.
146   ///
147   /// \return
148   ///     An error object that indicates success or the reason for
149   ///     failure.
150   Status Read(void *buf, size_t &num_bytes) override;
151 
152   /// Write bytes to a file at the current file position.
153   ///
154   /// NOTE: This function is NOT thread safe. Use the write function
155   /// that takes an "off_t &offset" to ensure correct operation in multi-
156   /// threaded environments.
157   ///
158   /// \param[in] buf
159   ///     A buffer where to put the bytes that are read.
160   ///
161   /// \param[in,out] num_bytes
162   ///     The number of bytes to write to the current file position
163   ///     which gets modified with the number of bytes that were
164   ///     written.
165   ///
166   /// \return
167   ///     An error object that indicates success or the reason for
168   ///     failure.
169   Status Write(const void *buf, size_t &num_bytes) override;
170 
171   /// Seek to an offset relative to the beginning of the file.
172   ///
173   /// NOTE: This function is NOT thread safe, other threads that
174   /// access this object might also change the current file position. For
175   /// thread safe reads and writes see the following functions: @see
176   /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
177   /// size_t, off_t &)
178   ///
179   /// \param[in] offset
180   ///     The offset to seek to within the file relative to the
181   ///     beginning of the file.
182   ///
183   /// \param[in] error_ptr
184   ///     A pointer to a lldb_private::Status object that will be
185   ///     filled in if non-nullptr.
186   ///
187   /// \return
188   ///     The resulting seek offset, or -1 on error.
189   off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr);
190 
191   /// Seek to an offset relative to the current file position.
192   ///
193   /// NOTE: This function is NOT thread safe, other threads that
194   /// access this object might also change the current file position. For
195   /// thread safe reads and writes see the following functions: @see
196   /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
197   /// size_t, off_t &)
198   ///
199   /// \param[in] offset
200   ///     The offset to seek to within the file relative to the
201   ///     current file position.
202   ///
203   /// \param[in] error_ptr
204   ///     A pointer to a lldb_private::Status object that will be
205   ///     filled in if non-nullptr.
206   ///
207   /// \return
208   ///     The resulting seek offset, or -1 on error.
209   off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr);
210 
211   /// Seek to an offset relative to the end of the file.
212   ///
213   /// NOTE: This function is NOT thread safe, other threads that
214   /// access this object might also change the current file position. For
215   /// thread safe reads and writes see the following functions: @see
216   /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
217   /// size_t, off_t &)
218   ///
219   /// \param[in,out] offset
220   ///     The offset to seek to within the file relative to the
221   ///     end of the file which gets filled in with the resulting
222   ///     absolute file offset.
223   ///
224   /// \param[in] error_ptr
225   ///     A pointer to a lldb_private::Status object that will be
226   ///     filled in if non-nullptr.
227   ///
228   /// \return
229   ///     The resulting seek offset, or -1 on error.
230   off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr);
231 
232   /// Read bytes from a file from the specified file offset.
233   ///
234   /// NOTE: This function is thread safe in that clients manager their
235   /// own file position markers and reads on other threads won't mess up the
236   /// current read.
237   ///
238   /// \param[in] dst
239   ///     A buffer where to put the bytes that are read.
240   ///
241   /// \param[in,out] num_bytes
242   ///     The number of bytes to read form the current file position
243   ///     which gets modified with the number of bytes that were read.
244   ///
245   /// \param[in,out] offset
246   ///     The offset within the file from which to read \a num_bytes
247   ///     bytes. This offset gets incremented by the number of bytes
248   ///     that were read.
249   ///
250   /// \return
251   ///     An error object that indicates success or the reason for
252   ///     failure.
253   Status Read(void *dst, size_t &num_bytes, off_t &offset);
254 
255   /// Read bytes from a file from the specified file offset.
256   ///
257   /// NOTE: This function is thread safe in that clients manager their
258   /// own file position markers and reads on other threads won't mess up the
259   /// current read.
260   ///
261   /// \param[in,out] num_bytes
262   ///     The number of bytes to read form the current file position
263   ///     which gets modified with the number of bytes that were read.
264   ///
265   /// \param[in,out] offset
266   ///     The offset within the file from which to read \a num_bytes
267   ///     bytes. This offset gets incremented by the number of bytes
268   ///     that were read.
269   ///
270   /// \param[in] null_terminate
271   ///     Ensure that the data that is read is terminated with a NULL
272   ///     character so that the data can be used as a C string.
273   ///
274   /// \param[out] data_buffer_sp
275   ///     A data buffer to create and fill in that will contain any
276   ///     data that is read from the file. This buffer will be reset
277   ///     if an error occurs.
278   ///
279   /// \return
280   ///     An error object that indicates success or the reason for
281   ///     failure.
282   Status Read(size_t &num_bytes, off_t &offset, bool null_terminate,
283               lldb::DataBufferSP &data_buffer_sp);
284 
285   /// Write bytes to a file at the specified file offset.
286   ///
287   /// NOTE: This function is thread safe in that clients manager their
288   /// own file position markers, though clients will need to implement their
289   /// own locking externally to avoid multiple people writing to the file at
290   /// the same time.
291   ///
292   /// \param[in] src
293   ///     A buffer containing the bytes to write.
294   ///
295   /// \param[in,out] num_bytes
296   ///     The number of bytes to write to the file at offset \a offset.
297   ///     \a num_bytes gets modified with the number of bytes that
298   ///     were read.
299   ///
300   /// \param[in,out] offset
301   ///     The offset within the file at which to write \a num_bytes
302   ///     bytes. This offset gets incremented by the number of bytes
303   ///     that were written.
304   ///
305   /// \return
306   ///     An error object that indicates success or the reason for
307   ///     failure.
308   Status Write(const void *src, size_t &num_bytes, off_t &offset);
309 
310   /// Flush the current stream
311   ///
312   /// \return
313   ///     An error object that indicates success or the reason for
314   ///     failure.
315   Status Flush();
316 
317   /// Sync to disk.
318   ///
319   /// \return
320   ///     An error object that indicates success or the reason for
321   ///     failure.
322   Status Sync();
323 
324   /// Get the permissions for a this file.
325   ///
326   /// \return
327   ///     Bits logical OR'ed together from the permission bits defined
328   ///     in lldb_private::File::Permissions.
329   uint32_t GetPermissions(Status &error) const;
330 
331   /// Return true if this file is interactive.
332   ///
333   /// \return
334   ///     True if this file is a terminal (tty or pty), false
335   ///     otherwise.
336   bool GetIsInteractive();
337 
338   /// Return true if this file from a real terminal.
339   ///
340   /// Just knowing a file is a interactive isn't enough, we also need to know
341   /// if the terminal has a width and height so we can do cursor movement and
342   /// other terminal manipulations by sending escape sequences.
343   ///
344   /// \return
345   ///     True if this file is a terminal (tty, not a pty) that has
346   ///     a non-zero width and height, false otherwise.
347   bool GetIsRealTerminal();
348 
349   bool GetIsTerminalWithColors();
350 
351   /// Output printf formatted output to the stream.
352   ///
353   /// Print some formatted output to the stream.
354   ///
355   /// \param[in] format
356   ///     A printf style format string.
357   ///
358   /// \param[in] ...
359   ///     Variable arguments that are needed for the printf style
360   ///     format string \a format.
361   size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
362 
363   size_t PrintfVarArg(const char *format, va_list args);
364 
365   void SetOptions(uint32_t options) { m_options = options; }
366 
367   static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
368 
369 protected:
370   bool DescriptorIsValid() const { return DescriptorIsValid(m_descriptor); }
371 
372   bool StreamIsValid() const { return m_stream != kInvalidStream; }
373 
374   void CalculateInteractiveAndTerminal();
375 
376   // Member variables
377   int m_descriptor;
378   FILE *m_stream;
379   uint32_t m_options;
380   bool m_own_stream;
381   LazyBool m_is_interactive;
382   LazyBool m_is_real_terminal;
383   LazyBool m_supports_colors;
384   std::mutex offset_access_mutex;
385 
386 private:
387   DISALLOW_COPY_AND_ASSIGN(File);
388 };
389 
390 } // namespace lldb_private
391 
392 #endif // liblldb_File_h_
393