PIProcess windows works

This commit is contained in:
2025-08-13 21:36:13 +03:00
parent 3625afa783
commit d6a0ae6106
2 changed files with 50 additions and 22 deletions

View File

@@ -23,6 +23,7 @@
# include "piincludes_p.h"
# include "piliterals_bytes.h"
# include "piprocess.h"
# include "pitranslator.h"
# ifndef WINDOWS
# include <csignal>
# include <sys/wait.h>
@@ -89,13 +90,12 @@ using PipeHandleType = int;
# endif
# ifdef WINDOWS
const char * convertWindowsCmd(PIStringList sl) {
for (int i = 0; i < sl.size_s(); ++i) {
sl[i].push_front('"');
sl[i].push_back('"');
PIString convertWindowsCmd(PIStringList sl) {
if (sl.isNotEmpty()) {
sl[0].replaceAll('/', '\\');
sl[0].quote();
}
PIString s = sl.join(' ');
return s.data();
return sl.join(' ');
}
# else
char * const * convertToCharArrays(const PIStringList & sl) {
@@ -144,7 +144,7 @@ PRIVATE_DEFINITION_START(PIProcess)
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
satrueAttr.lpSecurityDescriptor = NULL;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&(pipes[pt][PipeRead]), &(pipes[pt][PipeWrite]), &saAttr, 0)) return false;
return true;
# else
@@ -167,6 +167,11 @@ PRIVATE_DEFINITION_START(PIProcess)
}
}
}
# ifdef WINDOWS
if (grab[StdIn]) SetHandleInformation(pipes[StdIn][PipeWrite], HANDLE_FLAG_INHERIT, 0);
if (grab[StdOut]) SetHandleInformation(pipes[StdOut][PipeRead], HANDLE_FLAG_INHERIT, 0);
if (grab[StdErr]) SetHandleInformation(pipes[StdErr][PipeRead], HANDLE_FLAG_INHERIT, 0);
# endif
return true;
}
@@ -178,7 +183,7 @@ PRIVATE_DEFINITION_START(PIProcess)
void closePipe(PipeHandleType & hpipe) {
# ifdef WINDOWS
if (hpipe] != 0) {
if (hpipe != 0) {
CloseHandle(hpipe);
hpipe = 0;
}
@@ -205,12 +210,24 @@ PRIVATE_DEFINITION_START(PIProcess)
size_t offset = 0;
while (1) {
# ifdef WINDOWS
BOOL ok = ReadFile(pipes[pipe_type][PipeRead], read_buffer.data(offset), read_buffer.size() - offset, &bytes_read, NULL);
DWORD available = 0;
BOOL ok = PeekNamedPipe(pipes[pipe_type][PipeRead], nullptr, 0, nullptr, &available, nullptr);
// piCout << "ReadFile" << available;
if (available == 0) {
read_buffer.resize(offset);
break;
}
ok = ReadFile(pipes[pipe_type][PipeRead],
read_buffer.data(offset),
piMini(available, read_buffer.size() - offset),
&bytes_read,
nullptr);
// piCout << "ReadFile" << ok;
if (!ok) bytes_read = 0;
# else
bytes_read = ::read(pipes[pipe_type][PipeRead], read_buffer.data(offset), read_buffer.size() - offset);
# endif
piCout << "readed" << bytes_read;
// piCout << "readed" << bytes_read;
if (bytes_read > 0) {
offset += bytes_read;
read_buffer.resize(offset + read_buffer_size);
@@ -219,7 +236,7 @@ PRIVATE_DEFINITION_START(PIProcess)
break;
}
}
piCout << "readPipe" << read_buffer.toHex();
// piCout << "readPipe" << PIString::fromConsole(read_buffer);
return read_buffer;
}
@@ -232,7 +249,7 @@ PRIVATE_DEFINITION_START(PIProcess)
# else
sz = ::write(pipes[StdIn][PipeWrite], data.data(), data.size());
# endif
piCout << "writePipe" << sz;
// piCout << "writePipe" << sz;
return sz == data.size_s();
}
@@ -274,23 +291,26 @@ void PIProcess::startProc(bool detached) {
if (!PRIVATE->createPipes()) return;
# ifdef WINDOWS
STARTUPINFOA si;
piZeroMemory(pi);
piZeroMemory(si);
si.cb = sizeof(STARTUPINFOA);
if (PRIVATE->grab[StdIn]) si.hStdInput = PRIVATE->pipes[StdIn][PipeRead];
if (PRIVATE->grab[StdOut]) si.hStdOutput = PRIVATE->pipes[StdOut][PipeWrite];
if (PRIVATE->grab[StdErr]) si.hStdError = PRIVATE->pipes[StdErr][PipeWrite];
si.dwFlags |= STARTF_USESTDHANDLES;
const auto cmd = convertWindowsCmd(args);
// piCout << cmd;
if (CreateProcessA(0, // No module name (use command line)
convertWindowsCmd(args), // Command line
(LPSTR)cmd.data(), // Command line
0, // Process handle not inheritable
0, // Thread handle not inheritable
false, // Set handle inheritance to FALSE
true, // Set handle inheritance to FALSE
detached ? DETACHED_PROCESS /*CREATE_NEW_CONSOLE*/ : 0, // Creation flags
0, // Use environment
wd.isEmpty() ? 0 : wd.data(), // Use working directory
&si, // Pointer to STARTUPINFO structure
&(PRIVATE->pi))) // Pointer to PROCESS_INFORMATION structure
{
// piCout << "started";
exec_start = true;
if (!detached) {
WaitForSingleObject(PRIVATE->pi.hProcess, INFINITE);
@@ -397,7 +417,12 @@ bool PIProcess::writeInput(const PIByteArray & data) {
void PIProcess::closeInput() {
if (PRIVATE->grab[StdIn]) PRIVATE->closePipe(StdIn, PipeWrite);
if (PRIVATE->grab[StdIn]) {
# ifdef WINDOWS
// PRIVATE->writePipe({0x1A});
# endif
PRIVATE->closePipe(StdIn, PipeWrite);
}
}

View File

@@ -9,7 +9,7 @@ protected:
PIProcess launcher;
const PIString command =
#ifdef _WIN32
"cmd.exe";
"C:/Windows/System32/cmd.exe";
#else
"/bin/sh";
#endif
@@ -61,7 +61,7 @@ TEST_F(ProcessTest, Output) {
TEST_F(ProcessTest, Input) {
#ifdef _WIN32
const PIStringList args = {"/c", "set /p input= && echo %input%"};
const PIStringList args = {"/c", "more"};
#else
const PIStringList args = {"-c", "read input; echo $input"};
#endif
@@ -73,7 +73,10 @@ TEST_F(ProcessTest, Input) {
EXPECT_TRUE(launcher.isExecStarted());
EXPECT_TRUE(!launcher.isExecFinished());
const PIString test_input = "Test input string\n";
PIString test_input = "Test input string\n";
#ifdef WINDOWS
test_input += (char)0x1A;
#endif
EXPECT_TRUE(launcher.writeInput(test_input.toAscii()));
launcher.closeInput();
@@ -91,5 +94,5 @@ TEST_F(ProcessTest, NonexistentCommand) {
launcher.exec(command);
ASSERT_TRUE(launcher.isRunning());
ASSERT_TRUE(launcher.waitForFinish());
EXPECT_FALSE(!launcher.isExecFinished());
EXPECT_FALSE(launcher.isExecFinished());
}