From 34fa2d79a07a079be472c3ff486debfdac8c6070 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Wed, 18 Jan 2017 18:14:41 +0100 Subject: common: Fix flushing copy buffers. * common/exectool.c (copy_buffer_flush): Write and flush the data, but do not hide EAGAIN from the caller. (gnupg_exec_tool_stream): Retry on EAGAIN. GnuPG-bug-id: 2425 Signed-off-by: Justus Winter --- common/exectool.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'common/exectool.c') diff --git a/common/exectool.c b/common/exectool.c index 4593abdc2..0067fc63a 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -276,15 +276,23 @@ static gpg_error_t copy_buffer_flush (struct copy_buffer *c, estream_t sink) { gpg_error_t err; + size_t nwritten; - while (c->nread > 0) - { - err = copy_buffer_do_copy (c, NULL, sink); - if (err) - return err; - } + nwritten = 0; + err = es_write (sink, c->writep, c->nread, &nwritten); + + assert (nwritten <= c->nread); + c->writep += nwritten; + c->nread -= nwritten; + assert (c->writep - c->buffer <= sizeof c->buffer); + + if (err) + return err; - return 0; + if (es_fflush (sink)) + err = my_error_from_syserror (); + + return err; } @@ -444,6 +452,8 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], if (es_feof (input)) { err = copy_buffer_flush (cpbuf_in, fds[0].stream); + if (err == GPG_ERR_EAGAIN) + continue; /* Retry next time. */ if (err) { log_error ("error feeding data to '%s': %s\n", @@ -470,6 +480,8 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], if (es_feof (inextra)) { err = copy_buffer_flush (cpbuf_extra, fds[3].stream); + if (err == GPG_ERR_EAGAIN) + continue; /* Retry next time. */ if (err) { log_error ("error feeding data to '%s': %s\n", -- cgit v1.2.3