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