diff options
author | Justus Winter <[email protected]> | 2017-01-12 13:05:15 +0000 |
---|---|---|
committer | Justus Winter <[email protected]> | 2017-01-16 11:48:56 +0000 |
commit | 0e242278dfaa64ce31a45b72f5fa0806a3dba898 (patch) | |
tree | c5558bcf1e4ae46f090c99918fddbe046ee788f0 /src/engine-gpgconf.c | |
parent | tests: Improve the gpgconf test. (diff) | |
download | gpgme-0e242278dfaa64ce31a45b72f5fa0806a3dba898.tar.gz gpgme-0e242278dfaa64ce31a45b72f5fa0806a3dba898.zip |
Fix changing options with gpgconf.
* src/engine-gpgconf.c (gpgconf_write): Connect a pipe to the child's
stderr, and wait for it to be closed as an indication that gpgconf has
exited. Also improve error handling.
GnuPG-bug-id: 2881
Signed-off-by: Justus Winter <[email protected]>
Diffstat (limited to 'src/engine-gpgconf.c')
-rw-r--r-- | src/engine-gpgconf.c | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c index 01a60eb1..3e463105 100644 --- a/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -710,8 +710,11 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf) int buflen = 0; char *argv[7]; int argc = 0; - int rp[2]; - struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */}, {-1, -1} }; + int rp[2] = { -1, -1 }; + int errp[2] = { -1, -1 }; + struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */}, + {-1, 2 /* STDERR_FILENO */, -1}, + {-1, -1} }; int status; int nwrite; @@ -731,19 +734,31 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf) assert (argc < DIM (argv)); if (_gpgme_io_pipe (rp, 0) < 0) - return gpg_error_from_syserror (); + { + err = gpg_error_from_syserror (); + goto leave; + } + + if (_gpgme_io_pipe (errp, 1) < 0) + { + err = gpg_error_from_syserror (); + goto leave; + } cfd[0].fd = rp[0]; + cfd[1].fd = errp[1]; status = _gpgme_io_spawn (gpgconf->file_name, argv, IOSPAWN_FLAG_DETACHED, cfd, NULL, NULL, NULL); if (status < 0) { - _gpgme_io_close (rp[0]); - _gpgme_io_close (rp[1]); - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; } + rp[0] = -1; + errp[1] = -1; + for (;;) { if (buflen == 0) @@ -757,14 +772,29 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf) if (buflen < 0) { err = gpg_error_from_syserror (); - _gpgme_io_close (rp[1]); - return err; + goto leave; } else if (buflen == 0) { /* All is written. */ _gpgme_io_close (rp[1]); - return 0; + rp[1] = -1; + + for (;;) + { + do + { + buflen = _gpgme_io_read (errp[0], buf, BUFLEN); + } + while (buflen < 0 && errno == EAGAIN); + + if (buflen == 0) + { + err = 0; + goto leave; + } + /* XXX: Do something useful with BUF. */ + } } } @@ -782,12 +812,24 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf) } else if (nwrite < 0) { - _gpgme_io_close (rp[1]); - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; } } - return 0; + assert (! "reached"); + + leave: + if (rp[0] != -1) + _gpgme_io_close (rp[0]); + if (rp[1] != -1) + _gpgme_io_close (rp[1]); + if (errp[0] != -1) + _gpgme_io_close (errp[0]); + if (errp[1] != -1) + _gpgme_io_close (errp[1]); + + return err; } |