diff --git a/librz/util/subprocess.c b/librz/util/subprocess.c index 8b0da9f31e..eb6f0cd9c5 100644 --- a/librz/util/subprocess.c +++ b/librz/util/subprocess.c @@ -47,13 +47,17 @@ struct rz_subprocess_t { #define INVALID_POINTER_VALUE ((void *)PTRDIFF_MAX) -static RzThreadLock *subproc_mutex = NULL; -static long refcount = 0; -static bool has_procthreadattr = false; -static volatile long pipe_id = 0; -static DWORD mode_stdin; -static DWORD mode_stdout; -static DWORD mode_stderr; +typedef struct subprocess_windows_t { + RzThreadLock *subproc_mutex; + long refcount; + bool has_procthreadattr; + volatile long pipe_id; + DWORD mode_stdin; + DWORD mode_stdout; + DWORD mode_stderr; +} SubprocessWindows; + +static SubprocessWindows subwin = { 0 }; static bool create_pipe_overlap(HANDLE *pipe_read, HANDLE *pipe_write, LPSECURITY_ATTRIBUTES attrs, DWORD sz, DWORD read_mode, DWORD write_mode) { // see https://stackoverflow.com/a/419736 @@ -61,7 +65,7 @@ static bool create_pipe_overlap(HANDLE *pipe_read, HANDLE *pipe_write, LPSECURIT sz = 4096; } WCHAR name[MAX_PATH]; - _snwprintf_s(name, _countof(name), sizeof(name), L"\\\\.\\pipe\\rz-pipe-subproc.%d.%ld", (int)GetCurrentProcessId(), (long)InterlockedIncrement(&pipe_id)); + _snwprintf_s(name, _countof(name), sizeof(name), L"\\\\.\\pipe\\rz-pipe-subproc.%d.%ld", (int)GetCurrentProcessId(), (long)InterlockedIncrement(&subwin.pipe_id)); *pipe_read = CreateNamedPipeW(name, PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, sz, sz, 120 * 1000, attrs); if (!*pipe_read) { return FALSE; @@ -79,29 +83,29 @@ static bool create_pipe_overlap(HANDLE *pipe_read, HANDLE *pipe_write, LPSECURIT static RzThreadLock *get_subprocess_lock(void) { RzThreadLock *lock; do { - lock = InterlockedCompareExchangePointer(&subproc_mutex, INVALID_POINTER_VALUE, INVALID_POINTER_VALUE); + lock = InterlockedCompareExchangePointer(&subwin.subproc_mutex, INVALID_POINTER_VALUE, INVALID_POINTER_VALUE); } while (!lock); return lock; } RZ_API bool rz_subprocess_init(void) { - long ref = InterlockedIncrement(&refcount); + long ref = InterlockedIncrement(&subwin.refcount); RzThreadLock *lock = NULL; if (ref == 1) { lock = rz_th_lock_new(false); if (!lock) { - InterlockedExchangePointer(&subproc_mutex, INVALID_POINTER_VALUE); - InterlockedDecrement(&refcount); + InterlockedExchangePointer(&subwin.subproc_mutex, INVALID_POINTER_VALUE); + InterlockedDecrement(&subwin.refcount); return false; } // Enter lock before making it available, so we are the first to run rz_th_lock_enter(lock); - InterlockedExchangePointer(&subproc_mutex, lock); + InterlockedExchangePointer(&subwin.subproc_mutex, lock); } else { // Spin until theres a lock available or lock initialization failed lock = get_subprocess_lock(); if (lock == INVALID_POINTER_VALUE) { - InterlockedDecrement(&refcount); + InterlockedDecrement(&subwin.refcount); return false; } rz_th_lock_enter(lock); @@ -113,12 +117,12 @@ RZ_API bool rz_subprocess_init(void) { } // Save current console mode - GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode_stdin); - GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &mode_stdout); - GetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), &mode_stderr); + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &subwin.mode_stdin); + GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &subwin.mode_stdout); + GetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), &subwin.mode_stderr); #if NTDDI_VERSION >= NTDDI_VISTA - if (!has_procthreadattr && IsWindowsVistaOrGreater()) { + if (!subwin.has_procthreadattr && IsWindowsVistaOrGreater()) { HMODULE kernel32 = LoadLibraryW(L"kernel32"); if (!kernel32) { rz_sys_perror("LoadLibraryW(L\"kernel32\")"); @@ -128,7 +132,7 @@ RZ_API bool rz_subprocess_init(void) { lpUpdateProcThreadAttribute = (UpdateProcThreadAttribute_t)GetProcAddress(kernel32, "UpdateProcThreadAttribute"); lpDeleteProcThreadAttributeList = (DeleteProcThreadAttributeList_t)GetProcAddress(kernel32, "DeleteProcThreadAttributeList"); if (lpInitializeProcThreadAttributeList && lpUpdateProcThreadAttribute && lpDeleteProcThreadAttributeList) { - has_procthreadattr = true; + subwin.has_procthreadattr = true; } FreeLibrary(kernel32); } @@ -140,22 +144,22 @@ leave: RZ_API void rz_subprocess_fini(void) { RzThreadLock *lock = NULL; do { - if (InterlockedCompareExchange(&refcount, -1, -1) == 0) { + if (InterlockedCompareExchange(&subwin.refcount, -1, -1) == 0) { // Shouldn't happen, someone called this function excessively rz_warn_if_reached(); return; } - lock = InterlockedExchangePointer(&subproc_mutex, NULL); + lock = InterlockedExchangePointer(&subwin.subproc_mutex, NULL); } while (!lock); - if (InterlockedDecrement(&refcount) > 0) { - InterlockedExchangePointer(&subproc_mutex, lock); + if (InterlockedDecrement(&subwin.refcount) > 0) { + InterlockedExchangePointer(&subwin.subproc_mutex, lock); return; } SetEnvironmentVariableW(L"RZ_PIPE_PATH", NULL); // Restore console mode - SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode_stdin); - SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode_stdout); - SetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), mode_stderr); + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), subwin.mode_stdin); + SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), subwin.mode_stdout); + SetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), subwin.mode_stderr); rz_th_lock_free(lock); } @@ -373,7 +377,7 @@ RZ_API RZ_OWN RzSubprocess *rz_subprocess_start_opt(RZ_NONNULL const RzSubproces STARTUPINFOW *start_info = &start_info_short; #if NTDDI_VERSION >= NTDDI_VISTA STARTUPINFOEXW start_infoex = { .StartupInfo.cb = sizeof(STARTUPINFOEXW) }; - if (has_procthreadattr) { + if (subwin.has_procthreadattr) { SIZE_T attr_list_size = 0; if (!lpInitializeProcThreadAttributeList(NULL, 1, 0, &attr_list_size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {