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