mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Separate process waiting from process-reference release to eliminate Windows HANDLE reuse race
Some checks are pending
Build / build-mac (push) Waiting to run
Build / build-linux (push) Waiting to run
Build / build-arm32 (push) Waiting to run
Build / build-win (push) Waiting to run
Build / build-freebsd (push) Waiting to run
Build / build-musl (push) Waiting to run
CodeQL Advanced / Analyze (c-cpp) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
Some checks are pending
Build / build-mac (push) Waiting to run
Build / build-linux (push) Waiting to run
Build / build-arm32 (push) Waiting to run
Build / build-win (push) Waiting to run
Build / build-freebsd (push) Waiting to run
Build / build-musl (push) Waiting to run
CodeQL Advanced / Analyze (c-cpp) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
This commit is contained in:
parent
5381d0a1ee
commit
11fee73ec4
4 changed files with 36 additions and 12 deletions
|
|
@ -337,7 +337,9 @@ static int windows_ps(const char* ps_command, char* out, size_t out_size)
|
|||
close(stdout_fd);
|
||||
|
||||
status = 0;
|
||||
if (os_wait(pid, &status) < 0) {
|
||||
pid_t pid_ret = os_wait(pid, &status);
|
||||
os_dispose(pid);
|
||||
if (pid_ret < 0) {
|
||||
log_error(errno, "Failed to wait for PowerShell command '%s' (from os_wait).\n", ps_command);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
12
os/mingw.c
12
os/mingw.c
|
|
@ -3165,14 +3165,18 @@ pid_t os_wait(pid_t pid, int* status)
|
|||
WaitForSingleObject(h, INFINITE);
|
||||
|
||||
if (GetExitCodeProcess(h, &exit_code)) {
|
||||
CloseHandle(h);
|
||||
*status = exit_code;
|
||||
return pid;
|
||||
} else {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(h);
|
||||
|
||||
return -1;
|
||||
void os_dispose(pid_t pid)
|
||||
{
|
||||
if (pid > 0)
|
||||
CloseHandle((HANDLE)(intptr_t)pid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
21
os/os.h
21
os/os.h
|
|
@ -127,24 +127,33 @@ pid_t os_spawn(char** argv, int* stdout_read_fd, int* stderr_read_fd, const char
|
|||
|
||||
/**
|
||||
* Wait for the child process to terminate.
|
||||
* \param pid Process ID of the child process.
|
||||
* This function does not release the process reference returned by os_spawn().
|
||||
* The caller must eventually call os_dispose().
|
||||
* \param pid Process reference returned by os_spawn().
|
||||
* \param status Pointer to store the exit status.
|
||||
* \return Child PID on success, -1 on failure.
|
||||
* \return Child process reference on success, -1 on failure.
|
||||
*/
|
||||
pid_t os_wait(pid_t pid, int* status);
|
||||
|
||||
/**
|
||||
* Release the process reference returned by os_spawn().
|
||||
* On Unix this is a no-op. On Windows this closes the process HANDLE.
|
||||
* \param pid Process reference returned by os_spawn().
|
||||
*/
|
||||
void os_dispose(pid_t pid);
|
||||
|
||||
/**
|
||||
* Terminate gracefully a process. Intended for daemon/service processes controlling child processes.
|
||||
* The caller must subsequently call os_wait() to reap process resources and close handles.
|
||||
* \param pid Process ID of the process to terminate.
|
||||
* The caller retains ownership and must eventually call both os_wait() and os_dispose() as appropriate.
|
||||
* \param pid Process reference of the process to terminate.
|
||||
* \return 0 on success, -1 on failure.
|
||||
*/
|
||||
int os_term(pid_t pid);
|
||||
|
||||
/**
|
||||
* Forcibly terminate a process.
|
||||
* The caller must subsequently call os_wait() to reap process resources and close handles.
|
||||
* \param pid Process ID of the process to kill.
|
||||
* The caller retains ownership and must eventually call both os_wait() and os_dispose() as appropriate.
|
||||
* \param pid Process reference of the process to kill.
|
||||
* \return 0 on success, -1 on failure.
|
||||
*/
|
||||
int os_kill(pid_t pid);
|
||||
|
|
|
|||
11
os/unix.c
11
os/unix.c
|
|
@ -1427,6 +1427,11 @@ pid_t os_wait(pid_t pid, int* status)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void os_dispose(pid_t pid)
|
||||
{
|
||||
(void)pid;
|
||||
}
|
||||
|
||||
int os_term(pid_t pid)
|
||||
{
|
||||
if (pid <= 0) {
|
||||
|
|
@ -1484,6 +1489,7 @@ int os_spawn_and_wait(const char** argv)
|
|||
|
||||
int status;
|
||||
int ret = os_wait(pid, &status);
|
||||
os_dispose(pid);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
|
|
@ -1519,6 +1525,7 @@ OS_FILE* os_popen(const char** argv)
|
|||
close(stdout_fd);
|
||||
int status;
|
||||
os_wait(pid, &status);
|
||||
os_dispose(pid);
|
||||
errno = saved_errno;
|
||||
free(os_file);
|
||||
return 0;
|
||||
|
|
@ -1547,7 +1554,9 @@ int os_pclose(OS_FILE* stream)
|
|||
fclose(fp);
|
||||
|
||||
int status = 0;
|
||||
if (os_wait(pid, &status) < 0) {
|
||||
int ret = os_wait(pid, &status);
|
||||
os_dispose(pid);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue