diff options
author | Werner Koch <[email protected]> | 2015-09-28 16:10:21 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2015-09-28 16:40:38 +0000 |
commit | 83811e3f1f0c615b2b63bafdb49a35a0fc198088 (patch) | |
tree | 676f6c145331d2911969ad01db7fcea6f6132c80 /common/exechelp-posix.c | |
parent | scd: Handle error correctly. (diff) | |
download | gnupg-83811e3f1f0c615b2b63bafdb49a35a0fc198088.tar.gz gnupg-83811e3f1f0c615b2b63bafdb49a35a0fc198088.zip |
common: Change calling convention for gnupg_spawn_process.
* common/exechelp.h (GNUPG_SPAWN_NONBLOCK): New.
(GNUPG_SPAWN_RUN_ASFW, GNUPG_SPAWN_DETACHED): Macro to replace the
numbers.
* common/exechelp.h (gnupg_spawn_process): Change function to not take
an optional stream for stdin but to return one.
* common/exechelp-posix.c (gnupg_spawn_process): Implement change.
(create_pipe_and_estream): Add args outbound and nonblock.
* common/exechelp-w32.c (gnupg_spawn_process): Implement change.
--
In 2.1 this function is only used at one place and the stdin parameter
is not used. Thus this change is trivial for the callers but along
with estream's new es_poll it is overall simpler to use.
Note that the Windows version has not been tested.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'common/exechelp-posix.c')
-rw-r--r-- | common/exechelp-posix.c | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 8a2b3b9c2..2bf2592e0 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -313,6 +313,7 @@ gnupg_create_outbound_pipe (int filedes[2]) static gpg_error_t create_pipe_and_estream (int filedes[2], estream_t *r_fp, + int outbound, int nonblock, gpg_err_source_t errsource) { gpg_error_t err; @@ -326,7 +327,10 @@ create_pipe_and_estream (int filedes[2], estream_t *r_fp, return err; } - *r_fp = es_fdopen (filedes[0], "r"); + if (outbound) + *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r"); + else + *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w"); if (!*r_fp) { err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); @@ -347,53 +351,70 @@ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], gpg_err_source_t errsource, void (*preexec)(void), unsigned int flags, - estream_t infp, + estream_t *r_infp, estream_t *r_outfp, estream_t *r_errfp, pid_t *pid) { gpg_error_t err; - int infd = -1; + int inpipe[2] = {-1, -1}; int outpipe[2] = {-1, -1}; int errpipe[2] = {-1, -1}; + estream_t infp = NULL; estream_t outfp = NULL; estream_t errfp = NULL; + int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK); - (void)flags; /* Currently not used. */ - + if (r_infp) + *r_infp = NULL; if (r_outfp) *r_outfp = NULL; if (r_errfp) *r_errfp = NULL; *pid = (pid_t)(-1); /* Always required. */ - if (infp) + if (r_infp) { - es_fflush (infp); - es_rewind (infp); - infd = es_fileno (infp); - if (infd == -1) - return gpg_err_make (errsource, GPG_ERR_INV_VALUE); + err = create_pipe_and_estream (inpipe, &infp, 0, nonblock, errsource); + if (err) + return err; } if (r_outfp) { - err = create_pipe_and_estream (outpipe, &outfp, errsource); + err = create_pipe_and_estream (outpipe, &outfp, 1, nonblock, errsource); if (err) - return err; + { + if (infp) + es_fclose (infp); + else if (inpipe[1] != -1) + close (inpipe[1]); + if (inpipe[0] != -1) + close (inpipe[0]); + + return err; + } } if (r_errfp) { - err = create_pipe_and_estream (errpipe, &errfp, errsource); + err = create_pipe_and_estream (errpipe, &errfp, 1, nonblock, errsource); if (err) { + if (infp) + es_fclose (infp); + else if (inpipe[1] != -1) + close (inpipe[1]); + if (inpipe[0] != -1) + close (inpipe[0]); + if (outfp) es_fclose (outfp); else if (outpipe[0] != -1) close (outpipe[0]); if (outpipe[1] != -1) close (outpipe[1]); + return err; } } @@ -405,6 +426,13 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); log_error (_("error forking process: %s\n"), gpg_strerror (err)); + if (infp) + es_fclose (infp); + else if (inpipe[1] != -1) + close (inpipe[1]); + if (inpipe[0] != -1) + close (inpipe[0]); + if (outfp) es_fclose (outfp); else if (outpipe[0] != -1) @@ -427,16 +455,20 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], gcry_control (GCRYCTL_TERM_SECMEM); es_fclose (outfp); es_fclose (errfp); - do_exec (pgmname, argv, infd, outpipe[1], errpipe[1], preexec); + do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], preexec); /*NOTREACHED*/ } /* This is the parent. */ + if (inpipe[0] != -1) + close (inpipe[0]); if (outpipe[1] != -1) close (outpipe[1]); if (errpipe[1] != -1) close (errpipe[1]); + if (r_infp) + *r_infp = infp; if (r_outfp) *r_outfp = outfp; if (r_errfp) |