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