LLDB mainline
File.cpp
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#include "lldb/Host/File.h"
10
11#include <cerrno>
12#include <climits>
13#include <cstdarg>
14#include <cstdio>
15#include <fcntl.h>
16#include <optional>
17#include <sys/stat.h>
18
19#include "lldb/Host/Config.h"
21#include "lldb/Host/Host.h"
25#include "lldb/Utility/Log.h"
27#include "llvm/ADT/StringExtras.h"
28#include "llvm/Support/ConvertUTF.h"
29#include "llvm/Support/Errno.h"
30#include "llvm/Support/FileSystem.h"
31#include "llvm/Support/Process.h"
32#include "llvm/Support/raw_ostream.h"
33
34using namespace lldb;
35using namespace lldb_private;
36using llvm::Expected;
37
38Expected<const char *>
43
44 if (options & File::eOpenOptionAppend) {
47 return "a+x";
48 else
49 return "a+";
50 } else if (rw == File::eOpenOptionWriteOnly) {
52 return "ax";
53 else
54 return "a";
55 }
56 } else if (rw == File::eOpenOptionReadWrite) {
57 if (options & File::eOpenOptionCanCreate) {
59 return "w+x";
60 else
61 return "w+";
62 } else
63 return "r+";
64 } else if (rw == File::eOpenOptionWriteOnly) {
65 return "w";
66 } else if (rw == File::eOpenOptionReadOnly) {
67 return "r";
68 }
69 return llvm::createStringError(
70 llvm::inconvertibleErrorCode(),
71 "invalid options, cannot convert to mode string");
72}
73
74Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) {
75 OpenOptions opts =
76 llvm::StringSwitch<OpenOptions>(mode)
77 .Cases({"r", "rb"}, eOpenOptionReadOnly)
78 .Cases({"w", "wb"}, eOpenOptionWriteOnly)
79 .Cases({"a", "ab"}, eOpenOptionWriteOnly | eOpenOptionAppend |
81 .Cases({"r+", "rb+", "r+b"}, eOpenOptionReadWrite)
82 .Cases({"w+", "wb+", "w+b"}, eOpenOptionReadWrite |
85 .Cases({"a+", "ab+", "a+b"}, eOpenOptionReadWrite |
88 .Default(eOpenOptionInvalid);
89 if (opts != eOpenOptionInvalid)
90 return opts;
91 return llvm::createStringError(
92 llvm::inconvertibleErrorCode(),
93 "invalid mode, cannot convert to File::OpenOptions");
94}
95
97FILE *File::kInvalidStream = nullptr;
98
99Status File::Read(void *buf, size_t &num_bytes) {
100 return std::error_code(ENOTSUP, std::system_category());
101}
102Status File::Write(const void *buf, size_t &num_bytes) {
103 return std::error_code(ENOTSUP, std::system_category());
104}
105
106bool File::IsValid() const { return false; }
107
108Status File::Close() { return Flush(); }
109
113
115 file_spec.Clear();
116 return std::error_code(ENOTSUP, std::system_category());
117}
118
120
121FILE *File::GetStream() { return nullptr; }
122
123off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
124 if (error_ptr)
125 *error_ptr = std::error_code(ENOTSUP, std::system_category());
126 return -1;
127}
128
129off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
130 if (error_ptr)
131 *error_ptr = std::error_code(ENOTSUP, std::system_category());
132 return -1;
133}
134
135off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
136 if (error_ptr)
137 *error_ptr = std::error_code(ENOTSUP, std::system_category());
138 return -1;
139}
140
141Status File::Read(void *dst, size_t &num_bytes, off_t &offset) {
142 return std::error_code(ENOTSUP, std::system_category());
143}
144
145Status File::Write(const void *src, size_t &num_bytes, off_t &offset) {
146 return std::error_code(ENOTSUP, std::system_category());
147}
148
149Status File::Flush() { return Status(); }
150
151Status File::Sync() { return Flush(); }
152
154 // The base class has no descriptor of its own; concrete subclasses probe
155 // the platform. Default to "not a terminal" so callers see consistent
156 // values when they didn't override.
160}
161
167
173
179
180size_t File::Printf(const char *format, ...) {
181 va_list args;
182 va_start(args, format);
183 size_t result = PrintfVarArg(format, args);
184 va_end(args);
185 return result;
186}
187
188size_t File::PrintfVarArg(const char *format, va_list args) {
189 llvm::SmallString<0> s;
190 if (VASprintf(s, format, args)) {
191 size_t written = s.size();
192 Write(s.data(), written);
193 return written;
194 }
195 return 0;
196}
197
198Expected<File::OpenOptions> File::GetOptions() const {
199 return llvm::createStringError(
200 llvm::inconvertibleErrorCode(),
201 "GetOptions() not implemented for this File class");
202}
203
205 int fd = GetDescriptor();
206 if (!DescriptorIsValid(fd)) {
207 error = std::error_code(ENOTSUP, std::system_category());
208 return 0;
209 }
210 struct stat file_stats;
211 if (::fstat(fd, &file_stats) == -1) {
213 return 0;
214 }
215 error.Clear();
216 return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
217}
218
220
222 bool transfer_ownership)
223 : m_stream(fh), m_options(options), m_own_stream(transfer_ownership) {}
224
226 bool transfer_ownership)
227 : m_descriptor(fd), m_own_descriptor(transfer_ownership),
228 m_options(options) {}
229
231 std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex,
234}
235
236Expected<File::OpenOptions> NativeFileBase::GetOptions() const {
237 return m_options;
238}
239
240int NativeFileBase::Fileno(FILE *fh) const { return ::fileno(fh); }
241
242int NativeFileBase::Dup(int fd) const { return ::dup(fd); }
243
245 if (ValueGuard descriptor_guard = DescriptorIsValid()) {
246 return m_descriptor;
247 }
248
249 // Don't open the file descriptor if we don't need to, just get it from the
250 // stream if we have one.
251 if (ValueGuard stream_guard = StreamIsValid()) {
252 return Fileno(m_stream);
253 }
254
255 // Invalid descriptor and invalid stream, return invalid descriptor.
256 return kInvalidDescriptor;
257}
258
260 // The mapping from descriptor/stream to a poll-able WaitableHandle is
261 // platform-specific (an int on POSIX, a HANDLE on Windows). Subclasses
262 // override; the base returns the portable invalid sentinel.
264}
265
267 ValueGuard stream_guard = StreamIsValid();
268 if (stream_guard)
269 return m_stream;
270
271 ValueGuard descriptor_guard = DescriptorIsValid();
272 if (!descriptor_guard)
273 return m_stream;
274
275 auto mode_or_err = GetStreamOpenModeFromOptions(m_options);
276 if (!mode_or_err) {
277 LLDB_LOG_ERROR(GetLog(LLDBLog::Object), mode_or_err.takeError(),
278 "Failed to get stream options: {0}");
279 return m_stream;
280 }
281 const char *mode = *mode_or_err;
282
283 if (!m_own_descriptor) {
284 // We must duplicate the file descriptor if we don't own it because
285 // when you call fdopen, the stream will own the fd.
287 m_own_descriptor = true;
288 }
289
290 m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
291
292 // If we got a stream, then we own the stream and should no longer own
293 // the descriptor because fclose() will close it for us.
294 if (m_stream) {
295 m_own_stream = true;
296 m_own_descriptor = false;
298 }
299
300 return m_stream;
301}
302
304 std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex,
306
308
309 if (StreamIsValidUnlocked()) {
310 if (m_own_stream) {
311 if (::fclose(m_stream) == EOF)
313 } else {
317
318 if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) {
319 if (::fflush(m_stream) == EOF)
321 }
322 }
323 }
324
326 if (::close(m_descriptor) != 0)
328 }
329
331 m_own_stream = false;
333 m_own_descriptor = false;
337 return error;
338}
339
341 // Default: not supported. POSIX subclass overrides with F_GETPATH /
342 // /proc/self/fd lookups; the Windows subclass currently has no equivalent
343 // and inherits this behaviour.
344 file_spec.Clear();
346 "NativeFile::GetFileSpec is not supported on this platform");
347}
348
349off_t NativeFileBase::SeekFromStart(off_t offset, Status *error_ptr) {
350 off_t result = 0;
351 if (ValueGuard descriptor_guard = DescriptorIsValid()) {
352 result = ::lseek(m_descriptor, offset, SEEK_SET);
353
354 if (error_ptr) {
355 if (result == -1)
356 *error_ptr = Status::FromErrno();
357 else
358 error_ptr->Clear();
359 }
360 return result;
361 }
362
363 if (ValueGuard stream_guard = StreamIsValid()) {
364 result = ::fseek(m_stream, offset, SEEK_SET);
365
366 if (error_ptr) {
367 if (result == -1)
368 *error_ptr = Status::FromErrno();
369 else
370 error_ptr->Clear();
371 }
372 return result;
373 }
374
375 if (error_ptr)
376 *error_ptr = Status::FromErrorString("invalid file handle");
377 return result;
378}
379
380off_t NativeFileBase::SeekFromCurrent(off_t offset, Status *error_ptr) {
381 off_t result = -1;
382 if (ValueGuard descriptor_guard = DescriptorIsValid()) {
383 result = ::lseek(m_descriptor, offset, SEEK_CUR);
384
385 if (error_ptr) {
386 if (result == -1)
387 *error_ptr = Status::FromErrno();
388 else
389 error_ptr->Clear();
390 }
391 return result;
392 }
393
394 if (ValueGuard stream_guard = StreamIsValid()) {
395 result = ::fseek(m_stream, offset, SEEK_CUR);
396
397 if (error_ptr) {
398 if (result == -1)
399 *error_ptr = Status::FromErrno();
400 else
401 error_ptr->Clear();
402 }
403 return result;
404 }
405
406 if (error_ptr)
407 *error_ptr = Status::FromErrorString("invalid file handle");
408 return result;
409}
410
411off_t NativeFileBase::SeekFromEnd(off_t offset, Status *error_ptr) {
412 off_t result = -1;
413 if (ValueGuard descriptor_guard = DescriptorIsValid()) {
414 result = ::lseek(m_descriptor, offset, SEEK_END);
415
416 if (error_ptr) {
417 if (result == -1)
418 *error_ptr = Status::FromErrno();
419 else
420 error_ptr->Clear();
421 }
422 return result;
423 }
424
425 if (ValueGuard stream_guard = StreamIsValid()) {
426 result = ::fseek(m_stream, offset, SEEK_END);
427
428 if (error_ptr) {
429 if (result == -1)
430 *error_ptr = Status::FromErrno();
431 else
432 error_ptr->Clear();
433 }
434 return result;
435 }
436
437 if (error_ptr)
438 *error_ptr = Status::FromErrorString("invalid file handle");
439 return result;
440}
441
444 if (ValueGuard stream_guard = StreamIsValid()) {
445 if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF)
447 return error;
448 }
449
450 {
451 ValueGuard descriptor_guard = DescriptorIsValid();
452 if (!descriptor_guard)
453 error = Status::FromErrorString("invalid file handle");
454 }
455 return error;
456}
457
458#if defined(__APPLE__)
459// Darwin kernels only can read/write <= INT_MAX bytes
460#define MAX_READ_SIZE INT_MAX
461#define MAX_WRITE_SIZE INT_MAX
462#endif
463
464Status NativeFileBase::Read(void *buf, size_t &num_bytes) {
466
467 // Ensure the file is open for reading.
469 return Status(std::make_error_code(std::errc::bad_file_descriptor));
470
471#if defined(MAX_READ_SIZE)
472 if (num_bytes > MAX_READ_SIZE) {
473 uint8_t *p = (uint8_t *)buf;
474 size_t bytes_left = num_bytes;
475 // Init the num_bytes read to zero
476 num_bytes = 0;
477
478 while (bytes_left > 0) {
479 size_t curr_num_bytes;
480 if (bytes_left > MAX_READ_SIZE)
481 curr_num_bytes = MAX_READ_SIZE;
482 else
483 curr_num_bytes = bytes_left;
484
485 error = Read(p + num_bytes, curr_num_bytes);
486
487 // Update how many bytes were read
488 num_bytes += curr_num_bytes;
489 if (bytes_left < curr_num_bytes)
490 bytes_left = 0;
491 else
492 bytes_left -= curr_num_bytes;
493
494 if (error.Fail())
495 break;
496 }
497 return error;
498 }
499#endif
500
501 ssize_t bytes_read = -1;
502 if (ValueGuard descriptor_guard = DescriptorIsValid()) {
503 bytes_read =
504 llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes);
505 if (bytes_read == -1) {
507 num_bytes = 0;
508 } else
509 num_bytes = bytes_read;
510 return error;
511 }
512
513 if (ValueGuard file_lock = StreamIsValid()) {
514 bytes_read = ::fread(buf, 1, num_bytes, m_stream);
515
516 if (bytes_read == 0) {
517 if (::feof(m_stream))
519 else if (::ferror(m_stream))
520 error = Status::FromErrorString("ferror");
521 num_bytes = 0;
522 } else
523 num_bytes = bytes_read;
524 return error;
525 }
526
527 num_bytes = 0;
528 error = Status::FromErrorString("invalid file handle");
529 return error;
530}
531
532Status NativeFileBase::Write(const void *buf, size_t &num_bytes) {
534
535 // Ensure the file is open for writing.
537 return Status(std::make_error_code(std::errc::bad_file_descriptor));
538
539#if defined(MAX_WRITE_SIZE)
540 if (num_bytes > MAX_WRITE_SIZE) {
541 const uint8_t *p = (const uint8_t *)buf;
542 size_t bytes_left = num_bytes;
543 // Init the num_bytes written to zero
544 num_bytes = 0;
545
546 while (bytes_left > 0) {
547 size_t curr_num_bytes;
548 if (bytes_left > MAX_WRITE_SIZE)
549 curr_num_bytes = MAX_WRITE_SIZE;
550 else
551 curr_num_bytes = bytes_left;
552
553 error = Write(p + num_bytes, curr_num_bytes);
554
555 // Update how many bytes were read
556 num_bytes += curr_num_bytes;
557 if (bytes_left < curr_num_bytes)
558 bytes_left = 0;
559 else
560 bytes_left -= curr_num_bytes;
561
562 if (error.Fail())
563 break;
564 }
565 return error;
566 }
567#endif
568
569 ssize_t bytes_written = -1;
570 if (ValueGuard descriptor_guard = DescriptorIsValid()) {
571 bytes_written =
572 llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes);
573 if (bytes_written == -1) {
575 num_bytes = 0;
576 } else
577 num_bytes = bytes_written;
578 return error;
579 }
580
581 if (ValueGuard stream_guard = StreamIsValid()) {
582 if (TryWriteStreamUnlocked(buf, num_bytes, error))
583 return error;
584 bytes_written = ::fwrite(buf, 1, num_bytes, m_stream);
585
586 if (bytes_written == 0) {
587 if (::feof(m_stream))
589 else if (::ferror(m_stream))
590 error = Status::FromErrorString("ferror");
591 num_bytes = 0;
592 } else
593 num_bytes = bytes_written;
594 return error;
595 }
596
597 num_bytes = 0;
598 error = Status::FromErrorString("invalid file handle");
599 return error;
600}
601
602size_t NativeFileBase::PrintfVarArg(const char *format, va_list args) {
603 if (StreamIsValid()) {
604 return ::vfprintf(m_stream, format, args);
605 } else {
606 return File::PrintfVarArg(format, args);
607 }
608}
609
611 mode_t mode = 0;
615 if (rw == eOpenOptionReadWrite)
616 mode |= O_RDWR;
617 else if (rw == eOpenOptionWriteOnly)
618 mode |= O_WRONLY;
619 else if (rw == eOpenOptionReadOnly)
620 mode |= O_RDONLY;
621
622 if (open_options & eOpenOptionAppend)
623 mode |= O_APPEND;
624
625 if (open_options & eOpenOptionTruncate)
626 mode |= O_TRUNC;
627
628 if (open_options & eOpenOptionNonBlocking)
629 mode |= O_NONBLOCK;
630
631 if (open_options & eOpenOptionCanCreateNewOnly)
632 mode |= O_CREAT | O_EXCL;
633 else if (open_options & eOpenOptionCanCreate)
634 mode |= O_CREAT;
635
636 return mode;
637}
638
639llvm::Expected<SerialPort::Options>
640SerialPort::OptionsFromURL(llvm::StringRef urlqs) {
641 SerialPort::Options serial_options;
642 for (llvm::StringRef x : llvm::split(urlqs, '&')) {
643 if (x.consume_front("baud=")) {
644 unsigned int baud_rate;
645 if (!llvm::to_integer(x, baud_rate, 10))
646 return llvm::createStringError(llvm::inconvertibleErrorCode(),
647 "Invalid baud rate: %s",
648 x.str().c_str());
649 serial_options.BaudRate = baud_rate;
650 } else if (x.consume_front("parity=")) {
651 serial_options.Parity =
652 llvm::StringSwitch<std::optional<Terminal::Parity>>(x)
653 .Case("no", Terminal::Parity::No)
654 .Case("even", Terminal::Parity::Even)
655 .Case("odd", Terminal::Parity::Odd)
656 .Case("mark", Terminal::Parity::Mark)
657 .Case("space", Terminal::Parity::Space)
658 .Default(std::nullopt);
659 if (!serial_options.Parity)
660 return llvm::createStringError(
661 llvm::inconvertibleErrorCode(),
662 "Invalid parity (must be no, even, odd, mark or space): %s",
663 x.str().c_str());
664 } else if (x.consume_front("parity-check=")) {
665 serial_options.ParityCheck =
666 llvm::StringSwitch<std::optional<Terminal::ParityCheck>>(x)
667 .Case("no", Terminal::ParityCheck::No)
669 .Case("ignore", Terminal::ParityCheck::Ignore)
670 // "mark" mode is not currently supported as it requires special
671 // input processing
672 // .Case("mark", Terminal::ParityCheck::Mark)
673 .Default(std::nullopt);
674 if (!serial_options.ParityCheck)
675 return llvm::createStringError(
676 llvm::inconvertibleErrorCode(),
677 "Invalid parity-check (must be no, replace, ignore or mark): %s",
678 x.str().c_str());
679 } else if (x.consume_front("stop-bits=")) {
680 unsigned int stop_bits;
681 if (!llvm::to_integer(x, stop_bits, 10) ||
682 (stop_bits != 1 && stop_bits != 2))
683 return llvm::createStringError(
684 llvm::inconvertibleErrorCode(),
685 "Invalid stop bit number (must be 1 or 2): %s", x.str().c_str());
686 serial_options.StopBits = stop_bits;
687 } else
688 return llvm::createStringError(llvm::inconvertibleErrorCode(),
689 "Unknown parameter: %s", x.str().c_str());
690 }
691 return serial_options;
692}
693
694llvm::Expected<std::unique_ptr<SerialPort>>
695SerialPort::Create(int fd, OpenOptions options, Options serial_options,
696 bool transfer_ownership) {
697 std::unique_ptr<SerialPort> out{
698 new SerialPort(fd, options, serial_options, transfer_ownership)};
699
700 if (!out->GetIsInteractive())
701 return llvm::createStringError(llvm::inconvertibleErrorCode(),
702 "the specified file is not a teletype");
703
704 Terminal term{fd};
705 if (llvm::Error error = term.SetRaw())
706 return std::move(error);
707 if (serial_options.BaudRate) {
708 if (llvm::Error error = term.SetBaudRate(*serial_options.BaudRate))
709 return std::move(error);
710 }
711 if (serial_options.Parity) {
712 if (llvm::Error error = term.SetParity(*serial_options.Parity))
713 return std::move(error);
714 }
715 if (serial_options.ParityCheck) {
716 if (llvm::Error error = term.SetParityCheck(*serial_options.ParityCheck))
717 return std::move(error);
718 }
719 if (serial_options.StopBits) {
720 if (llvm::Error error = term.SetStopBits(*serial_options.StopBits))
721 return std::move(error);
722 }
723
724 return std::move(out);
725}
726
728 SerialPort::Options serial_options,
729 bool transfer_ownership)
730 : NativeFile(fd, options, transfer_ownership), m_state(fd) {}
731
733 m_state.Restore();
734 return NativeFile::Close();
735}
736
737char File::ID = 0;
738char NativeFileBase::ID = 0;
739char SerialPort::ID = 0;
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:394
A file utility class.
Definition FileSpec.h:57
void Clear()
Clears the object state.
Definition FileSpec.cpp:259
virtual llvm::Expected< OpenOptions > GetOptions() const
Return the OpenOptions for this file.
Definition File.cpp:198
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition File.cpp:180
WaitableHandle GetWaitableHandle() override
Get a handle that can be used for OS polling interfaces, such as WaitForMultipleObjects,...
Definition File.cpp:110
bool GetIsRealTerminal()
Return true if this file from a real terminal.
Definition File.cpp:168
static constexpr OpenOptions OpenOptionsModeMask
Definition FileBase.h:67
virtual FILE * GetStream()
Get the underlying libc stream for this file, or NULL.
Definition File.cpp:121
Status Read(void *buf, size_t &num_bytes) override
Read bytes from a file from the current file position into buf.
Definition File.cpp:99
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:123
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:114
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:129
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:610
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
Definition File.cpp:119
static llvm::Expected< const char * > GetStreamOpenModeFromOptions(OpenOptions options)
Definition File.cpp:39
bool GetIsTerminalWithColors()
Return true if this file is a terminal which supports colors.
Definition File.cpp:174
Status Close() override
Flush any buffers and release any resources owned by the file.
Definition File.cpp:108
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:102
@ eOpenOptionCanCreateNewOnly
Definition FileBase.h:56
uint32_t GetPermissions(Status &error) const
Get the permissions for a this file.
Definition File.cpp:204
bool IsValid() const override
IsValid.
Definition File.cpp:106
static char ID
Definition FileBase.h:362
virtual Status Flush()
Flush the current stream.
Definition File.cpp:149
static llvm::Expected< OpenOptions > GetOptionsFromMode(llvm::StringRef mode)
Definition File.cpp:74
size_t virtual size_t PrintfVarArg(const char *format, va_list args)
Output printf formatted output to the stream.
Definition File.cpp:188
virtual Status Sync()
Sync to disk.
Definition File.cpp:151
LazyBool m_supports_colors
Definition FileBase.h:369
bool GetIsInteractive()
Return true if this file is interactive.
Definition File.cpp:162
virtual void CalculateInteractiveAndTerminal()
Refresh the cached interactive / terminal / color flags by inspecting the underlying descriptor.
Definition File.cpp:153
virtual void OnStreamOpened()
Called after a stream is successfully opened from a descriptor.
Definition FileBase.h:378
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:135
static const WaitableHandle kInvalidHandleValue
Definition IOObject.h:31
lldb::file_t WaitableHandle
Definition IOObject.h:29
bool DescriptorIsValidUnlocked() const
Definition FileBase.h:439
WaitableHandle GetWaitableHandle() override
Get a handle that can be used for OS polling interfaces, such as WaitForMultipleObjects,...
Definition File.cpp:259
bool StreamIsValidUnlocked() const
Definition FileBase.h:443
Status Flush() override
Flush the current stream.
Definition File.cpp:442
llvm::Expected< OpenOptions > GetOptions() const override
Return the OpenOptions for this file.
Definition File.cpp:236
off_t SeekFromCurrent(off_t offset, Status *error_ptr=nullptr) override
Seek to an offset relative to the current file position.
Definition File.cpp:380
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:532
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:463
virtual int Fileno(FILE *fh) const
Map a stream to its underlying file descriptor.
Definition File.cpp:240
int GetDescriptor() const override
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
Definition File.cpp:244
virtual int Dup(int fd) const
Duplicate a file descriptor.
Definition File.cpp:242
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:411
ValueGuard StreamIsValid() const
Definition FileBase.h:450
ValueGuard DescriptorIsValid() const
Definition FileBase.h:445
bool IsValid() const override
IsValid.
Definition File.cpp:230
size_t PrintfVarArg(const char *format, va_list args) override
Output printf formatted output to the stream.
Definition File.cpp:602
FILE * GetStream() override
Get the underlying libc stream for this file, or NULL.
Definition File.cpp:266
Status GetFileSpec(FileSpec &file_spec) const override
Get the file specification for this file, if possible.
Definition File.cpp:340
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:349
Status Close() override
Flush any buffers and release any resources owned by the file.
Definition File.cpp:303
Status Read(void *buf, size_t &num_bytes) override
Read bytes from a file from the current file position into buf.
Definition File.cpp:464
static llvm::Expected< std::unique_ptr< SerialPort > > Create(int fd, OpenOptions options, Options serial_options, bool transfer_ownership)
Definition File.cpp:695
TerminalState m_state
Definition File.h:68
SerialPort(int fd, OpenOptions options, Options serial_options, bool transfer_ownership)
Definition File.cpp:727
Status Close() override
Flush any buffers and release any resources owned by the file.
Definition File.cpp:732
static char ID
Definition File.h:55
static llvm::Expected< Options > OptionsFromURL(llvm::StringRef urlqs)
Definition File.cpp:640
An error handling class.
Definition Status.h:118
void Clear()
Clear the object state.
Definition Status.cpp:214
static Status FromErrno()
Set the current error to errno.
Definition Status.cpp:299
static Status FromErrorString(const char *str)
Definition Status.h:141
llvm::Error SetRaw()
Definition Terminal.cpp:112
llvm::Error SetParityCheck(ParityCheck parity_check)
Definition Terminal.cpp:361
llvm::Error SetBaudRate(unsigned int baud_rate)
Definition Terminal.cpp:277
llvm::Error SetParity(Parity parity)
Definition Terminal.cpp:328
llvm::Error SetStopBits(unsigned int stop_bits)
Definition Terminal.cpp:303
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
bool VASprintf(llvm::SmallVectorImpl< char > &buf, const char *fmt, va_list args)
Definition VASprintf.cpp:19
NativeFilePosix NativeFile
Definition File.h:29
std::optional< Terminal::ParityCheck > ParityCheck
Definition File.h:37
std::optional< unsigned int > StopBits
Definition File.h:38
std::optional< Terminal::Parity > Parity
Definition File.h:36
std::optional< unsigned int > BaudRate
Definition File.h:35
#define S_IRWXG
#define O_NONBLOCK
#define S_IRWXO
#define S_IRWXU