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 <justus@g10code.com>
This commit is contained in:
parent
186dcd3494
commit
0e242278df
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user