• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <mutex>
19 #include <stdarg.h>
20 #include <stdio.h>
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);
DescriptorIsValid(int descriptor)64   static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
65   static llvm::Expected<const char *>
66   GetStreamOpenModeFromOptions(OpenOptions options);
67 
File()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 
GetOpenMode()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;
isA(const void * classID)359   virtual bool isA(const void *classID) const { return classID == &ID; }
classof(const File * file)360   static bool classof(const File *file) { return file->isA(&ID); }
361 
362 protected:
363   LazyBool m_is_interactive;
364   LazyBool m_is_real_terminal;
365   LazyBool m_supports_colors;
366 
367   void CalculateInteractiveAndTerminal();
368 
369 private:
370   File(const File &) = delete;
371   const File &operator=(const File &) = delete;
372 };
373 
374 class NativeFile : public File {
375 public:
NativeFile()376   NativeFile()
377       : m_descriptor(kInvalidDescriptor), m_own_descriptor(false),
378         m_stream(kInvalidStream), m_options(), m_own_stream(false) {}
379 
NativeFile(FILE * fh,bool transfer_ownership)380   NativeFile(FILE *fh, bool transfer_ownership)
381       : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh),
382         m_options(), m_own_stream(transfer_ownership) {}
383 
NativeFile(int fd,OpenOptions options,bool transfer_ownership)384   NativeFile(int fd, OpenOptions options, bool transfer_ownership)
385       : m_descriptor(fd), m_own_descriptor(transfer_ownership),
386         m_stream(kInvalidStream), m_options(options), m_own_stream(false) {}
387 
~NativeFile()388   ~NativeFile() override { Close(); }
389 
IsValid()390   bool IsValid() const override {
391     return DescriptorIsValid() || StreamIsValid();
392   }
393 
394   Status Read(void *buf, size_t &num_bytes) override;
395   Status Write(const void *buf, size_t &num_bytes) override;
396   Status Close() override;
397   WaitableHandle GetWaitableHandle() override;
398   Status GetFileSpec(FileSpec &file_spec) const override;
399   int GetDescriptor() const override;
400   FILE *GetStream() override;
401   off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override;
402   off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override;
403   off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override;
404   Status Read(void *dst, size_t &num_bytes, off_t &offset) override;
405   Status Write(const void *src, size_t &num_bytes, off_t &offset) override;
406   Status Flush() override;
407   Status Sync() override;
408   size_t PrintfVarArg(const char *format, va_list args) override;
409   llvm::Expected<OpenOptions> GetOptions() const override;
410 
411   static char ID;
isA(const void * classID)412   virtual bool isA(const void *classID) const override {
413     return classID == &ID || File::isA(classID);
414   }
classof(const File * file)415   static bool classof(const File *file) { return file->isA(&ID); }
416 
417 protected:
DescriptorIsValid()418   bool DescriptorIsValid() const {
419     return File::DescriptorIsValid(m_descriptor);
420   }
StreamIsValid()421   bool StreamIsValid() const { return m_stream != kInvalidStream; }
422 
423   // Member variables
424   int m_descriptor;
425   bool m_own_descriptor;
426   FILE *m_stream;
427   OpenOptions m_options;
428   bool m_own_stream;
429   std::mutex offset_access_mutex;
430 
431 private:
432   NativeFile(const NativeFile &) = delete;
433   const NativeFile &operator=(const NativeFile &) = delete;
434 };
435 
436 } // namespace lldb_private
437 
438 #endif // LLDB_HOST_FILE_H
439