diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2024-05-31 08:36:39 +0200 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2024-05-31 08:36:39 +0200 |
commit | fc3fde1bdeb260c92b0a3ea7489536129e9a8a93 (patch) | |
tree | d5eb2a841f582211f48dc155f4fd079ea4ead597 /common | |
parent | common: Fix process termination check at release. (diff) | |
download | gnupg2-fc3fde1bdeb260c92b0a3ea7489536129e9a8a93.tar.xz gnupg2-fc3fde1bdeb260c92b0a3ea7489536129e9a8a93.zip |
spawn: Remove spawn callback, introduce gnupg_spawn_actions.
* common/exechelp-posix.c (call_spawn_cb): Remove.
(gnupg_spawn_actions_new, gnupg_spawn_actions_release)
(gnupg_spawn_actions_set_environ, gnupg_spawn_actions_set_atfork)
(gnupg_spawn_actions_set_redirect)
(gnupg_spawn_actions_set_inherit_fds): New.
(my_exec, spawn_detached): Use spawn actions.
(gnupg_spawn_helper): Remove.
(gnupg_process_spawn): Remove callback, introduce gnupg_spawn_actions.
* common/exechelp-w32.c: Ditto.
* common/exechelp.h: Ditto.
* agent/genkey.c (do_check_passphrase_pattern): Follow the change of
gnupg_process_spawn API.
* common/asshelp.c (start_new_service): Likewise.
* common/exectool.c (gnupg_exec_tool_stream): Likewise.
* common/t-exechelp.c (test_pipe_stream): Likewise.
* dirmngr/ldap-wrapper.c (ldap_wrapper): Likewise.
* g10/photoid.c (run_with_pipe): Likewise.
* scd/app.c (report_change): Likewise.
* tests/gpgscm/ffi.c (do_process_spawn_io, do_process_spawn_fd):
Likewise.
* tools/gpg-card.c (cmd_gpg): Likewise.
* tools/gpgconf-comp.c (gpg_agent_runtime_change): Likewise.
(scdaemon_runtime_change, tpm2daemon_runtime_change)
(dirmngr_runtime_change, keyboxd_runtime_change)
(gc_component_launch, gc_component_check_options)
(retrieve_options_from_program): Likewise.
* tools/gpgconf.c (show_versions_via_dirmngr): Likewise.
* tools/gpgtar-create.c (gpgtar_create): Likewise.
* tools/gpgtar-extract.c (gpgtar_extract): Likewise.
* tools/gpgtar-list.c (gpgtar_list): Likewise.
--
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/asshelp.c | 5 | ||||
-rw-r--r-- | common/exechelp-posix.c | 142 | ||||
-rw-r--r-- | common/exechelp-w32.c | 159 | ||||
-rw-r--r-- | common/exechelp.h | 37 | ||||
-rw-r--r-- | common/exectool.c | 14 | ||||
-rw-r--r-- | common/t-exechelp.c | 2 |
6 files changed, 240 insertions, 119 deletions
diff --git a/common/asshelp.c b/common/asshelp.c index 5a40e0380..957ca994d 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -525,11 +525,10 @@ start_new_service (assuan_context_t *r_ctx, { #ifdef HAVE_W32_SYSTEM err = gnupg_process_spawn (program? program : program_name, argv, - GNUPG_PROCESS_DETACHED, - NULL, NULL, NULL); + GNUPG_PROCESS_DETACHED, NULL, NULL); #else /*!W32*/ err = gnupg_process_spawn (program? program : program_name, argv, - 0, NULL, NULL, NULL); + 0, NULL, NULL); #endif /*!W32*/ if (err) log_error ("failed to start %s '%s': %s\n", diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 3f124ab80..97d8fa4ad 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -182,7 +182,7 @@ get_max_fds (void) which shall not be closed. This list shall be sorted in ascending order with the end marked by -1. */ void -close_all_fds (int first, int *except) +close_all_fds (int first, const int *except) { int max_fd = get_max_fds (); int fd, i, except_start; @@ -429,46 +429,105 @@ posix_open_null (int for_write) return fd; } -static void -call_spawn_cb (struct spawn_cb_arg *sca, - int fd_in, int fd_out, int fd_err, - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) +struct gnupg_spawn_actions { + int fd[3]; + const int *except_fds; + char **environ; + void (*atfork) (void *); + void *atfork_arg; +}; + +gpg_err_code_t +gnupg_spawn_actions_new (gnupg_spawn_actions_t *r_act) { - sca->fds[0] = fd_in; - sca->fds[1] = fd_out; - sca->fds[2] = fd_err; - sca->except_fds = NULL; - sca->arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (sca); + gnupg_spawn_actions_t act; + int i; + + *r_act = NULL; + + act = xtrycalloc (1, sizeof (struct gnupg_spawn_actions)); + if (act == NULL) + return gpg_err_code_from_syserror (); + + for (i = 0; i <= 2; i++) + act->fd[i] = -1; + + *r_act = act; + return 0; +} + +void +gnupg_spawn_actions_release (gnupg_spawn_actions_t act) +{ + if (!act) + return; + + xfree (act); +} + +void +gnupg_spawn_actions_set_environ (gnupg_spawn_actions_t act, + char **environ_for_child) +{ + act->environ = environ_for_child; +} + +void +gnupg_spawn_actions_set_atfork (gnupg_spawn_actions_t act, + void (*atfork)(void *), void *arg) +{ + act->atfork = atfork; + act->atfork_arg = arg; +} + +void +gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t act, + int in, int out, int err) +{ + act->fd[0] = in; + act->fd[1] = out; + act->fd[2] = err; +} + +void +gnupg_spawn_actions_set_inherit_fds (gnupg_spawn_actions_t act, + const int *fds) +{ + act->except_fds = fds; } static void -my_exec (const char *pgmname, const char *argv[], struct spawn_cb_arg *sca) +my_exec (const char *pgmname, const char *argv[], gnupg_spawn_actions_t act) { int i; /* Assign /dev/null to unused FDs. */ for (i = 0; i <= 2; i++) - if (sca->fds[i] == -1) - sca->fds[i] = posix_open_null (i); + if (act->fd[i] == -1) + act->fd[i] = posix_open_null (i); /* Connect the standard files. */ for (i = 0; i <= 2; i++) - if (sca->fds[i] != i) + if (act->fd[i] != i) { - if (dup2 (sca->fds[i], i) == -1) + if (dup2 (act->fd[i], i) == -1) log_fatal ("dup2 std%s failed: %s\n", i==0?"in":i==1?"out":"err", strerror (errno)); /* - * We don't close sca.fds[i] here, but close them by + * We don't close act->fd[i] here, but close them by * close_all_fds. Note that there may be same one in three of - * sca->fds[i]. + * act->fd[i]. */ } /* Close all other files. */ - close_all_fds (3, sca->except_fds); + close_all_fds (3, act->except_fds); + + if (act->environ) + environ = act->environ; + + if (act->atfork) + act->atfork (act->atfork_arg); execv (pgmname, (char *const *)argv); /* No way to print anything, as we have may have closed all streams. */ @@ -477,7 +536,7 @@ my_exec (const char *pgmname, const char *argv[], struct spawn_cb_arg *sca) static gpg_err_code_t spawn_detached (const char *pgmname, const char *argv[], - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) + gnupg_spawn_actions_t act) { gpg_err_code_t ec; pid_t pid; @@ -510,7 +569,6 @@ spawn_detached (const char *pgmname, const char *argv[], if (!pid) { pid_t pid2; - struct spawn_cb_arg sca; if (setsid() == -1 || chdir ("/")) _exit (1); @@ -521,9 +579,7 @@ spawn_detached (const char *pgmname, const char *argv[], if (pid2) _exit (0); /* Let the parent exit immediately. */ - call_spawn_cb (&sca, -1, -1, -1, spawn_cb, spawn_cb_arg); - - my_exec (pgmname, argv, &sca); + my_exec (pgmname, argv, act); /*NOTREACHED*/ } @@ -532,7 +588,7 @@ spawn_detached (const char *pgmname, const char *argv[], { post_syscall (); ec = gpg_err_code_from_syserror (); - log_error ("waitpid failed in gpgrt_spawn_process_detached: %s", + log_error ("waitpid failed in spawn_detached: %s", gpg_strerror (ec)); return ec; } @@ -542,18 +598,9 @@ spawn_detached (const char *pgmname, const char *argv[], return 0; } -void -gnupg_spawn_helper (struct spawn_cb_arg *sca) -{ - int *user_except = sca->arg; - sca->except_fds = user_except; -} - gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv1[], - unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + unsigned int flags, gnupg_spawn_actions_t act, gnupg_process_t *r_process) { gpg_err_code_t ec; @@ -564,6 +611,15 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], pid_t pid; const char **argv; int i, j; + struct gnupg_spawn_actions act_default; + + if (!act) + { + memset (&act_default, 0, sizeof (act_default)); + for (i = 0; i <= 2; i++) + act_default.fd[i] = -1; + act = &act_default; + } check_syscall_func (); @@ -603,7 +659,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], return GPG_ERR_INV_ARG; } - return spawn_detached (pgmname, argv, spawn_cb, spawn_cb_arg); + return spawn_detached (pgmname, argv, act); } process = xtrycalloc (1, sizeof (struct gnupg_process)); @@ -732,8 +788,6 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], if (!pid) { - struct spawn_cb_arg sca; - if (fd_in[1] >= 0) close (fd_in[1]); if (fd_out[0] >= 0) @@ -741,11 +795,15 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], if (fd_err[0] >= 0) close (fd_err[0]); - call_spawn_cb (&sca, fd_in[0], fd_out[1], fd_err[1], - spawn_cb, spawn_cb_arg); + if (act->fd[0] < 0) + act->fd[0] = fd_in[0]; + if (act->fd[1] < 0) + act->fd[1] = fd_out[1]; + if (act->fd[2] < 0) + act->fd[2] = fd_err[1]; /* Run child. */ - my_exec (pgmname, argv, &sca); + my_exec (pgmname, argv, act); /*NOTREACHED*/ } diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index d1764d1f6..46fb9ae92 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -65,7 +65,6 @@ #include "util.h" #include "i18n.h" #include "sysutils.h" -#define NEED_STRUCT_SPAWN_CB_ARG #include "exechelp.h" #include <windows.h> @@ -126,7 +125,7 @@ get_max_fds (void) /* Under Windows this is a dummy function. */ void -close_all_fds (int first, int *except) +close_all_fds (int first, const int *except) { (void)first; (void)except; @@ -410,6 +409,12 @@ gnupg_close_pipe (int fd) close (fd); } +struct gnupg_spawn_actions { + void *hd[3]; + void **inherit_hds; + char *env; +}; + struct gnupg_process { const char *pgmname; unsigned int terminated :1; /* or detached */ @@ -479,8 +484,7 @@ check_windows_version (void) static gpg_err_code_t -spawn_detached (const char *pgmname, char *cmdline, - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) +spawn_detached (const char *pgmname, char *cmdline, gnupg_spawn_actions_t act) { SECURITY_ATTRIBUTES sec_attr; PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; @@ -490,8 +494,8 @@ spawn_detached (const char *pgmname, char *cmdline, wchar_t *wpgmname = NULL; gpg_err_code_t ec; int ret; - struct spawn_cb_arg sca; BOOL ask_inherit = FALSE; + int i; ec = gnupg_access (pgmname, X_OK); if (ec) @@ -502,22 +506,27 @@ spawn_detached (const char *pgmname, char *cmdline, memset (&si, 0, sizeof si); - sca.allow_foreground_window = FALSE; - sca.hd[0] = INVALID_HANDLE_VALUE; - sca.hd[1] = INVALID_HANDLE_VALUE; - sca.hd[2] = INVALID_HANDLE_VALUE; - sca.inherit_hds = NULL; - sca.arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (&sca); + i = 0; + if (act->hd[0] != INVALID_HANDLE_VALUE) + i++; + if (act->hd[1] != INVALID_HANDLE_VALUE) + i++; + if (act->hd[2] != INVALID_HANDLE_VALUE) + i++; - if (sca.inherit_hds) + if (i != 0 || act->inherit_hds) { SIZE_T attr_list_size = 0; HANDLE hd[16]; - HANDLE *hd_p = sca.inherit_hds; + HANDLE *hd_p = act->inherit_hds; int j = 0; + if (act->hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[0]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[1]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[2]; if (hd_p) { while (*hd_p != INVALID_HANDLE_VALUE) @@ -559,7 +568,8 @@ spawn_detached (const char *pgmname, char *cmdline, /* Start the process. */ si.StartupInfo.cb = sizeof (si); - si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; + si.StartupInfo.dwFlags = ((i > 0 ? STARTF_USESTDHANDLES : 0) + | STARTF_USESHOWWINDOW); si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; cr_flags = (CREATE_DEFAULT_ERROR_MODE @@ -579,7 +589,7 @@ spawn_detached (const char *pgmname, char *cmdline, &sec_attr, /* Thread security attributes. */ ask_inherit, /* Inherit handles. */ cr_flags, /* Creation flags. */ - NULL, /* Environment. */ + act->env, /* Environment. */ NULL, /* Use current drive/directory. */ (STARTUPINFOW *)&si, /* Startup information. */ &pi /* Returns process information. */ @@ -617,18 +627,60 @@ spawn_detached (const char *pgmname, char *cmdline, } +gpg_err_code_t +gnupg_spawn_actions_new (gnupg_spawn_actions_t *r_act) +{ + gnupg_spawn_actions_t act; + int i; + + *r_act = NULL; + + act = xtrycalloc (1, sizeof (struct gnupg_spawn_actions)); + if (act == NULL) + return gpg_err_code_from_syserror (); + + for (i = 0; i <= 2; i++) + act->hd[i] = INVALID_HANDLE_VALUE; + + *r_act = act; + return 0; +} + +void +gnupg_spawn_actions_release (gnupg_spawn_actions_t act) +{ + if (!act) + return; + + xfree (act); +} + +void +gnupg_spawn_actions_set_envvars (gnupg_spawn_actions_t act, char *env) +{ + act->env = env; +} + void -gnupg_spawn_helper (struct spawn_cb_arg *sca) +gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t act, + void *in, void *out, void *err) { - HANDLE *user_except = sca->arg; - sca->inherit_hds = user_except; + act->hd[0] = in; + act->hd[1] = out; + act->hd[2] = err; } +void +gnupg_spawn_actions_set_inherit_handles (gnupg_spawn_actions_t act, + void **handles) +{ + act->inherit_hds = handles; +} + + gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[], - unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + unsigned int flags, gnupg_spawn_actions_t act, gnupg_process_t *r_process) { gpg_err_code_t ec; @@ -644,9 +696,18 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], HANDLE hd_in[2]; HANDLE hd_out[2]; HANDLE hd_err[2]; - struct spawn_cb_arg sca; int i; BOOL ask_inherit = FALSE; + BOOL allow_foreground_window = FALSE; + struct gnupg_spawn_actions act_default; + + if (!act) + { + memset (&act_default, 0, sizeof (act_default)); + for (i = 0; i <= 2; i++) + act_default.hd[i] = INVALID_HANDLE_VALUE; + act = &act_default; + } check_syscall_func (); @@ -670,7 +731,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], return GPG_ERR_INV_ARG; } - return spawn_detached (pgmname, cmdline, spawn_cb, spawn_cb_arg); + return spawn_detached (pgmname, cmdline, act); } if (r_process) @@ -770,36 +831,34 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], memset (&si, 0, sizeof si); - sca.allow_foreground_window = FALSE; - sca.hd[0] = hd_in[0]; - sca.hd[1] = hd_out[1]; - sca.hd[2] = hd_err[1]; - sca.inherit_hds = NULL; - sca.arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (&sca); + if (act->hd[0] == INVALID_HANDLE_VALUE) + act->hd[0] = hd_in[0]; + if (act->hd[1] == INVALID_HANDLE_VALUE) + act->hd[1] = hd_out[1]; + if (act->hd[2] == INVALID_HANDLE_VALUE) + act->hd[2] = hd_err[1]; i = 0; - if (sca.hd[0] != INVALID_HANDLE_VALUE) + if (act->hd[0] != INVALID_HANDLE_VALUE) i++; - if (sca.hd[1] != INVALID_HANDLE_VALUE) + if (act->hd[1] != INVALID_HANDLE_VALUE) i++; - if (sca.hd[2] != INVALID_HANDLE_VALUE) + if (act->hd[2] != INVALID_HANDLE_VALUE) i++; - if (i != 0 || sca.inherit_hds) + if (i != 0 || act->inherit_hds) { SIZE_T attr_list_size = 0; HANDLE hd[16]; - HANDLE *hd_p = sca.inherit_hds; + HANDLE *hd_p = act->inherit_hds; int j = 0; - if (sca.hd[0] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[0]; - if (sca.hd[1] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[1]; - if (sca.hd[1] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[2]; + if (act->hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[0]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[1]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[2]; if (hd_p) { while (*hd_p != INVALID_HANDLE_VALUE) @@ -858,9 +917,9 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], si.StartupInfo.cb = sizeof (si); si.StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE; - si.StartupInfo.hStdInput = sca.hd[0]; - si.StartupInfo.hStdOutput = sca.hd[1]; - si.StartupInfo.hStdError = sca.hd[2]; + si.StartupInfo.hStdInput = act->hd[0]; + si.StartupInfo.hStdOutput = act->hd[1]; + si.StartupInfo.hStdError = act->hd[2]; /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ cr_flags = (CREATE_DEFAULT_ERROR_MODE @@ -877,9 +936,9 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], &sec_attr, /* Thread security attributes. */ ask_inherit, /* Inherit handles. */ cr_flags, /* Creation flags. */ - NULL, /* Environment. */ + act->env, /* Environment. */ NULL, /* Use current drive/directory. */ - (STARTUPINFOW *)&si, /* Startup information. */ + (STARTUPINFOW *)&si, /* Startup information. */ &pi /* Returns process information. */ ); if (!ret) @@ -933,7 +992,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], /* pi.hProcess, pi.hThread, */ /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - if (sca.allow_foreground_window) + if (allow_foreground_window) { /* Fixme: For unknown reasons AllowSetForegroundWindow returns * an invalid argument error if we pass it the correct diff --git a/common/exechelp.h b/common/exechelp.h index 0370b23a4..93ba12eeb 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -42,7 +42,7 @@ int get_max_fds (void); EXCEPT is not NULL, it is expected to be a list of file descriptors which are not to close. This list shall be sorted in ascending order with its end marked by -1. */ -void close_all_fds (int first, int *except); +void close_all_fds (int first, const int *except); /* Returns an array with all currently open file descriptors. The end @@ -75,22 +75,21 @@ void gnupg_close_pipe (int fd); /* The opaque type for a subprocess. */ typedef struct gnupg_process *gnupg_process_t; +typedef struct gnupg_spawn_actions *gnupg_spawn_actions_t; +gpg_err_code_t gnupg_spawn_actions_new (gnupg_spawn_actions_t *r_act); +void gnupg_spawn_actions_release (gnupg_spawn_actions_t act); #ifdef HAVE_W32_SYSTEM -struct spawn_cb_arg; -#ifdef NEED_STRUCT_SPAWN_CB_ARG -struct spawn_cb_arg { - HANDLE hd[3]; - HANDLE *inherit_hds; - BOOL allow_foreground_window; - void *arg; -}; -#endif +void gnupg_spawn_actions_set_envvars (gnupg_spawn_actions_t, char *); +void gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t, + void *, void *, void *); +void gnupg_spawn_actions_set_inherit_handles (gnupg_spawn_actions_t, void **); #else -struct spawn_cb_arg { - int fds[3]; - int *except_fds; - void *arg; -}; +void gnupg_spawn_actions_set_environ (gnupg_spawn_actions_t, char **); +void gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t, int, int, int); +void gnupg_spawn_actions_set_inherit_fds (gnupg_spawn_actions_t, + const int *); +void gnupg_spawn_actions_set_atfork (gnupg_spawn_actions_t, + void (*atfork)(void *), void *arg); #endif #define GNUPG_PROCESS_DETACHED (1 << 1) @@ -110,14 +109,10 @@ struct spawn_cb_arg { #define GNUPG_PROCESS_STREAM_NONBLOCK (1 << 16) -/* Spawn helper. */ -void gnupg_spawn_helper (struct spawn_cb_arg *sca); - /* Spawn PGMNAME. */ -gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[], +gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv1[], unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + gnupg_spawn_actions_t act, gnupg_process_t *r_process); /* Get FDs for subprocess I/O. It is the caller which should care diff --git a/common/exectool.c b/common/exectool.c index 3505c25f1..05504de98 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -338,6 +338,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], read_and_log_buffer_t fderrstate; struct copy_buffer *cpbuf_in = NULL, *cpbuf_out = NULL, *cpbuf_extra = NULL; int quiet = 0; + gnupg_spawn_actions_t act = NULL; memset (fds, 0, sizeof fds); memset (&fderrstate, 0, sizeof fderrstate); @@ -413,13 +414,21 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], else exceptclose[0] = -1; + err = gnupg_spawn_actions_new (&act); + if (err) + goto leave; + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, exceptclose); +#else + gnupg_spawn_actions_set_inherit_fds (act, exceptclose); +#endif err = gnupg_process_spawn (pgmname, argv, ((input ? GNUPG_PROCESS_STDIN_PIPE : 0) | GNUPG_PROCESS_STDOUT_PIPE - | GNUPG_PROCESS_STDERR_PIPE), - gnupg_spawn_helper, exceptclose, &proc); + | GNUPG_PROCESS_STDERR_PIPE), act, &proc); gnupg_process_get_streams (proc, GNUPG_PROCESS_STREAM_NONBLOCK, input? &infp : NULL, &outfp, &errfp); if (extrapipe[0] != -1) @@ -572,6 +581,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], es_fclose (outfp); es_fclose (errfp); gnupg_process_release (proc); + gnupg_spawn_actions_release (act); copy_buffer_shred (cpbuf_in); xfree (cpbuf_in); diff --git a/common/t-exechelp.c b/common/t-exechelp.c index 2179ef2a0..f25c91d3a 100644 --- a/common/t-exechelp.c +++ b/common/t-exechelp.c @@ -266,7 +266,7 @@ test_pipe_stream (const char *pgmname) err = gnupg_process_spawn (pgmname, argv, (GNUPG_PROCESS_STDOUT_PIPE |GNUPG_PROCESS_STDERR_KEEP), - NULL, NULL, &proc); + NULL, &proc); if (err) { fprintf (stderr, "gnupg_process_spawn failed\n"); |