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 /// \return
48 /// An llvm::Error if the ConPTY could not be created, or if ConPTY is
49 /// not available on this version of Windows, llvm::Error::success()
50 /// otherwise.
51 llvm::Error OpenPseudoConsole();
52
53 /// Creates a pair of anonymous pipes to use for stdio instead of a ConPTY.
54 ///
55 /// \return
56 /// An llvm::Error if the pipes could not be created.
57 llvm::Error OpenAnonymousPipes();
58
59 /// Closes the ConPTY and invalidates its handle, without closing the STDIN
60 /// and STDOUT pipes. Closing the ConPTY signals EOF to any process currently
61 /// attached to it.
62 void Close();
63
64 /// Closes the STDIN and STDOUT pipe handles and invalidates them.
66
67 /// Closes the child-side pipe handles (stdin read end and stdout/stderr write
68 /// end) that were passed to CreateProcessW. Must be called after a successful
69 /// CreateProcessW to avoid keeping the pipes alive indefinitely.
71
72 /// Closes any open ConPTY/pipe handles and resets internal state to a
73 /// freshly-constructed PseudoConsole.
74 void Reset();
75
76 /// Returns whether the ConPTY and its pipes are currently open and valid.
77 bool IsConnected() const;
78
79 /// The ConPTY HPCON handle accessor.
80 ///
81 /// This object retains ownership of the HPCON when this accessor is used.
82 ///
83 /// \return
84 /// The ConPTY HPCON handle, or INVALID_HANDLE_VALUE if it is currently
85 /// invalid.
87
88 /// The STDOUT read HANDLE accessor.
89 ///
90 /// This object retains ownership of the HANDLE when this accessor is used.
91 ///
92 /// \return
93 /// The STDOUT read HANDLE, or INVALID_HANDLE_VALUE if it is currently
94 /// invalid.
96
97 /// The STDIN write HANDLE accessor.
98 ///
99 /// This object retains ownership of the HANDLE when this accessor is used.
100 ///
101 /// \return
102 /// The STDIN write HANDLE, or INVALID_HANDLE_VALUE if it is currently
103 /// invalid.
105
106 /// The child-side stdin read HANDLE (pipe mode only).
108
109 /// The child-side stdout/stderr write HANDLE (pipe mode only).
111
112 Mode GetMode() const { return m_mode; };
113
114 /// Returns a reference to the mutex used to synchronize access to the
115 /// ConPTY state.
116 std::mutex &GetMutex() { return m_mutex; };
117
118 /// Returns a reference to the condition variable used to signal state changes
119 /// to threads waiting on the ConPTY (e.g. waiting for output or shutdown).
120 std::condition_variable &GetCV() { return m_cv; };
121
122 /// Returns whether the ConPTY is in the process of shutting down.
123 ///
124 /// \return
125 /// A reference to the atomic bool that is set to true when the ConPTY
126 /// is stopping. Callers should check this in their read/write loops to
127 /// exit gracefully.
128 bool IsStopping() const { return m_stopping.load(); };
129
130 /// Sets the stopping flag to \p value, signalling to threads waiting on the
131 /// ConPTY that they should stop.
132 void SetStopping(bool value) { m_stopping = value; };
133
134protected:
135 HANDLE m_conpty_handle = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
136 HANDLE m_conpty_output = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
137 HANDLE m_conpty_input = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
138 // Pipe mode: child-side handles passed to CreateProcessW, closed after launch
140 reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
142 reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
144 std::mutex m_mutex{};
145 std::condition_variable m_cv{};
146 std::atomic<bool> m_stopping = false;
147};
148} // namespace lldb_private
149
150#endif // LIBLLDB_HOST_WINDOWS_PSEUDOCONSOLE_H_
void * HPCON
void * HANDLE
PseudoConsole(const PseudoConsole &)=delete
PseudoConsole & operator=(const PseudoConsole &)=delete
llvm::Error OpenPseudoConsole()
Creates and opens a new ConPTY instance with a default console size of 80x25.
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
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.