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