Skip to content

Commit dded044

Browse files
committed
Set errno for popen and pclose for WIN32 just like POSIX does
(at least mingw64+wine seems to decode the error message without doing anything extra)
1 parent e4ce497 commit dded044

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

source/matplot/util/popen.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,21 @@ namespace matplot::detail {
2020

2121
// Create a pipe for the child process's input
2222
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
23+
errno = GetLastError(); // emulate POSIX behavior
2324
return nullptr;
2425
}
2526

2627
// Ensure the write handle to the pipe is not inherited by child
2728
// processes
2829
if (!SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0)) {
30+
errno = GetLastError(); // emulate POSIX behavior
2931
CloseHandle(hChildStdinRd);
3032
return nullptr;
3133
}
3234

3335
// Create a pipe for the child process's output
3436
if (!CreatePipe(&hStdin, &hStdout, &saAttr, 0)) {
37+
errno = GetLastError(); // emulate POSIX behavior
3538
CloseHandle(hChildStdinRd);
3639
CloseHandle(hChildStdinWr);
3740
return nullptr;
@@ -40,6 +43,7 @@ namespace matplot::detail {
4043
// Ensure the read handle to the output pipe is not inherited by child
4144
// processes
4245
if (!SetHandleInformation(hStdout, HANDLE_FLAG_INHERIT, 0)) {
46+
errno = GetLastError(); // emulate POSIX behavior
4347
CloseHandle(hChildStdinRd);
4448
CloseHandle(hChildStdinWr);
4549
CloseHandle(hStdin);
@@ -57,6 +61,7 @@ namespace matplot::detail {
5761
// Create the child process, while hiding the window
5862
if (!CreateProcess(NULL, const_cast<char *>(command), NULL, NULL, TRUE,
5963
CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
64+
errno = GetLastError(); // emulate POSIX behavior
6065
CloseHandle(hChildStdinRd);
6166
CloseHandle(hChildStdinWr);
6267
CloseHandle(hStdin);
@@ -73,6 +78,7 @@ namespace matplot::detail {
7378
FILE *file = _fdopen(_open_osfhandle((intptr_t)hChildStdinWr, 0), mode);
7479

7580
if (file == nullptr) {
81+
errno = GetLastError(); // emulate POSIX behavior
7682
CloseHandle(hChildStdinWr);
7783
CloseHandle(hStdin);
7884
CloseHandle(pi.hProcess);
@@ -87,16 +93,19 @@ namespace matplot::detail {
8793
int hiddenPclose(FILE *file) {
8894
HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
8995
fclose(file);
96+
// Wait for the process to finish
97+
if (auto r = WaitForSingleObject(hFile, INFINITE); r != WAIT_OBJECT_0) {
98+
errno = ECHILD; // emulate POSIX behavior
99+
return -1;
100+
}
101+
// Retrieve the exit code
90102
DWORD exitCode;
91-
92-
// Wait for the process to finish and get its exit code
93-
if (WaitForSingleObject(hFile, INFINITE) == WAIT_OBJECT_0 &&
94-
GetExitCodeProcess(hFile, &exitCode)) {
95-
CloseHandle(hFile);
96-
return exitCode;
97-
} else {
98-
return -1; // Failed to get the exit code
103+
if (auto r = GetExitCodeProcess(hFile, &exitCode); r == 0) {
104+
errno = ECHILD; // emulate POSIX behavior
105+
return -1;
99106
}
107+
CloseHandle(hFile);
108+
return exitCode;
100109
}
101110
} // namespace matplot::detail
102111
#endif // _WIN32

0 commit comments

Comments
 (0)