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 /// Returns whether the ConPTY and its pipes are currently open and valid.
73 bool IsConnected() const;
74
75 /// The ConPTY HPCON handle accessor.
76 ///
77 /// This object retains ownership of the HPCON when this accessor is used.
78 ///
79 /// \return
80 /// The ConPTY HPCON handle, or INVALID_HANDLE_VALUE if it is currently
81 /// invalid.
83
84 /// The STDOUT read HANDLE accessor.
85 ///
86 /// This object retains ownership of the HANDLE when this accessor is used.
87 ///
88 /// \return
89 /// The STDOUT read HANDLE, or INVALID_HANDLE_VALUE if it is currently
90 /// invalid.
92
93 /// The STDIN write HANDLE accessor.
94 ///
95 /// This object retains ownership of the HANDLE when this accessor is used.
96 ///
97 /// \return
98 /// The STDIN write HANDLE, or INVALID_HANDLE_VALUE if it is currently
99 /// invalid.
101
102 /// The child-side stdin read HANDLE (pipe mode only).
104
105 /// The child-side stdout/stderr write HANDLE (pipe mode only).
107
108 Mode GetMode() const { return m_mode; };
109
110 /// Returns a reference to the mutex used to synchronize access to the
111 /// ConPTY state.
112 std::mutex &GetMutex() { return m_mutex; };
113
114 /// Returns a reference to the condition variable used to signal state changes
115 /// to threads waiting on the ConPTY (e.g. waiting for output or shutdown).
116 std::condition_variable &GetCV() { return m_cv; };
117
118 /// Returns whether the ConPTY is in the process of shutting down.
119 ///
120 /// \return
121 /// A reference to the atomic bool that is set to true when the ConPTY
122 /// is stopping. Callers should check this in their read/write loops to
123 /// exit gracefully.
124 bool IsStopping() const { return m_stopping.load(); };
125
126 /// Sets the stopping flag to \p value, signalling to threads waiting on the
127 /// ConPTY that they should stop.
128 void SetStopping(bool value) { m_stopping = value; };
129
130protected:
131 HANDLE m_conpty_handle = ((HANDLE)(long long)-1);
132 HANDLE m_conpty_output = ((HANDLE)(long long)-1);
133 HANDLE m_conpty_input = ((HANDLE)(long long)-1);
134 // Pipe mode: child-side handles passed to CreateProcessW, closed after launch
135 HANDLE m_pipe_child_stdin = ((HANDLE)(long long)-1);
138 std::mutex m_mutex{};
139 std::condition_variable m_cv{};
140 std::atomic<bool> m_stopping = false;
141};
142} // namespace lldb_private
143
144#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 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.