diff options
-rw-r--r-- | agent/genkey.c | 2 | ||||
-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 | ||||
-rw-r--r-- | dirmngr/ldap-wrapper.c | 2 | ||||
-rw-r--r-- | g10/photoid.c | 4 | ||||
-rw-r--r-- | scd/app.c | 25 | ||||
-rw-r--r-- | tests/gpgscm/ffi.c | 53 | ||||
-rw-r--r-- | tools/gpg-card.c | 2 | ||||
-rw-r--r-- | tools/gpgconf-comp.c | 27 | ||||
-rw-r--r-- | tools/gpgconf.c | 5 | ||||
-rw-r--r-- | tools/gpgtar-create.c | 17 | ||||
-rw-r--r-- | tools/gpgtar-extract.c | 17 | ||||
-rw-r--r-- | tools/gpgtar-list.c | 17 |
17 files changed, 350 insertions, 180 deletions
diff --git a/agent/genkey.c b/agent/genkey.c index bb7e74e9b..9a8b3c2aa 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -207,7 +207,7 @@ do_check_passphrase_pattern (ctrl_t ctrl, const char *pw, unsigned int flags) if (gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDIN_PIPE, - NULL, NULL, &proc)) + NULL, &proc)) result = 1; /* Execute error - assume password should no be used. */ else { 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"); diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c index 2ec944c72..a6d58d3b2 100644 --- a/dirmngr/ldap-wrapper.c +++ b/dirmngr/ldap-wrapper.c @@ -851,7 +851,7 @@ ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) err = gnupg_process_spawn (pgmname, arg_list, (GNUPG_PROCESS_STDOUT_PIPE | GNUPG_PROCESS_STDERR_PIPE), - NULL, NULL, &process); + NULL, &process); if (err) { xfree (arg_list); diff --git a/g10/photoid.c b/g10/photoid.c index 8cc7e3a20..b226cbedd 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -601,7 +601,7 @@ run_with_pipe (struct spawn_info *info, const void *image, u32 len) fill_command_argv (argv, info->command); err = gnupg_process_spawn (argv[0], argv+1, GNUPG_PROCESS_STDIN_PIPE, - NULL, NULL, &proc); + NULL, &proc); if (err) log_error (_("unable to execute shell '%s': %s\n"), argv[0], gpg_strerror (err)); @@ -695,7 +695,7 @@ show_photo (const char *command, const char *name, const void *image, u32 len) const char *argv[4]; fill_command_argv (argv, spawn->command); - err = gnupg_process_spawn (argv[0], argv+1, 0, NULL, NULL, NULL); + err = gnupg_process_spawn (argv[0], argv+1, 0, NULL, NULL); if (err) log_error (_("unnatural exit of external program\n")); #endif @@ -2383,18 +2383,15 @@ app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr, return err; } - +#ifndef HAVE_W32_SYSTEM static void -setup_env (struct spawn_cb_arg *sca) +setup_env (void *arg) { -#ifdef HAVE_W32_SYSTEM - (void)sca; /* Not supported on Windows. */ -#else - char *v = sca->arg; + char *v = arg; putenv (v); -#endif } +#endif static void report_change (int slot, int old_status, int cur_status) @@ -2425,6 +2422,7 @@ report_change (int slot, int old_status, int cur_status) gpg_error_t err; const char *args[9]; char numbuf1[30], numbuf2[30], numbuf3[30]; + gnupg_spawn_actions_t act = NULL; sprintf (numbuf1, "%d", slot); sprintf (numbuf2, "0x%04X", old_status); @@ -2442,9 +2440,16 @@ report_change (int slot, int old_status, int cur_status) args[8] = NULL; fname = make_filename (gnupg_homedir (), "scd-event", NULL); - err = gnupg_process_spawn (fname, args, - GNUPG_PROCESS_DETACHED, - setup_env, envstr, NULL); + err = gnupg_spawn_actions_new (&act); + if (!err) + { +#ifndef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_atfork (act, setup_env, envstr); +#endif + err = gnupg_process_spawn (fname, args, GNUPG_PROCESS_DETACHED, + act, NULL); + gnupg_spawn_actions_release (act); + } if (err && gpg_err_code (err) != GPG_ERR_ENOENT) log_error ("failed to run event handler '%s': %s\n", fname, gpg_strerror (err)); diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index 36b0b98d2..510dc4088 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -938,7 +938,7 @@ do_process_spawn_io (scheme *sc, pointer args) } err = gnupg_process_spawn (argv[0], (const char **) &argv[1], - flags, NULL, NULL, &proc); + flags, NULL, &proc); err = gnupg_process_get_streams (proc, 0, &infp, NULL, NULL); err = es_write (infp, a_input, strlen (a_input), NULL); @@ -1137,25 +1137,6 @@ do_process_spawn_io (scheme *sc, pointer args) FFI_RETURN_ERR (sc, err); } -static void -setup_std_fds (struct spawn_cb_arg *sca) -{ - int *std_fds = sca->arg; - -#ifdef HAVE_W32_SYSTEM - sca->hd[0] = std_fds[0] == -1? - INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[0]); - sca->hd[1] = std_fds[1] == -1? - INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[1]); - sca->hd[2] = std_fds[2] == -1? - INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[2]); -#else - sca->fds[0] = std_fds[0]; - sca->fds[1] = std_fds[1]; - sca->fds[2] = std_fds[2]; -#endif -} - static pointer do_process_spawn_fd (scheme *sc, pointer args) { @@ -1165,6 +1146,7 @@ do_process_spawn_fd (scheme *sc, pointer args) size_t len; int std_fds[3]; gnupg_process_t proc = NULL; + gnupg_spawn_actions_t act = NULL; FFI_ARG_OR_RETURN (sc, pointer, arguments, list, args); FFI_ARG_OR_RETURN (sc, int, std_fds[0], number, args); @@ -1189,8 +1171,35 @@ do_process_spawn_fd (scheme *sc, pointer args) fprintf (stderr, " (%d %d %d)\n", std_fds[0], std_fds[1], std_fds[2]); } - err = gnupg_process_spawn (argv[0], (const char **) &argv[1], - 0, setup_std_fds, std_fds, &proc); + err = gnupg_spawn_actions_new (&act); + if (err) + { + FFI_RETURN_ERR (sc, err); + } +#ifdef HAVE_W32_SYSTEM + { + HANDLE std_in, std_out, std_err; + + if (std_fds[0] == -1) + std_in = INVALID_HANDLE_VALUE; + else + std_in = (HANDLE)_get_osfhandle (std_fds[0]); + if (std_fds[1] == -1) + std_out = INVALID_HANDLE_VALUE; + else + std_out = (HANDLE)_get_osfhandle (std_fds[1]); + if (std_fds[2] == -1) + std_err = INVALID_HANDLE_VALUE; + else + std_err = (HANDLE)_get_osfhandle (std_fds[2]); + + gnupg_spawn_actions_set_redirect (act, std_in, std_out, std_err); + } +#else + gnupg_spawn_actions_set_redirect (act, std_fds[0], std_fds[1], std_fds[2]); +#endif + err = gnupg_process_spawn (argv[0], (const char **)&argv[1], 0, act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); FFI_RETURN_POINTER (sc, proc_wrap (sc, proc)); } diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 8b3a3082b..3d66033bf 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -3835,7 +3835,7 @@ cmd_gpg (card_info_t info, char *argstr, int use_gpgsm) argv, (GNUPG_PROCESS_STDOUT_KEEP | GNUPG_PROCESS_STDERR_KEEP), - NULL, NULL, &proc); + NULL, &proc); if (!err) { err = gnupg_process_wait (proc, 1); diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index d6aa9d61b..b54b52c69 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -761,7 +761,7 @@ gpg_agent_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -805,7 +805,7 @@ scdaemon_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -850,7 +850,7 @@ tpm2daemon_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -885,7 +885,7 @@ dirmngr_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -919,7 +919,7 @@ keyboxd_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -985,7 +985,7 @@ gc_component_launch (int component) argv[i] = NULL; log_assert (i < DIM(argv)); - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -1369,9 +1369,8 @@ gc_component_check_options (int component, estream_t out, const char *conf_file) result = 0; errlines = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDERR_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDERR_PIPE, + NULL, &proc); if (err) result |= 1; /* Program could not be run. */ else @@ -1763,9 +1762,8 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) /* First we need to read the option table from the program. */ argv[0] = "--dump-option-table"; argv[1] = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDOUT_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDOUT_PIPE, + NULL, &proc); if (err) { gc_error (1, 0, "could not gather option table from '%s': %s", @@ -1952,9 +1950,8 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) /* Now read the default options. */ argv[0] = "--gpgconf-list"; argv[1] = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDOUT_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDOUT_PIPE, + NULL, &proc); if (err) { gc_error (1, 0, "could not gather active options from '%s': %s", diff --git a/tools/gpgconf.c b/tools/gpgconf.c index ac709ae21..301c1838f 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1311,9 +1311,8 @@ show_versions_via_dirmngr (estream_t fp) pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); argv[0] = "--gpgconf-versions"; argv[1] = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDOUT_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDOUT_PIPE, + NULL, &proc); if (err) { log_error ("error spawning %s: %s", pgmname, gpg_strerror (err)); diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 7af5a2ede..76eb47449 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1234,6 +1234,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, int except[2] = { -1, -1 }; #endif const char **argv; + gnupg_spawn_actions_t act = NULL; /* '--encrypt' may be combined with '--symmetric', but 'encrypt' * is set either way. Clear it if no recipients are specified. @@ -1296,11 +1297,23 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, goto leave; } + err = gnupg_spawn_actions_new (&act); + if (err) + { + xfree (argv); + goto leave; + } + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, except); +#else + gnupg_spawn_actions_set_inherit_fds (act, except); +#endif err = gnupg_process_spawn (opt.gpg_program, argv, (GNUPG_PROCESS_STDIN_PIPE | GNUPG_PROCESS_STDOUT_KEEP - | GNUPG_PROCESS_STDERR_KEEP), - gnupg_spawn_helper, except, &proc); + | GNUPG_PROCESS_STDERR_KEEP), act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); if (err) goto leave; diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 87113b054..e93ffdc37 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -390,6 +390,7 @@ gpgtar_extract (const char *filename, int decrypt) int except[2] = { -1, -1 }; #endif const char **argv; + gnupg_spawn_actions_t act = NULL; ccparray_init (&ccp, 0); if (opt.batch) @@ -435,10 +436,22 @@ gpgtar_extract (const char *filename, int decrypt) goto leave; } + err = gnupg_spawn_actions_new (&act); + if (err) + { + xfree (argv); + goto leave; + } + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, except); +#else + gnupg_spawn_actions_set_inherit_fds (act, except); +#endif err = gnupg_process_spawn (opt.gpg_program, argv, ((filename ? 0 : GNUPG_PROCESS_STDIN_KEEP) - | GNUPG_PROCESS_STDOUT_PIPE), - gnupg_spawn_helper, except, &proc); + | GNUPG_PROCESS_STDOUT_PIPE), act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); if (err) goto leave; diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index 0c5e474f3..55d9246af 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -474,6 +474,7 @@ gpgtar_list (const char *filename, int decrypt) int except[2] = { -1, -1 }; #endif const char **argv; + gnupg_spawn_actions_t act = NULL; ccparray_init (&ccp, 0); if (opt.batch) @@ -513,10 +514,22 @@ gpgtar_list (const char *filename, int decrypt) goto leave; } + err = gnupg_spawn_actions_new (&act); + if (err) + { + xfree (argv); + goto leave; + } + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, except); +#else + gnupg_spawn_actions_set_inherit_fds (act, except); +#endif err = gnupg_process_spawn (opt.gpg_program, argv, ((filename ? 0 : GNUPG_PROCESS_STDIN_KEEP) - | GNUPG_PROCESS_STDOUT_PIPE), - gnupg_spawn_helper, except, &proc); + | GNUPG_PROCESS_STDOUT_PIPE), act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); if (err) goto leave; |