1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

common,tools,dirmngr: Introduce gnupg_process_spawn.

--

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2022-11-17 14:12:51 +09:00
parent 18a3ce1c9b
commit 729951f4c2
No known key found for this signature in database
GPG key ID: 640114AF89DE6054
12 changed files with 1629 additions and 140 deletions

View file

@ -301,6 +301,38 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink)
}
static int
close_all_except (struct spawn_cb_arg *arg)
{
int except[32];
int i = 0;
int fd_in = arg->std_fds[0];
int fd_out = arg->std_fds[1];
int fd_err = arg->std_fds[2];
int *exceptclose = arg->arg;
if (fd_in >= 0)
except[i++] = fd_in;
if (fd_out >= 0)
except[i++] = fd_out;
if (fd_err >= 0)
except[i++] = fd_err;
for (; i < 31; i++)
{
int fd = *exceptclose++;
if (fd < 0)
break;
else
except[i] = fd;
}
except[i++] = -1;
close_all_fds (3, except);
return 1;
}
/* Run the program PGMNAME with the command line arguments given in
* the NULL terminates array ARGV. If INPUT is not NULL it will be
@ -321,7 +353,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
void *status_cb_value)
{
gpg_error_t err;
pid_t pid = (pid_t) -1;
gnupg_process_t proc = NULL;
estream_t infp = NULL;
estream_t extrafp = NULL;
estream_t outfp = NULL, errfp = NULL;
@ -335,7 +367,6 @@ 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;
int dummy_exitcode;
memset (fds, 0, sizeof fds);
memset (&fderrstate, 0, sizeof fderrstate);
@ -411,10 +442,15 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
else
exceptclose[0] = -1;
err = gnupg_spawn_process (pgmname, argv,
exceptclose, GNUPG_SPAWN_NONBLOCK,
input? &infp : NULL,
&outfp, &errfp, &pid);
err = gnupg_process_spawn (pgmname, argv,
((input
? GNUPG_PROCESS_STDIN_PIPE
: GNUPG_PROCESS_STDIN_NULL)
| GNUPG_PROCESS_STDOUT_PIPE
| GNUPG_PROCESS_STDERR_PIPE),
close_all_except, exceptclose, &proc);
gnupg_process_get_streams (proc, GNUPG_PROCESS_STREAM_NONBLOCK,
input? &infp : NULL, &outfp, &errfp);
if (extrapipe[0] != -1)
close (extrapipe[0]);
if (argsave)
@ -546,20 +582,25 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
es_fclose (outfp); outfp = NULL;
es_fclose (errfp); errfp = NULL;
err = gnupg_wait_process (pgmname, pid, 1, quiet? &dummy_exitcode : NULL);
pid = (pid_t)(-1);
err = gnupg_process_wait (proc, 1);
if (!err)
{ /* To be compatible to old wait_process. */
int status;
gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &status);
if (status)
err = gpg_error (GPG_ERR_GENERAL);
}
leave:
if (err && pid != (pid_t) -1)
gnupg_kill_process (pid);
if (err && proc)
gnupg_process_terminate (proc);
es_fclose (infp);
es_fclose (extrafp);
es_fclose (outfp);
es_fclose (errfp);
if (pid != (pid_t)(-1))
gnupg_wait_process (pgmname, pid, 1, quiet? &dummy_exitcode : NULL);
gnupg_release_process (pid);
gnupg_process_release (proc);
copy_buffer_shred (cpbuf_in);
xfree (cpbuf_in);