[git] GnuPG - branch, master, updated. gnupg-2.1.12-37-g239a4d5

by Werner Koch cvs at cvs.gnupg.org
Sat May 28 00:10:16 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  239a4d53916b47b5b0f0167a9b2c7a8915bb9c52 (commit)
       via  44a32455c8e41400ea96db4507c8a42bdb65b3b6 (commit)
      from  e6d9a2d07ed7aeac3944d8a7d1317c4a117356b4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 239a4d53916b47b5b0f0167a9b2c7a8915bb9c52
Author: Werner Koch <wk at gnupg.org>
Date:   Sat May 28 00:07:09 2016 +0200

    common: Add a status callback to gnupg_exec_tool_stream.
    
    * common/exectool.h (exec_tool_status_cb_t): New.
    * common/exectool.c: Include missing exectool.h.
    (read_and_log_buffer_t): Replace array by pointer.
    (gnupg_exec_tool_stream): Add args 'status_cb' and 'status_cb_value'.
    Change all callers to pass NULL for them.  Malloc buffer for
    FDERRSTATE.
    (read_and_log_stderr): Implement status_fd feature.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/common/exectool.c b/common/exectool.c
index 953c34a..897450e 100644
--- a/common/exectool.c
+++ b/common/exectool.c
@@ -44,13 +44,17 @@
 #include "exechelp.h"
 #include "sysutils.h"
 #include "util.h"
+#include "exectool.h"
 
 typedef struct
 {
   const char *pgmname;
+  exec_tool_status_cb_t status_cb;
+  void *status_cb_value;
   int cont;
-  int used;
-  char buffer[256];
+  size_t used;
+  size_t buffer_size;
+  char *buffer;
 } read_and_log_buffer_t;
 
 
@@ -83,14 +87,37 @@ read_and_log_stderr (read_and_log_buffer_t *state, es_poll_t *fderr)
             pname++;
           else
             pname = state->pgmname;
-          /* If our pgmname plus colon is identical to the start of
-             the output, print only the output.  */
           len = strlen (pname);
-          if (!state->cont
+
+          if (state->status_cb
+              && !strncmp (state->buffer, "[GNUPG:] ", 9)
+              && state->buffer[9] >= 'A' && state->buffer[9] <= 'Z')
+            {
+              char *rest;
+
+              rest = strchr (state->buffer + 9, ' ');
+              if (!rest)
+                {
+                  /* Set REST to an empty string.  */
+                  rest = state->buffer + strlen (state->buffer);
+                }
+              else
+                {
+                  *rest++ = 0;
+                  trim_spaces (rest);
+                }
+              state->status_cb (state->status_cb_value,
+                                state->buffer + 9, rest);
+            }
+          else if (!state->cont
               && !strncmp (state->buffer, pname, len)
               && strlen (state->buffer) > strlen (pname)
               && state->buffer[len] == ':' )
-            log_info ("%s\n", state->buffer);
+            {
+              /* PGMNAME plus colon is identical to the start of
+                 the output: print only the output.  */
+              log_info ("%s\n", state->buffer);
+            }
           else
             log_info ("%s%c %s\n",
                       pname, state->cont? '+':':', state->buffer);
@@ -123,10 +150,39 @@ read_and_log_stderr (read_and_log_buffer_t *state, es_poll_t *fderr)
         }
       else
         {
-          if (state->used >= sizeof state->buffer - 1)
+          if (state->used >= state->buffer_size - 1)
             {
-              read_and_log_stderr (state, NULL);
-              state->cont = 1;
+              if (state->status_cb)
+                {
+                  /* A status callback requires that we have a full
+                   * line.  Thus we need to enlarget the buffer in
+                   * this case.  */
+                  char *newbuffer;
+                  size_t newsize = state->buffer_size + 256;
+
+                  newbuffer = xtrymalloc (newsize);
+                  if (!newbuffer)
+                    {
+                      log_error ("error allocating memory for status cb: %s\n",
+                                 gpg_strerror (my_error_from_syserror ()));
+                      /* We better disable the status CB in this case.  */
+                      state->status_cb = NULL;
+                      read_and_log_stderr (state, NULL);
+                      state->cont = 1;
+                    }
+                  else
+                    {
+                      memcpy (newbuffer, state->buffer, state->used);
+                      xfree (state->buffer);
+                      state->buffer = newbuffer;
+                      state->buffer_size = newsize;
+                    }
+                }
+              else
+                {
+                  read_and_log_stderr (state, NULL);
+                  state->cont = 1;
+                }
             }
           state->buffer[state->used++] = c;
         }
@@ -242,7 +298,9 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink)
 gpg_error_t
 gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
                         estream_t input, estream_t inextra,
-                        estream_t output)
+                        estream_t output,
+                        exec_tool_status_cb_t status_cb,
+                        void *status_cb_value)
 {
   gpg_error_t err;
   pid_t pid;
@@ -265,6 +323,14 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
   copy_buffer_init (&cpbuf_out);
   copy_buffer_init (&cpbuf_extra);
 
+  fderrstate.pgmname = pgmname;
+  fderrstate.status_cb = status_cb;
+  fderrstate.status_cb_value = status_cb_value;
+  fderrstate.buffer_size = 256;
+  fderrstate.buffer = xtrymalloc (fderrstate.buffer_size);
+  if (!fderrstate.buffer)
+    return my_error_from_syserror ();
+
   if (inextra)
     {
       err = gnupg_create_outbound_pipe (extrapipe, &extrafp, 1);
@@ -272,6 +338,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
         {
           log_error ("error running outbound pipe for extra fp: %s\n",
                      gpg_strerror (err));
+          xfree (fderrstate.buffer);
           return err;
         }
       exceptclose[0] = extrapipe[0]; /* Do not close in child. */
@@ -303,11 +370,10 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
     {
       log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err));
       es_fclose (extrafp);
+      xfree (fderrstate.buffer);
       return err;
     }
 
-  fderrstate.pgmname = pgmname;
-
   fds[0].stream = infp;
   fds[0].want_write = 1;
   if (!input)
@@ -438,6 +504,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
   copy_buffer_shred (&cpbuf_out);
   if (inextra)
     copy_buffer_shred (&cpbuf_extra);
+  xfree (fderrstate.buffer);
   return err;
 }
 
@@ -488,7 +555,7 @@ gnupg_exec_tool (const char *pgmname, const char *argv[],
       goto leave;
     }
 
-  err = gnupg_exec_tool_stream (pgmname, argv, input, NULL, output);
+  err = gnupg_exec_tool_stream (pgmname, argv, input, NULL, output, NULL, NULL);
   if (err)
     goto leave;
 
diff --git a/common/exectool.h b/common/exectool.h
index 21bc177..94091fd 100644
--- a/common/exectool.h
+++ b/common/exectool.h
@@ -32,6 +32,17 @@
 
 #include <gpg-error.h>
 
+/* This callback can be used to process --status-fd outputs of GnuPG
+ * tools.  OPAQUE can be used to communicate between the caller of the
+ * function and the callback.  KEYWORD is the status keyword (see
+ * doc/DETAILS); it is never NULL.  ARGS are the arguments of the
+ * status line and will also never be NULL; the caller may modify this
+ * string.  */
+typedef void (*exec_tool_status_cb_t) (void *opaque,
+                                       const char *keyword,
+                                       char *args);
+
+
 /* Run the program PGMNAME with the command line arguments given in
    the NULL terminates array ARGV.  If INPUT_STRING is not NULL it
    will be fed to stdin of the process.  stderr is logged using
@@ -51,6 +62,8 @@ gpg_error_t gnupg_exec_tool (const char *pgmname, const char *argv[],
    printed, and an error code returned.  INEXTRA is reserved. */
 gpg_error_t gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
                                     estream_t input, estream_t inextra,
-                                    estream_t output);
+                                    estream_t output,
+                                    exec_tool_status_cb_t status_cb,
+                                    void *status_cb_value);
 
 #endif /* GNUPG_COMMON_EXECTOOL_H */
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
index d615fd3..6adc1f5 100644
--- a/tools/gpgtar-create.c
+++ b/tools/gpgtar-create.c
@@ -932,7 +932,7 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
         }
 
       err = gnupg_exec_tool_stream (opt.gpg_program, argv,
-                                    outstream, NULL, cipher_stream);
+                                    outstream, NULL, cipher_stream, NULL, NULL);
       xfree (argv);
       if (err)
         goto leave;
diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
index c4bf440..866215b 100644
--- a/tools/gpgtar-extract.c
+++ b/tools/gpgtar-extract.c
@@ -327,7 +327,7 @@ gpgtar_extract (const char *filename, int decrypt)
         }
 
       err = gnupg_exec_tool_stream (opt.gpg_program, argv,
-                                    cipher_stream, NULL, stream);
+                                    cipher_stream, NULL, stream, NULL, NULL);
       xfree (argv);
       if (err)
         goto leave;
diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c
index a3f85ac..1d59d9c 100644
--- a/tools/gpgtar-list.c
+++ b/tools/gpgtar-list.c
@@ -327,7 +327,7 @@ gpgtar_list (const char *filename, int decrypt)
         }
 
       err = gnupg_exec_tool_stream (opt.gpg_program, argv,
-                                    cipher_stream, NULL, stream);
+                                    cipher_stream, NULL, stream, NULL, NULL);
       xfree (argv);
       if (err)
         goto leave;

commit 44a32455c8e41400ea96db4507c8a42bdb65b3b6
Author: Werner Koch <wk at gnupg.org>
Date:   Fri May 27 22:48:04 2016 +0200

    common: Allow a second input stream for gnupg_exec_tool_stream.
    
    * common/exechelp-posix.c (do_exec): Add arg 'except' and pass to
    close_all_fds.
    (gnupg_spawn_process): Add arg 'except'.  Change callers to pass NULL
    for it.
    * common/exechelp-w32.c (gnupg_spawn_process): Add dummy arg 'except'.
    * common/exechelp-w32ce.c (gnupg_spawn_process): Ditto.
    * common/exectool.c (copy_buffer_do_copy): Allow NULL for SINK.
    (gnupg_exec_tool_stream): Add arg 'inextra'. Change callers to pass
    NULL for it.  Allow NULL for OUTPUT.
    --
    
    This hack is a first step to allow calling gpg for verification of
    signatures.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
index a7a9a92..aefb653 100644
--- a/common/exechelp-posix.c
+++ b/common/exechelp-posix.c
@@ -278,7 +278,7 @@ get_all_open_fds (void)
 static void
 do_exec (const char *pgmname, const char *argv[],
          int fd_in, int fd_out, int fd_err,
-         void (*preexec)(void) )
+         int *except, void (*preexec)(void) )
 {
   char **arg_list;
   int i, j;
@@ -324,7 +324,7 @@ do_exec (const char *pgmname, const char *argv[],
     }
 
   /* Close all other files. */
-  close_all_fds (3, NULL);
+  close_all_fds (3, except);
 
   if (preexec)
     preexec ();
@@ -420,7 +420,7 @@ gnupg_create_pipe (int filedes[2])
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     void (*preexec)(void), unsigned int flags,
+                     int *except, void (*preexec)(void), unsigned int flags,
                      estream_t *r_infp,
                      estream_t *r_outfp,
                      estream_t *r_errfp,
@@ -525,7 +525,8 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
       gcry_control (GCRYCTL_TERM_SECMEM);
       es_fclose (outfp);
       es_fclose (errfp);
-      do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], preexec);
+      do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
+               except, preexec);
       /*NOTREACHED*/
     }
 
@@ -575,7 +576,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
     {
       gcry_control (GCRYCTL_TERM_SECMEM);
       /* Run child. */
-      do_exec (pgmname, argv, infd, outfd, errfd, NULL);
+      do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL);
       /*NOTREACHED*/
     }
 
@@ -728,7 +729,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
         for (i=0; envp[i]; i++)
           putenv (xstrdup (envp[i]));
 
-      do_exec (pgmname, argv, -1, -1, -1, NULL);
+      do_exec (pgmname, argv, -1, -1, -1, NULL, NULL);
 
       /*NOTREACHED*/
     }
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c
index a8a8b45..b2d2457 100644
--- a/common/exechelp-w32.c
+++ b/common/exechelp-w32.c
@@ -357,7 +357,7 @@ gnupg_create_pipe (int filedes[2])
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     void (*preexec)(void), unsigned int flags,
+                     int *except, void (*preexec)(void), unsigned int flags,
                      estream_t *r_infp,
                      estream_t *r_outfp,
                      estream_t *r_errfp,
@@ -388,6 +388,8 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
   es_syshd_t syshd;
   gpg_err_source_t errsource = default_errsource;
 
+  (void)except; /* Not yet used.  */
+
   if (r_infp)
     *r_infp = NULL;
   if (r_outfp)
diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c
index 06aa6bc..9e72cef 100644
--- a/common/exechelp-w32ce.c
+++ b/common/exechelp-w32ce.c
@@ -515,7 +515,7 @@ create_process (const char *pgmname, const char *cmdline,
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     void (*preexec)(void), unsigned int flags,
+                     int *except, void (*preexec)(void), unsigned int flags,
                      estream_t *r_infp,
                      estream_t *r_outfp,
                      estream_t *r_errfp,
@@ -541,6 +541,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
   estream_t errfp = NULL;
   gpg_err_source_t errsource = default_errsource;
 
+  (void)except; /* Not yet used.  */
   (void)preexec;
   (void)flags;
 
diff --git a/common/exechelp.h b/common/exechelp.h
index d6ef5f0..c43cd25 100644
--- a/common/exechelp.h
+++ b/common/exechelp.h
@@ -90,6 +90,10 @@ gpg_error_t gnupg_create_pipe (int filedes[2]);
    If PREEXEC is not NULL, the given function will be called right
    before the exec.
 
+   IF EXCEPT is not NULL, it is expected to be an ordered list of file
+   descriptors, terminated by an entry with the value (-1).  These
+   file descriptors won't be closed before spawning a new program.
+
    Returns 0 on success or an error code.  Calling gnupg_wait_process
    and gnupg_release_process is required if the function succeeded.
 
@@ -116,7 +120,7 @@ gpg_error_t gnupg_create_pipe (int filedes[2]);
  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     void (*preexec)(void), unsigned int flags,
+                     int *execpt, void (*preexec)(void), unsigned int flags,
                      estream_t *r_infp,
                      estream_t *r_outfp,
                      estream_t *r_errfp,
diff --git a/common/exectool.c b/common/exectool.c
index 9ba336d..953c34a 100644
--- a/common/exectool.c
+++ b/common/exectool.c
@@ -188,7 +188,8 @@ copy_buffer_do_copy (struct copy_buffer *c, estream_t source, estream_t sink)
   if (c->nread == 0)
     return 0;	/* Done copying.  */
 
-  err = es_write (sink, c->writep, c->nread, &nwritten);
+
+  err = sink? es_write (sink, c->writep, c->nread, &nwritten) : 0;
   if (err)
     {
       if (errno == EAGAIN)
@@ -202,7 +203,7 @@ copy_buffer_do_copy (struct copy_buffer *c, estream_t source, estream_t sink)
   c->nread -= nwritten;
   assert (c->writep - c->buffer <= sizeof c->buffer);
 
-  if (es_fflush (sink) && errno != EAGAIN)
+  if (sink && es_fflush (sink) && errno != EAGAIN)
     err = my_error_from_syserror ();
 
   return err;
@@ -228,36 +229,80 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink)
 

 
 /* Run the program PGMNAME with the command line arguments given in
-   the NULL terminates array ARGV.  If INPUT is not NULL it will be
-   fed to stdin of the process.  stderr is logged using log_info and
-   the process' stdout is written to OUTPUT.  On error a diagnostic is
-   printed, and an error code returned.  */
+ * the NULL terminates array ARGV.  If INPUT is not NULL it will be
+ * fed to stdin of the process.  stderr is logged using log_info and
+ * the process' stdout is written to OUTPUT.  If OUTPUT is NULL the
+ * output is discarded.  If INEXTRA is given, an additional input
+ * stream will be passed to the child; to tell the child about this
+ * ARGV is scanned and the first occurrence of an argument
+ * "-&@INEXTRA@" is replaced by the concatenation of "-&" and the
+ * child's file descriptor of the pipe created for the INEXTRA stream.
+ *
+ * On error a diagnostic is printed and an error code returned.  */
 gpg_error_t
 gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
-                        estream_t input,
+                        estream_t input, estream_t inextra,
                         estream_t output)
 {
   gpg_error_t err;
   pid_t pid;
   estream_t infp = NULL;
+  estream_t extrafp = NULL;
   estream_t outfp, errfp;
-  es_poll_t fds[3];
+  es_poll_t fds[4];
+  int exceptclose[2];
+  int extrapipe[2] = {-1, -1};
+  char extrafdbuf[20];
+  const char *argsave = NULL;
+  int argsaveidx;
   int count;
   read_and_log_buffer_t fderrstate;
-  struct copy_buffer cpbuf[2];
+  struct copy_buffer cpbuf_in, cpbuf_out, cpbuf_extra; /* Fixme: malloc them. */
 
   memset (fds, 0, sizeof fds);
   memset (&fderrstate, 0, sizeof fderrstate);
-  copy_buffer_init (&cpbuf[0]);
-  copy_buffer_init (&cpbuf[1]);
+  copy_buffer_init (&cpbuf_in);
+  copy_buffer_init (&cpbuf_out);
+  copy_buffer_init (&cpbuf_extra);
+
+  if (inextra)
+    {
+      err = gnupg_create_outbound_pipe (extrapipe, &extrafp, 1);
+      if (err)
+        {
+          log_error ("error running outbound pipe for extra fp: %s\n",
+                     gpg_strerror (err));
+          return err;
+        }
+      exceptclose[0] = extrapipe[0]; /* Do not close in child. */
+      exceptclose[1] = -1;
+      /* Now find the argument marker and replace by the pipe's fd.
+         Yeah, that is an ugly non-thread safe hack but it safes us to
+         create a copy of the array.  */
+      snprintf (extrafdbuf, sizeof extrafdbuf, "-&%d", extrapipe[0]);
+      for (argsaveidx=0; argv[argsaveidx]; argsaveidx++)
+        if (!strcmp (argv[argsaveidx], "-&@INEXTRA@"))
+          {
+            argsave = argv[argsaveidx];
+            argv[argsaveidx] = extrafdbuf;
+            break;
+          }
+    }
+  else
+    exceptclose[0] = -1;
 
   err = gnupg_spawn_process (pgmname, argv,
-                             NULL, GNUPG_SPAWN_NONBLOCK,
+                             exceptclose, NULL, GNUPG_SPAWN_NONBLOCK,
                              input? &infp : NULL,
                              &outfp, &errfp, &pid);
+  if (extrapipe[0] != -1)
+    close (extrapipe[0]);
+  if (argsave)
+    argv[argsaveidx] = argsave;
   if (err)
     {
       log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err));
+      es_fclose (extrafp);
       return err;
     }
 
@@ -271,6 +316,11 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
   fds[1].want_read = 1;
   fds[2].stream = errfp;
   fds[2].want_read = 1;
+  fds[3].stream = extrafp;
+  fds[3].want_write = 1;
+  if (!inextra)
+    fds[3].ignore = 1;
+
   /* Now read as long as we have something to poll.  We continue
      reading even after EOF or error on stdout so that we get the
      other error messages or remaining outut.  */
@@ -291,7 +341,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
 
       if (fds[0].got_write)
         {
-          err = copy_buffer_do_copy (&cpbuf[0], input, fds[0].stream);
+          err = copy_buffer_do_copy (&cpbuf_in, input, fds[0].stream);
           if (err)
             {
               log_error ("error feeding data to '%s': %s\n",
@@ -301,7 +351,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
 
           if (es_feof (input))
             {
-              err = copy_buffer_flush (&cpbuf[0], fds[0].stream);
+              err = copy_buffer_flush (&cpbuf_in, fds[0].stream);
               if (err)
                 {
                   log_error ("error feeding data to '%s': %s\n",
@@ -314,9 +364,35 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
             }
         }
 
+      if (fds[3].got_write)
+        {
+          log_assert (inextra);
+          err = copy_buffer_do_copy (&cpbuf_extra, inextra, fds[3].stream);
+          if (err)
+            {
+              log_error ("error feeding data to '%s': %s\n",
+                         pgmname, gpg_strerror (err));
+              goto leave;
+            }
+
+          if (es_feof (inextra))
+            {
+              err = copy_buffer_flush (&cpbuf_extra, fds[3].stream);
+              if (err)
+                {
+                  log_error ("error feeding data to '%s': %s\n",
+                             pgmname, gpg_strerror (err));
+                  goto leave;
+                }
+
+              fds[3].ignore = 1; /* ready.  */
+              es_fclose (extrafp); extrafp = NULL;
+            }
+        }
+
       if (fds[1].got_read)
         {
-          err = copy_buffer_do_copy (&cpbuf[1], fds[1].stream, output);
+          err = copy_buffer_do_copy (&cpbuf_out, fds[1].stream, output);
           if (err)
             {
               log_error ("error reading data from '%s': %s\n",
@@ -329,7 +405,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
         read_and_log_stderr (&fderrstate, fds + 2);
     }
 
-  err = copy_buffer_flush (&cpbuf[1], output);
+  err = copy_buffer_flush (&cpbuf_out, output);
   if (err)
     {
       log_error ("error reading data from '%s': %s\n",
@@ -339,6 +415,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
 
   read_and_log_stderr (&fderrstate, NULL); /* Flush.  */
   es_fclose (infp); infp = NULL;
+  es_fclose (extrafp); extrafp = NULL;
   es_fclose (outfp); outfp = NULL;
   es_fclose (errfp); errfp = NULL;
 
@@ -350,14 +427,17 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
     gnupg_kill_process (pid);
 
   es_fclose (infp);
+  es_fclose (extrafp);
   es_fclose (outfp);
   es_fclose (errfp);
   if (pid != (pid_t)(-1))
     gnupg_wait_process (pgmname, pid, 1, NULL);
   gnupg_release_process (pid);
 
-  copy_buffer_shred (&cpbuf[0]);
-  copy_buffer_shred (&cpbuf[1]);
+  copy_buffer_shred (&cpbuf_in);
+  copy_buffer_shred (&cpbuf_out);
+  if (inextra)
+    copy_buffer_shred (&cpbuf_extra);
   return err;
 }
 
@@ -408,7 +488,7 @@ gnupg_exec_tool (const char *pgmname, const char *argv[],
       goto leave;
     }
 
-  err = gnupg_exec_tool_stream (pgmname, argv, input, output);
+  err = gnupg_exec_tool_stream (pgmname, argv, input, NULL, output);
   if (err)
     goto leave;
 
diff --git a/common/exectool.h b/common/exectool.h
index d9439aa..21bc177 100644
--- a/common/exectool.h
+++ b/common/exectool.h
@@ -48,9 +48,9 @@ gpg_error_t gnupg_exec_tool (const char *pgmname, const char *argv[],
    the NULL terminates array ARGV.  If INPUT is not NULL it will be
    fed to stdin of the process.  stderr is logged using log_info and
    the process' stdout is written to OUTPUT.  On error a diagnostic is
-   printed, and an error code returned.  */
+   printed, and an error code returned.  INEXTRA is reserved. */
 gpg_error_t gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
-				 estream_t input,
-				 estream_t output);
+                                    estream_t input, estream_t inextra,
+                                    estream_t output);
 
 #endif /* GNUPG_COMMON_EXECTOOL_H */
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index 5d4a26a..3d456a9 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -1626,7 +1626,7 @@ gc_component_check_options (int component, estream_t out, const char *conf_file)
 
   result = 0;
   errlines = NULL;
-  err = gnupg_spawn_process (pgmname, argv, NULL, 0,
+  err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
                              NULL, NULL, &errfp, &pid);
   if (err)
     result |= 1; /* Program could not be run.  */
@@ -1965,7 +1965,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
   argv[0] = "--gpgconf-list";
   argv[1] = NULL;
 
-  err = gnupg_spawn_process (pgmname, argv, NULL, 0,
+  err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
                              NULL, &outfp, NULL, &pid);
   if (err)
     {
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
index f7c8b1a..d615fd3 100644
--- a/tools/gpgtar-create.c
+++ b/tools/gpgtar-create.c
@@ -932,7 +932,7 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
         }
 
       err = gnupg_exec_tool_stream (opt.gpg_program, argv,
-                                    outstream, cipher_stream);
+                                    outstream, NULL, cipher_stream);
       xfree (argv);
       if (err)
         goto leave;
diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
index 3ee73ef..c4bf440 100644
--- a/tools/gpgtar-extract.c
+++ b/tools/gpgtar-extract.c
@@ -327,7 +327,7 @@ gpgtar_extract (const char *filename, int decrypt)
         }
 
       err = gnupg_exec_tool_stream (opt.gpg_program, argv,
-                                    cipher_stream, stream);
+                                    cipher_stream, NULL, stream);
       xfree (argv);
       if (err)
         goto leave;
diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c
index 930712a..a3f85ac 100644
--- a/tools/gpgtar-list.c
+++ b/tools/gpgtar-list.c
@@ -327,7 +327,7 @@ gpgtar_list (const char *filename, int decrypt)
         }
 
       err = gnupg_exec_tool_stream (opt.gpg_program, argv,
-                                    cipher_stream, stream);
+                                    cipher_stream, NULL, stream);
       xfree (argv);
       if (err)
         goto leave;

-----------------------------------------------------------------------

Summary of changes:
 common/exechelp-posix.c |  13 +--
 common/exechelp-w32.c   |   4 +-
 common/exechelp-w32ce.c |   3 +-
 common/exechelp.h       |   6 +-
 common/exectool.c       | 209 +++++++++++++++++++++++++++++++++++++++++-------
 common/exectool.h       |  19 ++++-
 tools/gpgconf-comp.c    |   4 +-
 tools/gpgtar-create.c   |   2 +-
 tools/gpgtar-extract.c  |   2 +-
 tools/gpgtar-list.c     |   2 +-
 10 files changed, 216 insertions(+), 48 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list