summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2022-03-15 09:33:09 +0100
committerWerner Koch <wk@gnupg.org>2022-03-18 11:14:54 +0100
commit6d6438a361d25f3b269f702e017f5e39fd1f5c38 (patch)
treec44dbcafde60dfaa1bd49cad9ef456246dd0eaf8 /common
parentcommon: Fix a race condition removing stale lockfile. (diff)
downloadgnupg2-6d6438a361d25f3b269f702e017f5e39fd1f5c38.tar.xz
gnupg2-6d6438a361d25f3b269f702e017f5e39fd1f5c38.zip
common: New flags for gnupg_spawn_process
* common/exechelp.h (GNUPG_SPAWN_KEEP_STDIN): New. (GNUPG_SPAWN_KEEP_STDOUT): New. (GNUPG_SPAWN_KEEP_STDERR): New. * common/exechelp-posix.c (do_exec): Add arg flags and implement new flags. * common/exechelp-w32.c (gnupg_spawn_process): Implement new flags.
Diffstat (limited to 'common')
-rw-r--r--common/exechelp-posix.c19
-rw-r--r--common/exechelp-w32.c9
-rw-r--r--common/exechelp.h10
3 files changed, 29 insertions, 9 deletions
diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
index 77182cb9d..b4d10bf65 100644
--- a/common/exechelp-posix.c
+++ b/common/exechelp-posix.c
@@ -277,16 +277,21 @@ get_all_open_fds (void)
static void
do_exec (const char *pgmname, const char *argv[],
int fd_in, int fd_out, int fd_err,
- int *except, void (*preexec)(void) )
+ int *except, void (*preexec)(void), unsigned int flags)
{
char **arg_list;
int i, j;
int fds[3];
+ int nodevnull[3];
fds[0] = fd_in;
fds[1] = fd_out;
fds[2] = fd_err;
+ nodevnull[0] = !!(flags & GNUPG_SPAWN_KEEP_STDIN);
+ nodevnull[1] = !!(flags & GNUPG_SPAWN_KEEP_STDOUT);
+ nodevnull[2] = !!(flags & GNUPG_SPAWN_KEEP_STDERR);
+
/* Create the command line argument array. */
i = 0;
if (argv)
@@ -305,7 +310,9 @@ do_exec (const char *pgmname, const char *argv[],
/* Assign /dev/null to unused FDs. */
for (i=0; i <= 2; i++)
{
- if (fds[i] == -1 )
+ if (nodevnull[i])
+ continue;
+ if (fds[i] == -1)
{
fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
if (fds[i] == -1)
@@ -317,6 +324,8 @@ do_exec (const char *pgmname, const char *argv[],
/* Connect the standard files. */
for (i=0; i <= 2; i++)
{
+ if (nodevnull[i])
+ continue;
if (fds[i] != i && dup2 (fds[i], i) == -1)
log_fatal ("dup2 std%s failed: %s\n",
i==0?"in":i==1?"out":"err", strerror (errno));
@@ -535,7 +544,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
es_fclose (outfp);
es_fclose (errfp);
do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
- except, preexec);
+ except, preexec, flags);
/*NOTREACHED*/
}
@@ -585,7 +594,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
{
gcry_control (GCRYCTL_TERM_SECMEM);
/* Run child. */
- do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL);
+ do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL, 0);
/*NOTREACHED*/
}
@@ -884,7 +893,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
for (i=0; envp[i]; i++)
putenv (xstrdup (envp[i]));
- do_exec (pgmname, argv, -1, -1, -1, NULL, NULL);
+ do_exec (pgmname, argv, -1, -1, -1, NULL, NULL, 0);
/*NOTREACHED*/
}
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c
index dee96f5b4..9529c57a0 100644
--- a/common/exechelp-w32.c
+++ b/common/exechelp-w32.c
@@ -556,11 +556,14 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
return err;
if (inpipe[0] == INVALID_HANDLE_VALUE)
- nullhd[0] = w32_open_null (0);
+ nullhd[0] = ((flags & GNUPG_SPAWN_KEEP_STDIN)?
+ GetStdHandle (STD_INPUT_HANDLE) : w32_open_null (0));
if (outpipe[1] == INVALID_HANDLE_VALUE)
- nullhd[1] = w32_open_null (1);
+ nullhd[1] = ((flags & GNUPG_SPAWN_KEEP_STDOUT)?
+ GetStdHandle (STD_OUTPUT_HANDLE) : w32_open_null (1));
if (errpipe[1] == INVALID_HANDLE_VALUE)
- nullhd[2] = w32_open_null (1);
+ nullhd[2] = ((flags & GNUPG_SPAWN_KEEP_STDOUT)?
+ GetStdHandle (STD_ERROR_HANDLE) : w32_open_null (1));
/* Start the process. Note that we can't run the PREEXEC function
because this might change our own environment. */
diff --git a/common/exechelp.h b/common/exechelp.h
index d50e378e7..735ea4728 100644
--- a/common/exechelp.h
+++ b/common/exechelp.h
@@ -76,7 +76,9 @@ void gnupg_close_pipe (int fd);
#define GNUPG_SPAWN_NONBLOCK 16
#define GNUPG_SPAWN_RUN_ASFW 64
#define GNUPG_SPAWN_DETACHED 128
-
+#define GNUPG_SPAWN_KEEP_STDIN 256
+#define GNUPG_SPAWN_KEEP_STDOUT 512
+#define GNUPG_SPAWN_KEEP_STDERR 1024
/* Fork and exec the program PGMNAME.
@@ -122,6 +124,12 @@ void gnupg_close_pipe (int fd);
the child. Note that due to unknown problems this actually
allows SetForegroundWindow for all children of this process.
+ GNUPG_SPAWN_KEEP_STDIN
+ GNUPG_SPAWN_KEEP_STDOUT
+ GNUPG_SPAWN_KEEP_STDERR
+ Do not assign /dev/null to a non-required standard file
+ descriptor.
+
*/
gpg_error_t
gnupg_spawn_process (const char *pgmname, const char *argv[],