mirror of
https://github.com/arun11299/cpp-subprocess.git
synced 2025-09-17 11:15:03 -04:00
Fix(windows): Resolve header conflicts and update tests (#123)
* Refactor: Isolate WinAPI declarations. This commit replaces the direct inclusion of `<windows.h>` with a minimal set of manual forward declarations. This is a deliberate architectural change to: - **Improve Compilation Speed:** Avoids parsing the notoriously large Windows header. - **Eliminate Naming Pollution:** Prevents name clashes with common names like `min`/`max` which conflict with the C++ standard library. - **Enhance Encapsulation:** Makes the library more self-contained by not exposing the entire Windows API. * fix(windows): Resolve header conflicts and update tests Previously, including both `subprocess.hpp` and `<Windows.h>` in the same file would cause compilation errors due to redefinitions of Windows API types and functions. This commit resolves these conflicts by wrapping the manual API declarations in `subprocess.hpp` with an `#ifndef _WINDEF_` guard. This ensures the library's lightweight declarations are only used if the official Windows headers haven't been included, making it safe to use both. The `test_ret_code.cc` unit test has been updated to include `<Windows.h>` directly for the `Sleep` function, which also serves to validate this fix. * fix(windows): Add platform-specific include for Windows.h Wraps the Windows.h include in a platform guard to prevent breaking non-Windows builds.
This commit is contained in:
parent
60d4ad8d52
commit
ad47657ddd
@ -74,6 +74,8 @@ extern "C" {
|
||||
|
||||
#ifdef __USING_WINDOWS__
|
||||
|
||||
#ifndef _WINDEF_
|
||||
|
||||
#define CONST const
|
||||
#define WINAPI __stdcall
|
||||
|
||||
@ -133,20 +135,24 @@ extern "C" {
|
||||
typedef WCHAR* LPWSTR;
|
||||
typedef CONST WCHAR* LPCWSTR;
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES {
|
||||
typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, * LPSECURITY_ATTRIBUTES;
|
||||
typedef struct _PROCESS_INFORMATION PROCESS_INFORMATION, * LPPROCESS_INFORMATION;
|
||||
typedef struct _STARTUPINFOW STARTUPINFOW, * LPSTARTUPINFOW;
|
||||
|
||||
typedef struct _SP_SECURITY_ATTRIBUTES {
|
||||
DWORD nLength;
|
||||
LPVOID lpSecurityDescriptor;
|
||||
BOOL bInheritHandle;
|
||||
} SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||
} SP_SECURITY_ATTRIBUTES, * SP_LPSECURITY_ATTRIBUTES;
|
||||
|
||||
typedef struct _PROCESS_INFORMATION {
|
||||
typedef struct _SP_PROCESS_INFORMATION {
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
DWORD dwProcessId;
|
||||
DWORD dwThreadId;
|
||||
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
|
||||
} SP_PROCESS_INFORMATION, * SP_LPPROCESS_INFORMATION;
|
||||
|
||||
typedef struct _STARTUPINFOW {
|
||||
typedef struct _SP_STARTUPINFOW {
|
||||
DWORD cb;
|
||||
LPWSTR lpReserved;
|
||||
LPWSTR lpDesktop;
|
||||
@ -165,24 +171,32 @@ extern "C" {
|
||||
HANDLE hStdInput;
|
||||
HANDLE hStdOutput;
|
||||
HANDLE hStdError;
|
||||
} STARTUPINFOW, * LPSTARTUPINFOW;
|
||||
} SP_STARTUPINFOW, * SP_LPSTARTUPINFOW;
|
||||
|
||||
BOOL WINAPI CloseHandle(HANDLE);
|
||||
BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);
|
||||
BOOL WINAPI CreateProcessW(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
|
||||
BOOL WINAPI FreeEnvironmentStringsW(LPWCH);
|
||||
BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD);
|
||||
BOOL WINAPI SetHandleInformation(HANDLE, DWORD, DWORD);
|
||||
BOOL WINAPI TerminateProcess(HANDLE, UINT);
|
||||
DWORD WINAPI FormatMessageA(DWORD, LPCVOID, DWORD, DWORD, LPSTR, DWORD, va_list*);
|
||||
DWORD WINAPI GetLastError(VOID);
|
||||
DWORD WINAPI WaitForSingleObject(HANDLE, DWORD);
|
||||
HLOCAL WINAPI LocalFree(HLOCAL);
|
||||
LPWSTR WINAPI GetEnvironmentStringsW(VOID);
|
||||
__declspec(dllimport) BOOL WINAPI CloseHandle(HANDLE);
|
||||
__declspec(dllimport) BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);
|
||||
__declspec(dllimport) BOOL WINAPI CreateProcessW(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
|
||||
__declspec(dllimport) BOOL WINAPI FreeEnvironmentStringsW(LPWCH);
|
||||
__declspec(dllimport) BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD);
|
||||
__declspec(dllimport) BOOL WINAPI SetHandleInformation(HANDLE, DWORD, DWORD);
|
||||
__declspec(dllimport) BOOL WINAPI TerminateProcess(HANDLE, UINT);
|
||||
__declspec(dllimport) DWORD WINAPI FormatMessageA(DWORD, LPCVOID, DWORD, DWORD, LPSTR, DWORD, va_list*);
|
||||
__declspec(dllimport) DWORD WINAPI GetLastError(VOID);
|
||||
__declspec(dllimport) DWORD WINAPI WaitForSingleObject(HANDLE, DWORD);
|
||||
__declspec(dllimport) HLOCAL WINAPI LocalFree(HLOCAL);
|
||||
__declspec(dllimport) LPWSTR WINAPI GetEnvironmentStringsW(VOID);
|
||||
|
||||
#define ZeroMemory(Destination,Length) memset((Destination),0,(Length))
|
||||
#define MAKELANGID(p, s) ((((WORD)(s)) << 10) | (WORD)(p))
|
||||
|
||||
#else
|
||||
|
||||
#define SP_SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
|
||||
#define SP_PROCESS_INFORMATION PROCESS_INFORMATION
|
||||
#define SP_STARTUPINFOW STARTUPINFOW
|
||||
|
||||
#endif
|
||||
|
||||
#include <io.h>
|
||||
#include <cwchar>
|
||||
#else
|
||||
@ -417,15 +431,15 @@ namespace util
|
||||
|
||||
inline void configure_pipe(HANDLE* read_handle, HANDLE* write_handle, HANDLE* child_handle)
|
||||
{
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
SP_SECURITY_ATTRIBUTES saAttr;
|
||||
|
||||
// Set the bInheritHandle flag so pipe handles are inherited.
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.nLength = sizeof(SP_SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
// Create a pipe for the child process's STDIN.
|
||||
if (!CreatePipe(read_handle, write_handle, &saAttr,0))
|
||||
if (!CreatePipe(read_handle, write_handle, reinterpret_cast<LPSECURITY_ATTRIBUTES>(&saAttr), 0))
|
||||
throw OSError("CreatePipe", 0);
|
||||
|
||||
// Ensure the write handle to the pipe for STDIN is not inherited.
|
||||
@ -1677,19 +1691,19 @@ inline void Popen::execute_process() noexcept(false)
|
||||
// CreateProcessW can modify szCmdLine so we allocate needed memory
|
||||
wchar_t *szCmdline = new wchar_t[command_line.size() + 1];
|
||||
wcscpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
|
||||
PROCESS_INFORMATION piProcInfo;
|
||||
STARTUPINFOW siStartInfo;
|
||||
SP_PROCESS_INFORMATION piProcInfo;
|
||||
SP_STARTUPINFOW siStartInfo;
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
|
||||
|
||||
// Set up members of the PROCESS_INFORMATION structure.
|
||||
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
|
||||
ZeroMemory(&piProcInfo, sizeof(SP_PROCESS_INFORMATION));
|
||||
|
||||
// Set up members of the STARTUPINFOW structure.
|
||||
// This structure specifies the STDIN and STDOUT handles for redirection.
|
||||
|
||||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFOW));
|
||||
siStartInfo.cb = sizeof(STARTUPINFOW);
|
||||
ZeroMemory(&siStartInfo, sizeof(SP_STARTUPINFOW));
|
||||
siStartInfo.cb = sizeof(SP_STARTUPINFOW);
|
||||
|
||||
siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr;
|
||||
siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr;
|
||||
@ -1708,8 +1722,8 @@ inline void Popen::execute_process() noexcept(false)
|
||||
creation_flags, // creation flags
|
||||
environment_string_table_ptr, // use provided environment
|
||||
cwd_arg, // use provided current directory
|
||||
&siStartInfo, // STARTUPINFOW pointer
|
||||
&piProcInfo); // receives PROCESS_INFORMATION
|
||||
reinterpret_cast<LPSTARTUPINFOW>(&siStartInfo), // STARTUPINFOW pointer
|
||||
reinterpret_cast<LPPROCESS_INFORMATION>(&piProcInfo)); // receives PROCESS_INFORMATION
|
||||
|
||||
// If an error occurs, exit the application.
|
||||
if (!bSuccess) {
|
||||
@ -2263,4 +2277,13 @@ OutBuffer pipeline(Args&&... args)
|
||||
|
||||
}
|
||||
|
||||
#ifdef __USING_WINDOWS__
|
||||
#ifndef _WINDEF_
|
||||
#undef ZeroMemory
|
||||
#undef MAKELANGID
|
||||
#undef STATUS_WAIT_0
|
||||
#undef WAIT_OBJECT_0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // SUBPROCESS_HPP
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include <iostream>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
#ifdef __USING_WINDOWS__
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace sp = subprocess;
|
||||
|
||||
void test_ret_code()
|
||||
|
Loading…
x
Reference in New Issue
Block a user