mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
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>
This commit is contained in:
parent
34045ed9e1
commit
fc3fde1bde
17 changed files with 351 additions and 181 deletions
|
@ -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*/
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue