aboutsummaryrefslogtreecommitdiffstats
path: root/common/exechelp-w32.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/exechelp-w32.c')
-rw-r--r--common/exechelp-w32.c109
1 files changed, 60 insertions, 49 deletions
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c
index 4616bec33..297f6f854 100644
--- a/common/exechelp-w32.c
+++ b/common/exechelp-w32.c
@@ -382,7 +382,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
int cr_flags;
char *cmdline;
int fd, fdout, rp[2];
- HANDLE nullhd[];
+ HANDLE nullhd[2];
int i;
(void)preexec;
@@ -428,7 +428,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
}
nullhd[0] = fd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE;
- nullhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE;
+ nullhd[1] = fdout == -1? w32_open_null (1) : INVALID_HANDLE_VALUE;
/* Start the process. Note that we can't run the PREEXEC function
because this would change our own environment. */
@@ -437,7 +437,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
si.hStdInput = fd == -1? nullhd[0] : fd_to_handle (fd);
- si.hStdOutput = outfd == -1? nullhd[1] : fd_to_handle (fdout);
+ si.hStdOutput = fdout == -1? nullhd[1] : fd_to_handle (fdout);
si.hStdError = fd_to_handle (rp[1]);
cr_flags = (CREATE_DEFAULT_ERROR_MODE
@@ -599,22 +599,17 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
}
-/* Wait for the process identified by PID to terminate. PGMNAME should
- be the same as supplied to the spawn function and is only used for
- diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL
- for any failures of the spawned program or other error codes. If
- EXITCODE is not NULL the exit code of the process is stored at this
- address or -1 if it could not be retrieved. */
+/* See exechelp.h for a description. */
gpg_error_t
-gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode)
+gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
{
gpg_err_code_t ec;
HANDLE proc = fd_to_handle (pid);
int code;
DWORD exc;
- if (exitcode)
- *exitcode = -1;
+ if (r_exitcode)
+ *r_exitcode = -1;
if (pid == (pid_t)(-1))
return gpg_error (GPG_ERR_INV_VALUE);
@@ -622,50 +617,66 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode)
/* FIXME: We should do a pth_waitpid here. However this has not yet
been implemented. A special W32 pth system call would even be
better. */
- code = WaitForSingleObject (proc, INFINITE);
+ code = WaitForSingleObject (proc, hang? INFINITE : 0);
switch (code)
{
- case WAIT_FAILED:
- log_error (_("waiting for process %d to terminate failed: %s\n"),
- (int)pid, w32_strerror (-1));
- ec = GPG_ERR_GENERAL;
- break;
-
- case WAIT_OBJECT_0:
- if (!GetExitCodeProcess (proc, &exc))
- {
- log_error (_("error getting exit code of process %d: %s\n"),
- (int)pid, w32_strerror (-1) );
- ec = GPG_ERR_GENERAL;
- }
- else if (exc)
- {
- log_error (_("error running `%s': exit status %d\n"),
- pgmname, (int)exc );
- if (exitcode)
- *exitcode = (int)exc;
- ec = GPG_ERR_GENERAL;
- }
- else
- {
- if (exitcode)
- *exitcode = 0;
- ec = 0;
- }
- CloseHandle (proc);
- break;
-
- default:
- log_error ("WaitForSingleObject returned unexpected "
- "code %d for pid %d\n", code, (int)pid );
- ec = GPG_ERR_GENERAL;
- break;
+ case WAIT_TIMEOUT:
+ ec = GPG_ERR_TIMEOUT;
+ break;
+
+ case WAIT_FAILED:
+ log_error (_("waiting for process %d to terminate failed: %s\n"),
+ (int)pid, w32_strerror (-1));
+ ec = GPG_ERR_GENERAL;
+ break;
+
+ case WAIT_OBJECT_0:
+ if (!GetExitCodeProcess (proc, &exc))
+ {
+ log_error (_("error getting exit code of process %d: %s\n"),
+ (int)pid, w32_strerror (-1) );
+ ec = GPG_ERR_GENERAL;
+ }
+ else if (exc)
+ {
+ log_error (_("error running `%s': exit status %d\n"),
+ pgmname, (int)exc );
+ if (r_exitcode)
+ *r_exitcode = (int)exc;
+ ec = GPG_ERR_GENERAL;
+ }
+ else
+ {
+ if (r_exitcode)
+ *r_exitcode = 0;
+ ec = 0;
+ }
+ break;
+
+ default:
+ log_error ("WaitForSingleObject returned unexpected "
+ "code %d for pid %d\n", code, (int)pid );
+ ec = GPG_ERR_GENERAL;
+ break;
}
-
+
return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
}
+
+void
+gnupg_release_process (pid_t pid)
+{
+ if (pid != (pid_t)INVALID_HANDLE_VALUE)
+ {
+ HANDLE process = (HANDLE)pid;
+
+ CloseHandle (process);
+ }
+}
+
+
/* Spawn a new process and immediatley detach from it. The name of
the program to exec is PGMNAME and its arguments are in ARGV (the
programname is automatically passed as first argument).