1 #ifndef PROCESSWINHELPER_H
2 #define PROCESSWINHELPER_H
6 #error Must include <windows.h> before this file.
12 inline bool IS_VALID_HANDLE(HANDLE h)
14 return h && h != INVALID_HANDLE_VALUE;
17 inline bool IS_VALID_HANDLE(PROCESS_INFORMATION
const &h)
19 return IS_VALID_HANDLE(h.hProcess) || IS_VALID_HANDLE(h.hThread);
22 inline bool write_all(HANDLE handle,
char const *data,
size_t size)
24 if (!IS_VALID_HANDLE(handle) || (!data && size != 0)) {
30 DWORD chunk = size > MAXDWORD ? MAXDWORD :
static_cast<DWORD
>(size);
31 if (!WriteFile(handle, data, chunk, &written,
nullptr) || written == 0) {
43 if (str.empty())
return wstr;
44 int len = MultiByteToWideChar(CP_UTF8, 0, str.data(), (
int)str.size(),
nullptr, 0);
47 MultiByteToWideChar(CP_UTF8, 0, str.data(), (
int)str.size(), &wstr[0], len);
55 if (str.empty())
return s;
56 int len = WideCharToMultiByte(CP_UTF8, 0, str.data(), (
int)str.size(),
nullptr, 0,
nullptr,
nullptr);
59 WideCharToMultiByte(CP_UTF8, 0, str.data(), (
int)str.size(), &s[0], len,
nullptr,
nullptr);
64 inline std::string_view
getProgram(std::string_view cmdline)
66 char const *begin = cmdline.data();
67 char const *end = begin + cmdline.size();
68 char const *ptr = begin;
82 }
else if (quote && c != 0) {
84 }
else if (isspace((
unsigned char)c) || c == 0) {
90 char const *left = begin;
91 char const *right = ptr;
92 if (left + 1 < right) {
93 if (left[0] ==
'\"' && right[-1] ==
'\"') {
98 return std::string_view(left, right - left);
101 template <
typename HANDLE>
class AbstractAutoHandle {
106 virtual void close_handle(HANDLE &h) = 0;
109 AbstractAutoHandle() =
default;
110 AbstractAutoHandle(HANDLE h)
114 AbstractAutoHandle(AbstractAutoHandle
const &) =
delete;
115 AbstractAutoHandle &operator=(AbstractAutoHandle
const &) =
delete;
116 AbstractAutoHandle(AbstractAutoHandle &&r) noexcept
120 AbstractAutoHandle &operator=(AbstractAutoHandle &&r) noexcept
122 if (
this != std::addressof(r)) {
128 virtual ~AbstractAutoHandle()
141 if (IS_VALID_HANDLE(h)) {
154 HANDLE &operator=(HANDLE h)
156 if (h_ == h)
return h_;
167 class AutoHandle :
public AbstractAutoHandle<HANDLE> {
169 void close_handle(HANDLE &h)
176 using AbstractAutoHandle<HANDLE>::AbstractAutoHandle;
177 using AbstractAutoHandle<HANDLE>::operator=;
180 class AutoProcessInformation :
public AbstractAutoHandle<PROCESS_INFORMATION> {
182 PROCESS_INFORMATION pi = { };
185 void close_handle(PROCESS_INFORMATION &pi)
187 if (IS_VALID_HANDLE(pi.hProcess)) {
188 CloseHandle(pi.hProcess);
190 if (IS_VALID_HANDLE(pi.hThread)) {
191 CloseHandle(pi.hThread);
197 using AbstractAutoHandle<PROCESS_INFORMATION>::AbstractAutoHandle;
198 using AbstractAutoHandle<PROCESS_INFORMATION>::operator=;
201 class AutoPseudoConsole {
206 AutoPseudoConsole() =
default;
207 AutoPseudoConsole(AutoPseudoConsole
const &) =
delete;
208 AutoPseudoConsole &operator=(AutoPseudoConsole
const &) =
delete;
209 AutoPseudoConsole(AutoPseudoConsole &&r) noexcept
214 AutoPseudoConsole &operator=(AutoPseudoConsole &&r) noexcept
216 if (
this != std::addressof(r)) {
229 if (IS_VALID_HANDLE(hPC)) {
230 ClosePseudoConsole(hPC);
247 std::string
append(std::string_view input)
250 for (
unsigned char c : input) {
254 state_ = State::Escape;
256 output.push_back(
static_cast<char>(c));
263 }
else if (c ==
']') {
265 }
else if (c ==
'P' || c ==
'X' || c ==
'^' || c ==
'_') {
267 }
else if (c >= 0x20 && c <= 0x2f) {
268 state_ = State::EscapeIntermediate;
269 }
else if (c == 0x1b) {
270 state_ = State::Escape;
272 state_ = State::Text;
276 case State::EscapeIntermediate:
277 if (c >= 0x30 && c <= 0x7e) {
278 state_ = State::Text;
279 }
else if (c == 0x1b) {
280 state_ = State::Escape;
285 if (c >= 0x40 && c <= 0x7e) {
286 state_ = State::Text;
287 }
else if (c == 0x1b) {
288 state_ = State::Escape;
294 state_ = State::Text;
295 }
else if (c == 0x1b) {
296 state_ = State::OscEscape;
300 case State::OscEscape:
302 state_ = State::Text;
303 }
else if (c != 0x1b) {
310 state_ = State::StringEscape;
314 case State::StringEscape:
316 state_ = State::Text;
317 }
else if (c != 0x1b) {
338 State state_ = State::Text;
@ String
Definition: jstream.h:399
static void append(std::vector< char > *out, char const *ptr, size_t len)
Definition: misc.h:174
std::u16string convert_str_to_wstr(std::string_view const &str)
Definition: wstring.cpp:41
std::string convert_wstr_to_str(std::u16string_view const &str)
Definition: wstring.cpp:118
std::string_view getProgram(std::string_view cmdline)
Definition: misc.cpp:777