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 <mutex>
15#include <string>
16
17#define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x20016
18typedef void *HANDLE;
19typedef void *HPCON;
20
21namespace lldb_private {
22
24
25public:
26 enum class Mode { ConPTY, Pipe, None };
27
28 PseudoConsole() = default;
30
31 PseudoConsole(const PseudoConsole &) = delete;
35
36 /// Creates a named pipe pair for overlapped I/O.
37 /// On failure any handles that were successfully opened are closed and an
38 /// error is returned.
39 llvm::Error CreateOverlappedPipePair(HANDLE &out_read, HANDLE &out_write,
40 bool inheritable);
41
42 /// Creates and opens a new ConPTY instance with a default console size of
43 /// 80x25. Also sets up the associated STDIN/STDOUT pipes and responds to
44 /// the cursor-position query that ConPTY emits at startup.
45 ///
46 /// \param req_cols, req_rows Optional terminal dimensions.
47 ///
48 /// \return
49 /// An llvm::Error if the ConPTY could not be created, or if ConPTY is
50 /// not available on this version of Windows, llvm::Error::success()
51 /// otherwise.
52 llvm::Error OpenPseudoConsole(uint16_t req_cols = 0, uint16_t req_rows = 0);
53
54 /// Creates a pair of anonymous pipes to use for stdio instead of a ConPTY.
55 ///
56 /// \return
57 /// An llvm::Error if the pipes could not be created.
58 llvm::Error OpenAnonymousPipes();
59
60 /// Closes the ConPTY and invalidates its handle, without closing the STDIN
61 /// and STDOUT pipes. Closing the ConPTY signals EOF to any process currently
62 /// attached to it. The console host then writes its last frame to the STDOUT
63 /// pipe and closes its end, so reading the pipe up to EOF gets all of the
64 /// output.
65 ///
66 /// In pipe mode there is no ConPTY to close: this cancels the read pending
67 /// on the STDOUT pipe and marks the pipes closed, so IsConnected() returns
68 /// false from then on, as it does once a ConPTY is closed.
69 void Close();
70
71 /// Closes the STDIN and STDOUT pipe handles and invalidates them.
73
74 /// Closes the child-side pipe handles (stdin read end and stdout/stderr write
75 /// end) that were passed to CreateProcessW. Must be called after a successful
76 /// CreateProcessW to avoid keeping the pipes alive indefinitely.
78
79 /// Closes any open ConPTY/pipe handles and resets internal state to a
80 /// freshly-constructed PseudoConsole.
81 void Reset();
82
83 /// Returns whether the ConPTY and its pipes are currently open and valid.
84 bool IsConnected() const;
85
86 /// The ConPTY HPCON handle accessor.
87 ///
88 /// This object retains ownership of the HPCON when this accessor is used.
89 ///
90 /// \return
91 /// The ConPTY HPCON handle, or INVALID_HANDLE_VALUE if it is currently
92 /// invalid.
94
95 /// The STDOUT read HANDLE accessor.
96 ///
97 /// This object retains ownership of the HANDLE when this accessor is used.
98 ///
99 /// \return
100 /// The STDOUT read HANDLE, or INVALID_HANDLE_VALUE if it is currently
101 /// invalid.
103
104 /// The STDIN write HANDLE accessor.
105 ///
106 /// This object retains ownership of the HANDLE when this accessor is used.
107 ///
108 /// \return
109 /// The STDIN write HANDLE, or INVALID_HANDLE_VALUE if it is currently
110 /// invalid.
112
113 /// The child-side stdin read HANDLE (pipe mode only).
115
116 /// The child-side stdout/stderr write HANDLE (pipe mode only).
118
119 Mode GetMode() const { return m_mode; };
120
121protected:
122 HANDLE m_conpty_handle = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
123 HANDLE m_conpty_output = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
124 HANDLE m_conpty_input = reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
125 // Pipe mode: child-side handles passed to CreateProcessW, closed after launch
127 reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
129 reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1));
130 // Pipe mode: set by Close(). Its CancelIoEx only reaches a read that is
131 // already pending, so a reader has to be able to tell that the pipes were
132 // closed before it starts the next one.
133 std::atomic<bool> m_pipes_closed = false;
135 std::mutex m_mutex{};
136};
137} // namespace lldb_private
138
139#endif // LIBLLDB_HOST_WINDOWS_PSEUDOCONSOLE_H_
void * HPCON
void * HANDLE
PseudoConsole(const PseudoConsole &)=delete
PseudoConsole & operator=(const PseudoConsole &)=delete
llvm::Error CreateOverlappedPipePair(HANDLE &out_read, HANDLE &out_write, bool inheritable)
Creates a named pipe pair for overlapped I/O.
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.
llvm::Error OpenAnonymousPipes()
Creates a pair of anonymous pipes to use for stdio instead of a ConPTY.
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...
std::atomic< bool > m_pipes_closed
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.