19#include "lldb/Host/Config.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"
69 return llvm::createStringError(
70 llvm::inconvertibleErrorCode(),
71 "invalid options, cannot convert to mode string");
76 llvm::StringSwitch<OpenOptions>(mode)
91 return llvm::createStringError(
92 llvm::inconvertibleErrorCode(),
93 "invalid mode, cannot convert to File::OpenOptions");
100 return std::error_code(ENOTSUP, std::system_category());
103 return std::error_code(ENOTSUP, std::system_category());
116 return std::error_code(ENOTSUP, std::system_category());
125 *error_ptr = std::error_code(ENOTSUP, std::system_category());
131 *error_ptr = std::error_code(ENOTSUP, std::system_category());
137 *error_ptr = std::error_code(ENOTSUP, std::system_category());
142 return std::error_code(ENOTSUP, std::system_category());
146 return std::error_code(ENOTSUP, std::system_category());
182 va_start(args, format);
189 llvm::SmallString<0> s;
191 size_t written = s.size();
192 Write(s.data(), written);
199 return llvm::createStringError(
200 llvm::inconvertibleErrorCode(),
201 "GetOptions() not implemented for this File class");
207 error = std::error_code(ENOTSUP, std::system_category());
210 struct stat file_stats;
211 if (::fstat(fd, &file_stats) == -1) {
222 bool transfer_ownership)
226 bool transfer_ownership)
272 if (!descriptor_guard)
278 "Failed to get stream options: {0}");
281 const char *mode = *mode_or_err;
346 "NativeFile::GetFileSpec is not supported on this platform");
364 result = ::fseek(
m_stream, offset, SEEK_SET);
395 result = ::fseek(
m_stream, offset, SEEK_CUR);
426 result = ::fseek(
m_stream, offset, SEEK_END);
445 if (llvm::sys::RetryAfterSignal(EOF, ::fflush,
m_stream) == EOF)
452 if (!descriptor_guard)
458#if defined(__APPLE__)
460#define MAX_READ_SIZE INT_MAX
461#define MAX_WRITE_SIZE INT_MAX
469 return Status(std::make_error_code(std::errc::bad_file_descriptor));
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;
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;
483 curr_num_bytes = bytes_left;
485 error =
Read(p + num_bytes, curr_num_bytes);
488 num_bytes += curr_num_bytes;
489 if (bytes_left < curr_num_bytes)
492 bytes_left -= curr_num_bytes;
501 ssize_t bytes_read = -1;
504 llvm::sys::RetryAfterSignal(-1, ::read,
m_descriptor, buf, num_bytes);
505 if (bytes_read == -1) {
509 num_bytes = bytes_read;
514 bytes_read = ::fread(buf, 1, num_bytes,
m_stream);
516 if (bytes_read == 0) {
523 num_bytes = bytes_read;
537 return Status(std::make_error_code(std::errc::bad_file_descriptor));
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;
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;
551 curr_num_bytes = bytes_left;
556 num_bytes += curr_num_bytes;
557 if (bytes_left < curr_num_bytes)
560 bytes_left -= curr_num_bytes;
569 ssize_t bytes_written = -1;
572 llvm::sys::RetryAfterSignal(-1, ::write,
m_descriptor, buf, num_bytes);
573 if (bytes_written == -1) {
577 num_bytes = bytes_written;
584 bytes_written = ::fwrite(buf, 1, num_bytes,
m_stream);
586 if (bytes_written == 0) {
593 num_bytes = bytes_written;
604 return ::vfprintf(
m_stream, format, args);
632 mode |= O_CREAT | O_EXCL;
639llvm::Expected<SerialPort::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",
649 serial_options.
BaudRate = baud_rate;
650 }
else if (x.consume_front(
"parity=")) {
652 llvm::StringSwitch<std::optional<Terminal::Parity>>(x)
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",
664 }
else if (x.consume_front(
"parity-check=")) {
666 llvm::StringSwitch<std::optional<Terminal::ParityCheck>>(x)
673 .Default(std::nullopt);
675 return llvm::createStringError(
676 llvm::inconvertibleErrorCode(),
677 "Invalid parity-check (must be no, replace, ignore or mark): %s",
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;
688 return llvm::createStringError(llvm::inconvertibleErrorCode(),
689 "Unknown parameter: %s", x.str().c_str());
691 return serial_options;
694llvm::Expected<std::unique_ptr<SerialPort>>
696 bool transfer_ownership) {
697 std::unique_ptr<SerialPort> out{
698 new SerialPort(fd, options, serial_options, transfer_ownership)};
700 if (!out->GetIsInteractive())
701 return llvm::createStringError(llvm::inconvertibleErrorCode(),
702 "the specified file is not a teletype");
706 return std::move(
error);
709 return std::move(
error);
711 if (serial_options.
Parity) {
713 return std::move(
error);
717 return std::move(
error);
721 return std::move(
error);
724 return std::move(out);
729 bool transfer_ownership)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
void Clear()
Clears the object state.
virtual llvm::Expected< OpenOptions > GetOptions() const
Return the OpenOptions for this file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
WaitableHandle GetWaitableHandle() override
Get a handle that can be used for OS polling interfaces, such as WaitForMultipleObjects,...
bool GetIsRealTerminal()
Return true if this file from a real terminal.
static constexpr OpenOptions OpenOptionsModeMask
virtual FILE * GetStream()
Get the underlying libc stream for this file, or NULL.
Status Read(void *buf, size_t &num_bytes) override
Read bytes from a file from the current file position into buf.
virtual off_t SeekFromStart(off_t offset, Status *error_ptr=nullptr)
Seek to an offset relative to the beginning of the file.
static int kInvalidDescriptor
static FILE * kInvalidStream
virtual Status GetFileSpec(FileSpec &file_spec) const
Get the file specification for this file, if possible.
LazyBool m_is_real_terminal
virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr=nullptr)
Seek to an offset relative to the current file position.
LazyBool m_is_interactive
static bool DescriptorIsValid(int descriptor)
static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options)
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
static llvm::Expected< const char * > GetStreamOpenModeFromOptions(OpenOptions options)
bool GetIsTerminalWithColors()
Return true if this file is a terminal which supports colors.
Status Close() override
Flush any buffers and release any resources owned by the file.
Status Write(const void *buf, size_t &num_bytes) override
Write bytes from buf to a file at the current file position.
@ eOpenOptionCanCreateNewOnly
uint32_t GetPermissions(Status &error) const
Get the permissions for a this file.
bool IsValid() const override
IsValid.
virtual Status Flush()
Flush the current stream.
static llvm::Expected< OpenOptions > GetOptionsFromMode(llvm::StringRef mode)
size_t virtual size_t PrintfVarArg(const char *format, va_list args)
Output printf formatted output to the stream.
virtual Status Sync()
Sync to disk.
LazyBool m_supports_colors
bool GetIsInteractive()
Return true if this file is interactive.
virtual void CalculateInteractiveAndTerminal()
Refresh the cached interactive / terminal / color flags by inspecting the underlying descriptor.
virtual void OnStreamOpened()
Called after a stream is successfully opened from a descriptor.
virtual off_t SeekFromEnd(off_t offset, Status *error_ptr=nullptr)
Seek to an offset relative to the end of the file.
static const WaitableHandle kInvalidHandleValue
lldb::file_t WaitableHandle
bool DescriptorIsValidUnlocked() const
std::mutex m_stream_mutex
WaitableHandle GetWaitableHandle() override
Get a handle that can be used for OS polling interfaces, such as WaitForMultipleObjects,...
bool StreamIsValidUnlocked() const
Status Flush() override
Flush the current stream.
llvm::Expected< OpenOptions > GetOptions() const override
Return the OpenOptions for this file.
off_t SeekFromCurrent(off_t offset, Status *error_ptr=nullptr) override
Seek to an offset relative to the current file position.
Status Write(const void *buf, size_t &num_bytes) override
Write bytes from buf to a file at the current file position.
virtual bool TryWriteStreamUnlocked(const void *buf, size_t &num_bytes, Status &error)
Hook for stream writes that bypass the default fwrite path.
virtual int Fileno(FILE *fh) const
Map a stream to its underlying file descriptor.
int GetDescriptor() const override
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
virtual int Dup(int fd) const
Duplicate a file descriptor.
off_t SeekFromEnd(off_t offset, Status *error_ptr=nullptr) override
Seek to an offset relative to the end of the file.
ValueGuard StreamIsValid() const
ValueGuard DescriptorIsValid() const
bool IsValid() const override
IsValid.
std::mutex m_descriptor_mutex
size_t PrintfVarArg(const char *format, va_list args) override
Output printf formatted output to the stream.
FILE * GetStream() override
Get the underlying libc stream for this file, or NULL.
Status GetFileSpec(FileSpec &file_spec) const override
Get the file specification for this file, if possible.
off_t SeekFromStart(off_t offset, Status *error_ptr=nullptr) override
Seek to an offset relative to the beginning of the file.
Status Close() override
Flush any buffers and release any resources owned by the file.
Status Read(void *buf, size_t &num_bytes) override
Read bytes from a file from the current file position into buf.
static llvm::Expected< std::unique_ptr< SerialPort > > Create(int fd, OpenOptions options, Options serial_options, bool transfer_ownership)
SerialPort(int fd, OpenOptions options, Options serial_options, bool transfer_ownership)
Status Close() override
Flush any buffers and release any resources owned by the file.
static llvm::Expected< Options > OptionsFromURL(llvm::StringRef urlqs)
void Clear()
Clear the object state.
static Status FromErrno()
Set the current error to errno.
static Status FromErrorString(const char *str)
llvm::Error SetParityCheck(ParityCheck parity_check)
llvm::Error SetBaudRate(unsigned int baud_rate)
llvm::Error SetParity(Parity parity)
llvm::Error SetStopBits(unsigned int stop_bits)
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.
bool VASprintf(llvm::SmallVectorImpl< char > &buf, const char *fmt, va_list args)
NativeFilePosix NativeFile
std::optional< Terminal::ParityCheck > ParityCheck
std::optional< unsigned int > StopBits
std::optional< Terminal::Parity > Parity
std::optional< unsigned int > BaudRate