LLDB mainline
PseudoConsole.h
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#ifndef LIBLLDB_HOST_WINDOWS_PSEUDOCONSOLE_H_
10#define LIBLLDB_HOST_WINDOWS_PSEUDOCONSOLE_H_
11
12#include "llvm/Support/Error.h"
13#include <atomic>
14#include <condition_variable>
15#include <mutex>
16#include <string>
17
18#define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x20016
19typedef void *HANDLE;
20typedef void *HPCON;
21
22namespace lldb_private {
23
25
26public:
27 enum class Mode { ConPTY, Pipe, None };
28
29 PseudoConsole() = default;
31
32 PseudoConsole(const PseudoConsole &) = delete;
36
37 /// Creates a named pipe pair for overlapped I/O.
38 /// On failure any handles that were successfully opened are closed and an
39 /// error is returned.
40 llvm::Error CreateOverlappedPipePair(HANDLE &out_read, HANDLE &out_write,
41 bool inheritable);
42
43 /// Creates and opens a new ConPTY instance with a default console size of
44 /// 80x25. Also sets up the associated STDIN/STDOUT pipes and responds to
45 /// the cursor-position query that ConPTY emits at startup.
46 ///
47 /// \param req_cols, req_rows Optional terminal dimensions.
48 ///
49 /// \return
50 /// An llvm::Error if the ConPTY could not be created, or if ConPTY is
51 /// not available on this version of Windows, llvm::Error::success()
52 /// otherwise.
53 llvm::Error OpenPseudoConsole(uint16_t req_cols = 0, uint16_t req_rows = 0);
54
55 /// Creates a pair of anonymous pipes to use for stdio instead of a ConPTY.
56 ///
57 /// \return
58 /// An llvm::Error if the pipes could not be created.
59 llvm::Error OpenAnonymousPipes();
60
61 /// Closes the ConPTY and invalidates its handle, without closing the STDIN
62 /// and STDOUT pipes. Closing the ConPTY signals EOF to any process currently
63 /// attached to it.
64 void Close();
65
66 /// Closes the STDIN and STDOUT pipe handles and invalidates them.
68
69 /// Closes the child-side pipe handles (stdin read end and stdout/stderr write
70 /// end) that were passed to CreateProcessW. Must be called after a successful
71 /// CreateProcessW to avoid keeping the pipes alive indefinitely.
73
74 /// Closes any open ConPTY/pipe handles and resets internal state to a
75 /// freshly-constructed PseudoConsole.
76 void Reset();
77
78 /// Returns whether the ConPTY and its pipes are currently open and valid.
79 bool IsConnected() const;
80
81 /// The ConPTY HPCON handle accessor.
82 ///
83 /// This object retains ownership of the HPCON when this accessor is used.
84 ///
85 /// \return
86 /// The ConPTY HPCON handle, or INVALID_HANDLE_VALUE if it is currently
87 /// invalid.
89
90 /// The STDOUT read HANDLE accessor.
91 ///
92 /// This object retains ownership of the HANDLE when this accessor is used.
93 ///
94 /// \return
95 /// The STDOUT read HANDLE, or INVALID_HANDLE_VALUE if it is currently
96 /// invalid.
98
99 /// The STDIN write HANDLE accessor.
100 ///
101 /// This object retains ownership of the HANDLE when this accessor is used.
102 ///
103 /// \return
104 /// The STDIN write HANDLE, or INVALID_HANDLE_VALUE if it is currently
105 /// invalid.
107
108 /// The child-side stdin read HANDLE (pipe mode only).
110
111 /// The child-side stdout/stderr write HANDLE (pipe mode only).
113
114 Mode GetMode() const { return m_mode; };
115
116 /// Returns a reference to the mutex used to synchronize access to the
117 /// ConPTY state.
118 std::mutex &GetMutex() { return m_mutex; };
119
120 /// Returns a reference to the condition variable used to signal state changes
121 /// to threads waiting on the ConPTY (e.g. waiting for output or shutdown).
122 std::condition_variable &GetCV() { return m_cv; };
123
124 /// Returns whether the ConPTY is in the process of shutting down.
125 ///
126 /// \return
127 /// A reference to the atomic bool that is set to true when the ConPTY
128 /// is stopping. Callers should check this in their read/write loops to
129 /// exit gracefully.
130 bool IsStopping() const { return m_stopping.load(); };
131
132 /// Sets the stopping flag to \p value, signalling to threads waiting on the
133 /// ConPTY that they should stop.
134 void SetStopping(bool value) { m_stopping = value; };
135
136protected:
137 HANDLE m_conpty_handle = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
138 HANDLE m_conpty_output = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
139 HANDLE m_conpty_input = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
140 // Pipe mode: child-side handles passed to CreateProcessW, closed after launch
142 reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
144 reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
146 std::mutex m_mutex{};
147 std::condition_variable m_cv{};
148 std::atomic<bool> m_stopping = false;
149};
150} // namespace lldb_private
151
152#endif // LIBLLDB_HOST_WINDOWS_PSEUDOCONSOLE_H_
void * HPCON
void * HANDLE
PseudoConsole(const PseudoConsole &)=delete
PseudoConsole & operator=(const PseudoConsole &)=delete
bool IsStopping() const
Returns whether the ConPTY is in the process of shutting down.
std::condition_variable & GetCV()
Returns a reference to the condition variable used to signal state changes to threads waiting on the ...
std::atomic< bool > m_stopping
llvm::Error CreateOverlappedPipePair(HANDLE &out_read, HANDLE &out_write, bool inheritable)
Creates a named pipe pair for overlapped I/O.
std::condition_variable m_cv
llvm::Error OpenPseudoConsole(uint16_t req_cols=0, uint16_t req_rows=0)
Creates and opens a new ConPTY instance with a default console size of 80x25.
std::mutex & GetMutex()
Returns a reference to the mutex used to synchronize access to the ConPTY state.
llvm::Error OpenAnonymousPipes()
Creates a pair of anonymous pipes to use for stdio instead of a ConPTY.
void SetStopping(bool value)
Sets the stopping flag to value, signalling to threads waiting on the ConPTY that they should stop.
PseudoConsole & operator=(PseudoConsole &&)=delete
HANDLE GetSTDOUTHandle() const
The STDOUT read HANDLE accessor.
HANDLE GetChildStdinHandle() const
The child-side stdin read HANDLE (pipe mode only).
void Close()
Closes the ConPTY and invalidates its handle, without closing the STDIN and STDOUT pipes.
void Reset()
Closes any open ConPTY/pipe handles and resets internal state to a freshly-constructed PseudoConsole.
void ClosePseudoConsolePipes()
Closes the STDIN and STDOUT pipe handles and invalidates them.
HANDLE GetChildStdoutHandle() const
The child-side stdout/stderr write HANDLE (pipe mode only).
bool IsConnected() const
Returns whether the ConPTY and its pipes are currently open and valid.
void CloseAnonymousPipes()
Closes the child-side pipe handles (stdin read end and stdout/stderr write end) that were passed to C...
HPCON GetPseudoTerminalHandle()
The ConPTY HPCON handle accessor.
PseudoConsole(PseudoConsole &&)=delete
HANDLE GetSTDINHandle() const
The STDIN write HANDLE accessor.
A class that represents a running process on the host machine.