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 | |
| 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]>
| -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;  } | 
