diff options
author | Werner Koch <[email protected]> | 2015-09-28 16:10:21 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2015-09-28 16:40:38 +0000 |
commit | 83811e3f1f0c615b2b63bafdb49a35a0fc198088 (patch) | |
tree | 676f6c145331d2911969ad01db7fcea6f6132c80 /common/exechelp-w32.c | |
parent | scd: Handle error correctly. (diff) | |
download | gnupg-83811e3f1f0c615b2b63bafdb49a35a0fc198088.tar.gz gnupg-83811e3f1f0c615b2b63bafdb49a35a0fc198088.zip |
common: Change calling convention for gnupg_spawn_process.
* common/exechelp.h (GNUPG_SPAWN_NONBLOCK): New.
(GNUPG_SPAWN_RUN_ASFW, GNUPG_SPAWN_DETACHED): Macro to replace the
numbers.
* common/exechelp.h (gnupg_spawn_process): Change function to not take
an optional stream for stdin but to return one.
* common/exechelp-posix.c (gnupg_spawn_process): Implement change.
(create_pipe_and_estream): Add args outbound and nonblock.
* common/exechelp-w32.c (gnupg_spawn_process): Implement change.
--
In 2.1 this function is only used at one place and the stdin parameter
is not used. Thus this change is trivial for the callers but along
with estream's new es_poll it is overall simpler to use.
Note that the Windows version has not been tested.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'common/exechelp-w32.c')
-rw-r--r-- | common/exechelp-w32.c | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 05e9e1000..ba3b357e9 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -346,7 +346,7 @@ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], gpg_err_source_t errsource, void (*preexec)(void), unsigned int flags, - estream_t infp, + estream_t *r_infp, estream_t *r_outfp, estream_t *r_errfp, pid_t *pid) @@ -363,9 +363,10 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], STARTUPINFO si; int cr_flags; char *cmdline; - HANDLE inhandle = INVALID_HANDLE_VALUE; + HANDLE inpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; HANDLE outpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; HANDLE errpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + estream_t infp = NULL; estream_t outfp = NULL; estream_t errfp = NULL; HANDLE nullhd[3] = {INVALID_HANDLE_VALUE, @@ -374,6 +375,8 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], int i; es_syshd_t syshd; + if (r_infp) + *r_infp = NULL; if (r_outfp) *r_outfp = NULL; if (r_errfp) @@ -382,29 +385,26 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], if (infp) { - es_fflush (infp); - es_rewind (infp); - es_syshd (infp, &syshd); - switch (syshd.type) + if (create_inheritable_pipe (inpipe, 0)) { - case ES_SYSHD_FD: - inhandle = (HANDLE)_get_osfhandle (syshd.u.fd); - break; - case ES_SYSHD_SOCK: - inhandle = (HANDLE)_get_osfhandle (syshd.u.sock); - break; - case ES_SYSHD_HANDLE: - inhandle = syshd.u.handle; - break; - default: - inhandle = INVALID_HANDLE_VALUE; - break; + err = gpg_err_make (errsource, GPG_ERR_GENERAL); + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + return err; + } + + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = inpipe[1]; + infp = es_sysopen (&syshd, "w"); + if (!infp) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error (_("error creating a stream for a pipe: %s\n"), + gpg_strerror (err)); + CloseHandle (inpipe[0]); + CloseHandle (inpipe[1]); + inpipe[0] = inpipe[1] = INVALID_HANDLE_VALUE; + return err; } - if (inhandle == INVALID_HANDLE_VALUE) - return gpg_err_make (errsource, GPG_ERR_INV_VALUE); - /* FIXME: In case we can't get a system handle (e.g. due to - es_fopencookie we should create a piper and a feeder - thread. */ } if (r_outfp) @@ -427,6 +427,12 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], CloseHandle (outpipe[0]); CloseHandle (outpipe[1]); outpipe[0] = outpipe[1] = INVALID_HANDLE_VALUE; + if (infp) + es_fclose (infp); + else if (inpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[1]); + if (inpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (inpipe[0]); return err; } } @@ -457,6 +463,12 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], CloseHandle (outpipe[0]); if (outpipe[1] != INVALID_HANDLE_VALUE) CloseHandle (outpipe[1]); + if (infp) + es_fclose (infp); + else if (inpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[1]); + if (inpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (inpipe[0]); return err; } } @@ -471,7 +483,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], if (err) return err; - if (inhandle != INVALID_HANDLE_VALUE) + if (inpipe[0] != INVALID_HANDLE_VALUE) nullhd[0] = w32_open_null (0); if (outpipe[1] != INVALID_HANDLE_VALUE) nullhd[1] = w32_open_null (0); @@ -486,12 +498,12 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], si.cb = sizeof (si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; - si.hStdInput = inhandle == INVALID_HANDLE_VALUE? nullhd[0] : inhandle; + si.hStdInput = inpipe[0] == INVALID_HANDLE_VALUE? nullhd[0] : inpipe[0]; si.hStdOutput = outpipe[1] == INVALID_HANDLE_VALUE? nullhd[1] : outpipe[1]; si.hStdError = errpipe[1] == INVALID_HANDLE_VALUE? nullhd[2] : errpipe[1]; cr_flags = (CREATE_DEFAULT_ERROR_MODE - | ((flags & 128)? DETACHED_PROCESS : 0) + | ((flags & GNUPG_SPAWN_DETACHED)? DETACHED_PROCESS : 0) | GetPriorityClass (GetCurrentProcess ()) | CREATE_SUSPENDED); /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ @@ -509,6 +521,12 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], { log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); xfree (cmdline); + if (infp) + es_fclose (infp); + else if (inpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[1]); + if (inpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (inpipe[0]); if (outfp) es_fclose (outfp); else if (outpipe[0] != INVALID_HANDLE_VALUE) @@ -532,6 +550,8 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], CloseHandle (nullhd[i]); /* Close the inherited ends of the pipes. */ + if (inpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (inpipe[0]); if (outpipe[1] != INVALID_HANDLE_VALUE) CloseHandle (outpipe[1]); if (errpipe[1] != INVALID_HANDLE_VALUE) @@ -546,13 +566,15 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], /* Fixme: For unknown reasons AllowSetForegroundWindow returns an invalid argument error if we pass it the correct processID. As a workaround we use -1 (ASFW_ANY). */ - if ( (flags & 64) ) + if ((flags & GNUPG_SPAWN_RUN_ASFW)) gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/); /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); CloseHandle (pi.hThread); + if (r_infp) + *r_infp = infp; if (r_outfp) *r_outfp = outfp; if (r_errfp) |