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