common: Fix flushing copy buffers.
authorJustus Winter <justus@g10code.com>
Wed, 18 Jan 2017 17:14:41 +0000 (18:14 +0100)
committerJustus Winter <justus@g10code.com>
Wed, 18 Jan 2017 17:24:51 +0000 (18:24 +0100)
* 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 <justus@g10code.com>
common/exectool.c

index 4593abd..0067fc6 100644 (file)
@@ -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;
 }
 
 \f
@@ -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",