11#include "lldb/Host/Config.h"
13#include "llvm/ADT/STLExtras.h"
19#if LLDB_ENABLE_TERMIOS
26#if LLDB_ENABLE_TERMIOS
27 struct termios m_termios;
33#if !LLDB_ENABLE_TERMIOS
35 return llvm::createStringError(llvm::inconvertibleErrorCode(),
36 "termios support missing in LLDB");
41#if LLDB_ENABLE_TERMIOS
43 return llvm::createStringError(llvm::inconvertibleErrorCode(),
47 return llvm::createStringError(llvm::inconvertibleErrorCode(),
51 if (::tcgetattr(
m_fd, &data.m_termios) != 0)
52 return llvm::createStringError(
53 std::error_code(errno, std::generic_category()),
54 "unable to get teletype attributes");
62#if LLDB_ENABLE_TERMIOS
66 if (::tcsetattr(
m_fd, TCSANOW, &data.m_termios) != 0)
67 return llvm::createStringError(
68 std::error_code(errno, std::generic_category()),
69 "unable to set teletype attributes");
70 return llvm::Error::success();
77#if LLDB_ENABLE_TERMIOS
78 llvm::Expected<Data> data =
GetData();
80 return data.takeError();
82 struct termios &fd_termios = data->m_termios;
83 fd_termios.c_lflag &= ~ECHO;
85 fd_termios.c_lflag |= ECHO;
93#if LLDB_ENABLE_TERMIOS
94 llvm::Expected<Data> data =
GetData();
96 return data.takeError();
98 struct termios &fd_termios = data->m_termios;
99 fd_termios.c_lflag &= ~ICANON;
101 fd_termios.c_lflag |= ICANON;
109#if LLDB_ENABLE_TERMIOS
110 llvm::Expected<Data> data =
GetData();
112 return data.takeError();
114 struct termios &fd_termios = data->m_termios;
115 ::cfmakeraw(&fd_termios);
119 fd_termios.c_cc[VMIN] = 1;
120 fd_termios.c_cc[VTIME] = 0;
128#if LLDB_ENABLE_TERMIOS
129static std::optional<speed_t> baudRateToConst(
unsigned int baud_rate) {
274#if LLDB_ENABLE_TERMIOS
275 llvm::Expected<Data> data =
GetData();
277 return data.takeError();
279 struct termios &fd_termios = data->m_termios;
280 std::optional<speed_t> val = baudRateToConst(baud_rate);
282 return llvm::createStringError(llvm::inconvertibleErrorCode(),
283 "baud rate %d unsupported by the platform",
285 if (::cfsetispeed(&fd_termios, *val) != 0)
286 return llvm::createStringError(
287 std::error_code(errno, std::generic_category()),
288 "setting input baud rate failed");
289 if (::cfsetospeed(&fd_termios, *val) != 0)
290 return llvm::createStringError(
291 std::error_code(errno, std::generic_category()),
292 "setting output baud rate failed");
300#if LLDB_ENABLE_TERMIOS
301 llvm::Expected<Data> data =
GetData();
303 return data.takeError();
305 struct termios &fd_termios = data->m_termios;
308 fd_termios.c_cflag &= ~CSTOPB;
311 fd_termios.c_cflag |= CSTOPB;
314 return llvm::createStringError(
315 llvm::inconvertibleErrorCode(),
316 "invalid stop bit count: %d (must be 1 or 2)", stop_bits);
325#if LLDB_ENABLE_TERMIOS
326 llvm::Expected<Data> data =
GetData();
328 return data.takeError();
330 struct termios &fd_termios = data->m_termios;
331 fd_termios.c_cflag &= ~(
338 fd_termios.c_cflag |= PARENB;
340 fd_termios.c_cflag |= PARODD;
343 fd_termios.c_cflag |= CMSPAR;
345 return llvm::createStringError(
346 llvm::inconvertibleErrorCode(),
347 "space/mark parity is not supported by the platform");
358#if LLDB_ENABLE_TERMIOS
359 llvm::Expected<Data> data =
GetData();
361 return data.takeError();
363 struct termios &fd_termios = data->m_termios;
364 fd_termios.c_iflag &= ~(IGNPAR | PARMRK | INPCK);
367 fd_termios.c_iflag |= INPCK;
369 fd_termios.c_iflag |= IGNPAR;
371 fd_termios.c_iflag |= PARMRK;
380#if LLDB_ENABLE_TERMIOS
381 llvm::Expected<Data> data =
GetData();
383 return data.takeError();
386 struct termios &fd_termios = data->m_termios;
387 fd_termios.c_cflag &= ~CRTSCTS;
389 fd_termios.c_cflag |= CRTSCTS;
393 return llvm::createStringError(
394 llvm::inconvertibleErrorCode(),
395 "hardware flow control is not supported by the platform");
396 return llvm::Error::success();
405 Save(term, save_process_group);
424#if LLDB_ENABLE_TERMIOS
426 if (::tcgetattr(fd, &new_data->m_termios) == 0)
427 m_data = std::move(new_data);
429 if (save_process_group)
443#if LLDB_ENABLE_TERMIOS
445 tcsetattr(fd, TCSANOW, &
m_data->m_termios);
450 void (*saved_sigttou_callback)(int) =
nullptr;
451 saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN);
455 signal(SIGTTOU, saved_sigttou_callback);
static llvm::Error termiosMissingError()
~TerminalState()
Destroy the instance, restoring terminal state if saved.
int m_tflags
Cached tflags information.
bool TFlagsIsValid() const
Test if tflags is valid.
bool Save(Terminal term, bool save_process_group)
Save the TTY state for fd.
std::unique_ptr< Terminal::Data > m_data
Platform-specific implementation.
bool TTYStateIsValid() const
Test if ttystate is valid.
bool Restore() const
Restore the TTY state to the cached state.
Terminal m_tty
A terminal.
lldb::pid_t m_process_group
Cached process group information.
TerminalState(Terminal term=-1, bool save_process_group=false)
Construct a new instance and optionally save terminal state.
bool IsValid() const
Test for valid cached TTY state information.
bool ProcessGroupIsValid() const
Test if the process group information is valid.
llvm::Error SetEcho(bool enabled)
int GetFileDescriptor() const
llvm::Error SetParityCheck(ParityCheck parity_check)
llvm::Error SetCanonical(bool enabled)
llvm::Error SetBaudRate(unsigned int baud_rate)
bool FileDescriptorIsValid() const
llvm::Error SetData(const Data &data)
llvm::Error SetHardwareFlowControl(bool enabled)
llvm::Expected< Data > GetData()
llvm::Error SetParity(Parity parity)
llvm::Error SetStopBits(unsigned int stop_bits)
A class that represents a running process on the host machine.