21
21
22
22
using namespace lldb_private ;
23
23
24
+ struct Terminal ::Data {
25
+ #if LLDB_ENABLE_TERMIOS
26
+ struct termios m_termios; // /< Cached terminal state information.
27
+ #endif
28
+ };
29
+
24
30
bool Terminal::IsATerminal () const { return m_fd >= 0 && ::isatty (m_fd); }
25
31
26
- bool Terminal::SetEcho (bool enabled) {
27
- if (FileDescriptorIsValid ()) {
32
+ llvm::Expected<Terminal::Data> Terminal::GetData () {
33
+ if (!FileDescriptorIsValid ())
34
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
35
+ " invalid fd" );
36
+
28
37
#if LLDB_ENABLE_TERMIOS
29
- if (IsATerminal ()) {
30
- struct termios fd_termios;
31
- if (::tcgetattr (m_fd, &fd_termios) == 0 ) {
32
- bool set_corectly = false ;
33
- if (enabled) {
34
- if (fd_termios.c_lflag & ECHO)
35
- set_corectly = true ;
36
- else
37
- fd_termios.c_lflag |= ECHO;
38
- } else {
39
- if (fd_termios.c_lflag & ECHO)
40
- fd_termios.c_lflag &= ~ECHO;
41
- else
42
- set_corectly = true ;
43
- }
44
-
45
- if (set_corectly)
46
- return true ;
47
- return ::tcsetattr (m_fd, TCSANOW, &fd_termios) == 0 ;
48
- }
49
- }
50
- #endif // #if LLDB_ENABLE_TERMIOS
51
- }
52
- return false ;
38
+ if (!IsATerminal ())
39
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
40
+ " fd not a terminal" );
41
+
42
+ Data data;
43
+ if (::tcgetattr (m_fd, &data.m_termios ) != 0 )
44
+ return llvm::createStringError (
45
+ std::error_code (errno, std::generic_category ()),
46
+ " unable to get teletype attributes" );
47
+ return data;
48
+ #else // !LLDB_ENABLE_TERMIOS
49
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
50
+ " termios support missing in LLDB" );
51
+ #endif // LLDB_ENABLE_TERMIOS
53
52
}
54
53
55
- bool Terminal::SetCanonical (bool enabled) {
56
- if (FileDescriptorIsValid ()) {
54
+ llvm::Error Terminal::SetData (const Terminal::Data &data) {
57
55
#if LLDB_ENABLE_TERMIOS
58
- if (IsATerminal ()) {
59
- struct termios fd_termios;
60
- if (::tcgetattr (m_fd, &fd_termios) == 0 ) {
61
- bool set_corectly = false ;
62
- if (enabled) {
63
- if (fd_termios.c_lflag & ICANON)
64
- set_corectly = true ;
65
- else
66
- fd_termios.c_lflag |= ICANON;
67
- } else {
68
- if (fd_termios.c_lflag & ICANON)
69
- fd_termios.c_lflag &= ~ICANON;
70
- else
71
- set_corectly = true ;
72
- }
73
-
74
- if (set_corectly)
75
- return true ;
76
- return ::tcsetattr (m_fd, TCSANOW, &fd_termios) == 0 ;
77
- }
78
- }
79
- #endif // #if LLDB_ENABLE_TERMIOS
80
- }
81
- return false ;
56
+ assert (FileDescriptorIsValid ());
57
+ assert (IsATerminal ());
58
+
59
+ if (::tcsetattr (m_fd, TCSANOW, &data.m_termios ) != 0 )
60
+ return llvm::createStringError (
61
+ std::error_code (errno, std::generic_category ()),
62
+ " unable to set teletype attributes" );
63
+ return llvm::Error::success ();
64
+ #else // !LLDB_ENABLE_TERMIOS
65
+ llvm_unreachable (" SetData() should not be called if !LLDB_ENABLE_TERMIOS" );
66
+ #endif // LLDB_ENABLE_TERMIOS
82
67
}
83
68
84
- struct TerminalState ::Data {
69
+ llvm::Error Terminal::SetEcho (bool enabled) {
70
+ llvm::Expected<Data> data = GetData ();
71
+ if (!data)
72
+ return data.takeError ();
73
+
85
74
#if LLDB_ENABLE_TERMIOS
86
- struct termios m_termios; // /< Cached terminal state information.
87
- #endif
88
- };
75
+ struct termios &fd_termios = data->m_termios ;
76
+ fd_termios.c_lflag &= ~ECHO;
77
+ if (enabled)
78
+ fd_termios.c_lflag |= ECHO;
79
+ return SetData (data.get ());
80
+ #endif // LLDB_ENABLE_TERMIOS
81
+ }
82
+
83
+ llvm::Error Terminal::SetCanonical (bool enabled) {
84
+ llvm::Expected<Data> data = GetData ();
85
+ if (!data)
86
+ return data.takeError ();
87
+
88
+ #if LLDB_ENABLE_TERMIOS
89
+ struct termios &fd_termios = data->m_termios ;
90
+ fd_termios.c_lflag &= ~ICANON;
91
+ if (enabled)
92
+ fd_termios.c_lflag |= ICANON;
93
+ return SetData (data.get ());
94
+ #endif // LLDB_ENABLE_TERMIOS
95
+ }
89
96
90
97
TerminalState::TerminalState (Terminal term, bool save_process_group)
91
98
: m_tty(term) {
@@ -109,7 +116,7 @@ bool TerminalState::Save(Terminal term, bool save_process_group) {
109
116
#if LLDB_ENABLE_POSIX
110
117
m_tflags = ::fcntl (fd, F_GETFL, 0 );
111
118
#if LLDB_ENABLE_TERMIOS
112
- std::unique_ptr<Data> new_data{new Data ()};
119
+ std::unique_ptr<Terminal:: Data> new_data{new Terminal:: Data ()};
113
120
if (::tcgetattr (fd, &new_data->m_termios ) == 0 )
114
121
m_data = std::move (new_data);
115
122
#endif // LLDB_ENABLE_TERMIOS
0 commit comments