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 LLDB_HOST_FILE_H
10 #define LLDB_HOST_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 #include "llvm/ADT/BitmaskEnum.h"
17 
18 #include <cstdarg>
19 #include <cstdio>
20 #include <mutex>
21 #include <sys/types.h>
22 
23 namespace lldb_private {
24 
25 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
26 
27 /// \class File File.h "lldb/Host/File.h"
28 /// An abstract base class for files.
29 ///
30 /// Files will often be NativeFiles, which provides a wrapper
31 /// around host OS file functionality.   But it
32 /// is also possible to subclass file to provide objects that have file
33 /// or stream functionality but are not backed by any host OS file.
34 class File : public IOObject {
35 public:
36   static int kInvalidDescriptor;
37   static FILE *kInvalidStream;
38 
39   // NB this enum is used in the lldb platform gdb-remote packet
40   // vFile:open: and existing values cannot be modified.
41   //
42   // FIXME
43   // These values do not match the values used by GDB
44   // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
45   // * rdar://problem/46788934
46   enum OpenOptions : uint32_t {
47     eOpenOptionRead = (1u << 0),  // Open file for reading
48     eOpenOptionWrite = (1u << 1), // Open file for writing
49     eOpenOptionAppend =
50         (1u << 2), // Don't truncate file when opening, append to end of file
51     eOpenOptionTruncate = (1u << 3),    // Truncate file when opening
52     eOpenOptionNonBlocking = (1u << 4), // File reads
53     eOpenOptionCanCreate = (1u << 5),   // Create file if doesn't already exist
54     eOpenOptionCanCreateNewOnly =
55         (1u << 6), // Can create file only if it doesn't already exist
56     eOpenOptionDontFollowSymlinks = (1u << 7),
57     eOpenOptionCloseOnExec =
58         (1u << 8), // Close the file when executing a new process
59     LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec)
60   };
61 
62   static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options);
63   static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode);
64   static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
65   static llvm::Expected<const char *>
66   GetStreamOpenModeFromOptions(OpenOptions options);
67 
68   File() : IOObject(eFDTypeFile){};
69 
70   /// Read bytes from a file from the current file position into buf.
71   ///
72   /// NOTE: This function is NOT thread safe. Use the read function
73   /// that takes an "off_t &offset" to ensure correct operation in multi-
74   /// threaded environments.
75   ///
76   /// \param[in,out] num_bytes
77   ///    Pass in the size of buf.  Read will pass out the number
78   ///    of bytes read.   Zero bytes read with no error indicates
79   ///    EOF.
80   ///
81   /// \return
82   ///    success, ENOTSUP, or another error.
83   Status Read(void *buf, size_t &num_bytes) override;
84 
85   /// Write bytes from buf to a file at the current file position.
86   ///
87   /// NOTE: This function is NOT thread safe. Use the write function
88   /// that takes an "off_t &offset" to ensure correct operation in multi-
89   /// threaded environments.
90   ///
91   /// \param[in,out] num_bytes
92   ///    Pass in the size of buf.  Write will pass out the number
93   ///    of bytes written.   Write will attempt write the full number
94   ///    of bytes and will not return early except on error.
95   ///
96   /// \return
97   ///    success, ENOTSUP, or another error.
98   Status Write(const void *buf, size_t &num_bytes) override;
99 
100   /// IsValid
101   ///
102   /// \return
103   ///    true iff the file is valid.
104   bool IsValid() const override;
105 
106   /// Flush any buffers and release any resources owned by the file.
107   /// After Close() the file will be invalid.
108   ///
109   /// \return
110   ///     success or an error.
111   Status Close() override;
112 
113   /// Get a handle that can be used for OS polling interfaces, such
114   /// as WaitForMultipleObjects, select, or epoll.   This may return
115   /// IOObject::kInvalidHandleValue if none is available.   This will
116   /// generally be the same as the file descriptor, this function
117   /// is not interchangeable with GetDescriptor().   A WaitableHandle
118   /// must only be used for polling, not actual I/O.
119   ///
120   /// \return
121   ///     a valid handle or IOObject::kInvalidHandleValue
122   WaitableHandle GetWaitableHandle() override;
123 
124   /// Get the file specification for this file, if possible.
125   ///
126   /// \param[out] file_spec
127   ///     the file specification.
128   /// \return
129   ///     ENOTSUP, success, or another error.
130   virtual Status GetFileSpec(FileSpec &file_spec) const;
131 
132   /// Get underlying OS file descriptor for this file, or kInvalidDescriptor.
133   /// If the descriptor is valid, then it may be used directly for I/O
134   /// However, the File may also perform it's own buffering, so avoid using
135   /// this if it is not necessary, or use Flush() appropriately.
136   ///
137   /// \return
138   ///    a valid file descriptor for this file or kInvalidDescriptor
139   virtual int GetDescriptor() const;
140 
141   /// Get the underlying libc stream for this file, or NULL.
142   ///
143   /// Not all valid files will have a FILE* stream.   This should only be
144   /// used if absolutely necessary, such as to interact with 3rd party
145   /// libraries that need FILE* streams.
146   ///
147   /// \return
148   ///    a valid stream or NULL;
149   virtual FILE *GetStream();
150 
151   /// Seek to an offset relative to the beginning of the file.
152   ///
153   /// NOTE: This function is NOT thread safe, other threads that
154   /// access this object might also change the current file position. For
155   /// thread safe reads and writes see the following functions: @see
156   /// File::Read (void *, size_t, off_t &) \see File::Write (const void *,
157   /// size_t, off_t &)
158   ///
159   /// \param[in] offset
160   ///     The offset to seek to within the file relative to the
161   ///     beginning of the file.
162   ///
163   /// \param[in] error_ptr
164   ///     A pointer to a lldb_private::Status object that will be
165   ///     filled in if non-nullptr.
166   ///
167   /// \return
168   ///     The resulting seek offset, or -1 on error.
169   virtual off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr);
170 
171   /// Seek to an offset relative to the current file position.
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   ///     current file position.
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   virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr);
190 
191   /// Seek to an offset relative to the end of the file.
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,out] offset
200   ///     The offset to seek to within the file relative to the
201   ///     end of the file which gets filled in with the resulting
202   ///     absolute file offset.
203   ///
204   /// \param[in] error_ptr
205   ///     A pointer to a lldb_private::Status object that will be
206   ///     filled in if non-nullptr.
207   ///
208   /// \return
209   ///     The resulting seek offset, or -1 on error.
210   virtual off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr);
211 
212   /// Read bytes from a file from the specified file offset.
213   ///
214   /// NOTE: This function is thread safe in that clients manager their
215   /// own file position markers and reads on other threads won't mess up the
216   /// current read.
217   ///
218   /// \param[in] dst
219   ///     A buffer where to put the bytes that are read.
220   ///
221   /// \param[in,out] num_bytes
222   ///     The number of bytes to read form the current file position
223   ///     which gets modified with the number of bytes that were read.
224   ///
225   /// \param[in,out] offset
226   ///     The offset within the file from which to read \a num_bytes
227   ///     bytes. This offset gets incremented by the number of bytes
228   ///     that were read.
229   ///
230   /// \return
231   ///     An error object that indicates success or the reason for
232   ///     failure.
233   virtual Status Read(void *dst, size_t &num_bytes, off_t &offset);
234 
235   /// Write bytes to a file at the specified file offset.
236   ///
237   /// NOTE: This function is thread safe in that clients manager their
238   /// own file position markers, though clients will need to implement their
239   /// own locking externally to avoid multiple people writing to the file at
240   /// the same time.
241   ///
242   /// \param[in] src
243   ///     A buffer containing the bytes to write.
244   ///
245   /// \param[in,out] num_bytes
246   ///     The number of bytes to write to the file at offset \a offset.
247   ///     \a num_bytes gets modified with the number of bytes that
248   ///     were read.
249   ///
250   /// \param[in,out] offset
251   ///     The offset within the file at which to write \a num_bytes
252   ///     bytes. This offset gets incremented by the number of bytes
253   ///     that were written.
254   ///
255   /// \return
256   ///     An error object that indicates success or the reason for
257   ///     failure.
258   virtual Status Write(const void *src, size_t &num_bytes, off_t &offset);
259 
260   /// Flush the current stream
261   ///
262   /// \return
263   ///     An error object that indicates success or the reason for
264   ///     failure.
265   virtual Status Flush();
266 
267   /// Sync to disk.
268   ///
269   /// \return
270   ///     An error object that indicates success or the reason for
271   ///     failure.
272   virtual Status Sync();
273 
274   /// Output printf formatted output to the stream.
275   ///
276   /// NOTE: this is not virtual, because it just calls the va_list
277   /// version of the function.
278   ///
279   /// Print some formatted output to the stream.
280   ///
281   /// \param[in] format
282   ///     A printf style format string.
283   ///
284   /// \param[in] ...
285   ///     Variable arguments that are needed for the printf style
286   ///     format string \a format.
287   size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
288 
289   /// Output printf formatted output to the stream.
290   ///
291   /// Print some formatted output to the stream.
292   ///
293   /// \param[in] format
294   ///     A printf style format string.
295   ///
296   /// \param[in] args
297   ///     Variable arguments that are needed for the printf style
298   ///     format string \a format.
299   virtual size_t PrintfVarArg(const char *format, va_list args);
300 
301   /// Return the OpenOptions for this file.
302   ///
303   /// Some options like eOpenOptionDontFollowSymlinks only make
304   /// sense when a file is being opened (or not at all)
305   /// and may not be preserved for this method.  But any valid
306   /// File should return either or both of eOpenOptionRead and
307   /// eOpenOptionWrite here.
308   ///
309   /// \return
310   ///    OpenOptions flags for this file, or an error.
311   virtual llvm::Expected<OpenOptions> GetOptions() const;
312 
313   llvm::Expected<const char *> GetOpenMode() const {
314     auto opts = GetOptions();
315     if (!opts)
316       return opts.takeError();
317     return GetStreamOpenModeFromOptions(opts.get());
318   }
319 
320   /// Get the permissions for a this file.
321   ///
322   /// \return
323   ///     Bits logical OR'ed together from the permission bits defined
324   ///     in lldb_private::File::Permissions.
325   uint32_t GetPermissions(Status &error) const;
326 
327   /// Return true if this file is interactive.
328   ///
329   /// \return
330   ///     True if this file is a terminal (tty or pty), false
331   ///     otherwise.
332   bool GetIsInteractive();
333 
334   /// Return true if this file from a real terminal.
335   ///
336   /// Just knowing a file is a interactive isn't enough, we also need to know
337   /// if the terminal has a width and height so we can do cursor movement and
338   /// other terminal manipulations by sending escape sequences.
339   ///
340   /// \return
341   ///     True if this file is a terminal (tty, not a pty) that has
342   ///     a non-zero width and height, false otherwise.
343   bool GetIsRealTerminal();
344 
345   /// Return true if this file is a terminal which supports colors.
346   ///
347   /// \return
348   ///    True iff this is a terminal and it supports colors.
349   bool GetIsTerminalWithColors();
350 
351   operator bool() const { return IsValid(); };
352 
353   bool operator!() const { return !IsValid(); };
354 
355   static char ID;
356   virtual bool isA(const void *classID) const { return classID == &ID; }
357   static bool classof(const File *file) { return file->isA(&ID); }
358 
359 protected:
360   LazyBool m_is_interactive = eLazyBoolCalculate;
361   LazyBool m_is_real_terminal = eLazyBoolCalculate;
362   LazyBool m_supports_colors = eLazyBoolCalculate;
363 
364   void CalculateInteractiveAndTerminal();
365 
366 private:
367   File(const File &) = delete;
368   const File &operator=(const File &) = delete;
369 };
370 
371 class NativeFile : public File {
372 public:
373   NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {}
374 
375   NativeFile(FILE *fh, bool transfer_ownership)
376       : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh),
377         m_options(), m_own_stream(transfer_ownership) {}
378 
379   NativeFile(int fd, OpenOptions options, bool transfer_ownership)
380       : m_descriptor(fd), m_own_descriptor(transfer_ownership),
381         m_stream(kInvalidStream), m_options(options), m_own_stream(false) {}
382 
383   ~NativeFile() override { Close(); }
384 
385   bool IsValid() const override {
386     return DescriptorIsValid() || StreamIsValid();
387   }
388 
389   Status Read(void *buf, size_t &num_bytes) override;
390   Status Write(const void *buf, size_t &num_bytes) override;
391   Status Close() override;
392   WaitableHandle GetWaitableHandle() override;
393   Status GetFileSpec(FileSpec &file_spec) const override;
394   int GetDescriptor() const override;
395   FILE *GetStream() override;
396   off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override;
397   off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override;
398   off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override;
399   Status Read(void *dst, size_t &num_bytes, off_t &offset) override;
400   Status Write(const void *src, size_t &num_bytes, off_t &offset) override;
401   Status Flush() override;
402   Status Sync() override;
403   size_t PrintfVarArg(const char *format, va_list args) override;
404   llvm::Expected<OpenOptions> GetOptions() const override;
405 
406   static char ID;
407   virtual bool isA(const void *classID) const override {
408     return classID == &ID || File::isA(classID);
409   }
410   static bool classof(const File *file) { return file->isA(&ID); }
411 
412 protected:
413   bool DescriptorIsValid() const {
414     return File::DescriptorIsValid(m_descriptor);
415   }
416   bool StreamIsValid() const { return m_stream != kInvalidStream; }
417 
418   // Member variables
419   int m_descriptor;
420   bool m_own_descriptor = false;
421   FILE *m_stream;
422   OpenOptions m_options{};
423   bool m_own_stream = false;
424   std::mutex offset_access_mutex;
425 
426 private:
427   NativeFile(const NativeFile &) = delete;
428   const NativeFile &operator=(const NativeFile &) = delete;
429 };
430 
431 } // namespace lldb_private
432 
433 #endif // LLDB_HOST_FILE_H
434