summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/genkey.c2
-rw-r--r--common/asshelp.c5
-rw-r--r--common/exechelp-posix.c142
-rw-r--r--common/exechelp-w32.c159
-rw-r--r--common/exechelp.h37
-rw-r--r--common/exectool.c14
-rw-r--r--common/t-exechelp.c2
-rw-r--r--dirmngr/ldap-wrapper.c2
-rw-r--r--g10/photoid.c4
-rw-r--r--scd/app.c25
-rw-r--r--tests/gpgscm/ffi.c53
-rw-r--r--tools/gpg-card.c2
-rw-r--r--tools/gpgconf-comp.c27
-rw-r--r--tools/gpgconf.c5
-rw-r--r--tools/gpgtar-create.c17
-rw-r--r--tools/gpgtar-extract.c17
-rw-r--r--tools/gpgtar-list.c17
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
diff --git a/scd/app.c b/scd/app.c
index a9591a12c..09a148416 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -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;