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.
This commit is contained in:
Werner Koch 2022-03-15 09:33:09 +01:00
parent e8b1ab1d2d
commit 7ba44d15ca
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 29 additions and 9 deletions

View File

@ -276,16 +276,21 @@ get_all_open_fds (void)
static void static void
do_exec (const char *pgmname, const char *argv[], do_exec (const char *pgmname, const char *argv[],
int fd_in, int fd_out, int fd_err, 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; char **arg_list;
int i, j; int i, j;
int fds[3]; int fds[3];
int nodevnull[3];
fds[0] = fd_in; fds[0] = fd_in;
fds[1] = fd_out; fds[1] = fd_out;
fds[2] = fd_err; 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. */ /* Create the command line argument array. */
i = 0; i = 0;
if (argv) if (argv)
@ -304,7 +309,9 @@ do_exec (const char *pgmname, const char *argv[],
/* Assign /dev/null to unused FDs. */ /* Assign /dev/null to unused FDs. */
for (i=0; i <= 2; i++) 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); fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
if (fds[i] == -1) if (fds[i] == -1)
@ -316,6 +323,8 @@ do_exec (const char *pgmname, const char *argv[],
/* Connect the standard files. */ /* Connect the standard files. */
for (i=0; i <= 2; i++) for (i=0; i <= 2; i++)
{ {
if (nodevnull[i])
continue;
if (fds[i] != i && dup2 (fds[i], i) == -1) if (fds[i] != i && dup2 (fds[i], i) == -1)
log_fatal ("dup2 std%s failed: %s\n", log_fatal ("dup2 std%s failed: %s\n",
i==0?"in":i==1?"out":"err", strerror (errno)); i==0?"in":i==1?"out":"err", strerror (errno));
@ -525,7 +534,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
es_fclose (outfp); es_fclose (outfp);
es_fclose (errfp); es_fclose (errfp);
do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
except, preexec); except, preexec, flags);
/*NOTREACHED*/ /*NOTREACHED*/
} }
@ -575,7 +584,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
{ {
gcry_control (GCRYCTL_TERM_SECMEM); gcry_control (GCRYCTL_TERM_SECMEM);
/* Run child. */ /* Run child. */
do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL); do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL, 0);
/*NOTREACHED*/ /*NOTREACHED*/
} }
@ -874,7 +883,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
for (i=0; envp[i]; i++) for (i=0; envp[i]; i++)
putenv (xstrdup (envp[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*/ /*NOTREACHED*/
} }

View File

@ -544,11 +544,14 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
return err; return err;
if (inpipe[0] == INVALID_HANDLE_VALUE) 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) 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) 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 /* Start the process. Note that we can't run the PREEXEC function
because this might change our own environment. */ because this might change our own environment. */

View File

@ -71,7 +71,9 @@ gpg_error_t gnupg_create_pipe (int filedes[2]);
#define GNUPG_SPAWN_NONBLOCK 16 #define GNUPG_SPAWN_NONBLOCK 16
#define GNUPG_SPAWN_RUN_ASFW 64 #define GNUPG_SPAWN_RUN_ASFW 64
#define GNUPG_SPAWN_DETACHED 128 #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. /* Fork and exec the program PGMNAME.
@ -117,6 +119,12 @@ gpg_error_t gnupg_create_pipe (int filedes[2]);
the child. Note that due to unknown problems this actually the child. Note that due to unknown problems this actually
allows SetForegroundWindow for all children of this process. 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 gpg_error_t
gnupg_spawn_process (const char *pgmname, const char *argv[], gnupg_spawn_process (const char *pgmname, const char *argv[],