[svn] GnuPG - r5401 - in trunk: . common tools

svn author wk cvs at cvs.gnupg.org
Fri Aug 20 14:18:40 CEST 2010


Author: wk
Date: 2010-08-20 14:18:38 +0200 (Fri, 20 Aug 2010)
New Revision: 5401

Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/README
   trunk/common/ChangeLog
   trunk/common/estream.c
   trunk/common/estream.h
   trunk/common/exechelp-posix.c
   trunk/common/exechelp-w32.c
   trunk/common/exechelp-w32ce.c
   trunk/common/exechelp.h
   trunk/tools/ChangeLog
   trunk/tools/gpgconf-comp.c
   trunk/tools/gpgconf.c
Log:
Reworked the posix and w32 exechelpers.


[The diff below has been truncated]

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/ChangeLog	2010-08-20 12:18:38 UTC (rev 5401)
@@ -1,3 +1,7 @@
+2010-08-19  Werner Koch  <wk at g10code.com>
+
+	* configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS.
+
 2010-08-09  Werner Koch  <wk at g10code.com>
 
 	* configure.ac (inet_pton): Check for it.

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/ChangeLog	2010-08-20 12:18:38 UTC (rev 5401)
@@ -1,3 +1,31 @@
+2010-08-20  Werner Koch  <wk at g10code.com>
+
+	* exechelp-w32.c (create_inheritable_pipe): Change arg to HANDLE.
+
+	* estream.h (es_sysopen_t): New.
+	* estream.c (es_func_w32_create, es_func_w32_read)
+	(es_func_w32_write, es_func_w32_seek, es_func_w32_destroy)
+	(estream_functions_w32, estream_cookie_fd): New.  Only for W32.
+	(es_sysopen, es_sysopen_nc): New.
+	(do_w32open, do_sysopen): New.
+	(es_syshd, es_syshd_unlocked): New.
+	(struct estream_internal): Replace filed FD by SYSHD.
+	(es_initialize): Clear SYSHD_VALID.
+	(map_w32_to_errno): New.
+	(es_get_fd): Remove.
+	(es_fileno_unlocked): Re-implement using es_syshd.
+	(es_initialize, es_create): Replace arg FD by SYSHD.
+	(es_fopen, es_mopen, es_fopenmem, do_fdopen, do_fpopen)
+	(es_tmpfile): Use SYSHD instead of FD.
+	(es_destroy): Rename to do_close.
+
+2010-08-19  Werner Koch  <wk at g10code.com>
+
+	* exechelp-posix.c (create_pipe_and_estream): New.
+	(gnupg_spawn_process): Rework this function and its calling
+	convention; it is not used anyway.
+	* exechelp-w32.c (gnupg_spawn_process): Ditto.
+
 2010-08-18  Werner Koch  <wk at g10code.com>
 
 	* logging.c (writen): Add arg IS_SOCKET.

Modified: trunk/tools/ChangeLog
===================================================================
--- trunk/tools/ChangeLog	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/tools/ChangeLog	2010-08-20 12:18:38 UTC (rev 5401)
@@ -1,5 +1,16 @@
+2010-08-20  Werner Koch  <wk at g10code.com>
+
+	* gpgconf-comp.c (collect_error_output): Remove extra CRs.
+
 2010-08-19  Werner Koch  <wk at g10code.com>
 
+	* gpgconf.c (main): Fix --check-options.
+
+	* gpgconf-comp.c (gc_component_check_options): Replace
+	gnupg_spawn_process_fd by gnupg_spawn_process.
+	(retrieve_options_from_program): Ditto.
+	(collect_error_output): Change to use estream.
+
 	* gpgconf-comp.c: Add new backend and component for PINENTRY.
 	(gc_component_check_options): Use --version to test the pinentry.
 	(gc_component_retrieve_options, gc_component_change_options):

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/NEWS	2010-08-20 12:18:38 UTC (rev 5401)
@@ -35,7 +35,9 @@
 
  * Given sufficient permissions Dirmngr is started automagically.
 
+ * Fixed output of "gpgconf --check-options".
 
+
 Noteworthy changes in version 2.0.13 (2009-09-04)
 -------------------------------------------------
 

Modified: trunk/README
===================================================================
--- trunk/README	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/README	2010-08-20 12:18:38 UTC (rev 5401)
@@ -16,7 +16,7 @@
 GnuPG is GNU's tool for secure communication and data storage.  It can
 be used to encrypt data and to create digital signatures.  It includes
 an advanced key management facility and is compliant with the proposed
-OpenPGP Internet standard as described in RFC2440 and the S/MIME
+OpenPGP Internet standard as described in RFC4880 and the S/MIME
 standard as described by several RFCs.
 
 GnuPG is distributed under the terms of the GNU General Public

Modified: trunk/common/estream.c
===================================================================
--- trunk/common/estream.c	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/estream.c	2010-08-20 12:18:38 UTC (rev 5401)
@@ -126,9 +126,9 @@
 #endif
 
 #ifdef HAVE_W32_SYSTEM
-# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1))
+# define IS_INVALID_FD(a)    ((void*)(a) == (void*)(-1)) /* ?? FIXME.  */
 #else
-# define IS_INVALID_FD(a) ((a) == -1)
+# define IS_INVALID_FD(a)    ((a) == -1)
 #endif
 
 
@@ -197,6 +197,7 @@
 # define ESTREAM_SYS_YIELD() do { } while (0)
 #endif
 
+
 /* Misc definitions.  */
 
 #define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR)
@@ -218,7 +219,7 @@
   es_cookie_seek_function_t func_seek;
   es_cookie_close_function_t func_close;
   int strategy;
-  int fd;                        /* Value to return by es_fileno().  */
+  es_syshd_t syshd;              /* A copy of the sytem handle.  */
   struct
   {
     unsigned int err: 1;
@@ -317,8 +318,40 @@
     free (p);
 }
 
+#ifdef HAVE_W32_SYSTEM
+static int
+map_w32_to_errno (DWORD w32_err)
+{
+  switch (w32_err)
+    {
+    case 0:
+      return 0;
 
+    case ERROR_FILE_NOT_FOUND:
+      return ENOENT;
 
+    case ERROR_PATH_NOT_FOUND:
+      return ENOENT;
+
+    case ERROR_ACCESS_DENIED:
+      return EPERM;
+
+    case ERROR_INVALID_HANDLE:
+    case ERROR_INVALID_BLOCK:
+      return EINVAL;
+
+    case ERROR_NOT_ENOUGH_MEMORY:
+      return ENOMEM;
+      
+    case ERROR_NO_DATA:
+      return EPIPE;
+
+    default:
+      return EIO;
+    }
+}
+#endif /*HAVE_W32_SYSTEM*/
+
 /*
  * List manipulation.
  */
@@ -744,7 +777,7 @@
 
 
 
-/* Implementation of fd I/O.  */
+/* Implementation of file descriptor based I/O.  */
 
 /* Cookie for fd objects.  */
 typedef struct estream_cookie_fd
@@ -887,6 +920,217 @@
 
 
 
+#ifdef HAVE_W32_SYSTEM
+/* Implementation of W32 handle based I/O.  */
+
+/* Cookie for fd objects.  */
+typedef struct estream_cookie_w32
+{
+  HANDLE hd;     /* The handle we are using for actual output.  */
+  int no_close;  /* If set we won't close the handle.  */
+} *estream_cookie_w32_t;
+
+
+/* Create function for w32 handle objects.  */
+static int
+es_func_w32_create (void **cookie, HANDLE hd,
+                    unsigned int modeflags, int no_close)
+{
+  estream_cookie_w32_t w32_cookie;
+  int err;
+
+  w32_cookie = mem_alloc (sizeof (*w32_cookie));
+  if (!w32_cookie)
+    err = -1;
+  else
+    {
+      /* CR/LF translations are not supported when using the bare W32
+         API.  If that is really required we need to implemented that
+         in the upper layer.  */
+      (void)modeflags;
+
+      w32_cookie->hd = hd;
+      w32_cookie->no_close = no_close;
+      *cookie = w32_cookie;
+      err = 0;
+    }
+  
+  return err;
+}
+
+/* Read function for W32 handle objects.  */
+static ssize_t
+es_func_w32_read (void *cookie, void *buffer, size_t size)
+{
+  estream_cookie_w32_t w32_cookie = cookie;
+  ssize_t bytes_read;
+  
+  if (w32_cookie->hd == INVALID_HANDLE_VALUE)
+    {
+      ESTREAM_SYS_YIELD ();
+      bytes_read = 0;
+    }
+  else
+    {
+      do
+        {
+#ifdef HAVE_PTH
+          /* Note: Our pth_read actually uses HANDLE! */
+          bytes_read = pth_read ((int)w32_cookie->hd, buffer, size);
+#else
+          DWORD nread, ec;
+          
+          if (!ReadFile (w32_cookie->hd, buffer, size, &nread, NULL))
+            {
+              ec = GetLastError ();
+              if (ec == ERROR_BROKEN_PIPE)
+                bytes_read = 0; /* Like our pth_read we handle this as EOF.  */
+              else
+                {
+                  _set_errno (map_w32_to_errno (ec));
+                  log_debug ("estream: ReadFile returned %d\n",
+                             (int)GetLastError ());
+                  bytes_read = -1;
+                }
+            }
+          else
+            bytes_read = (int)nread;
+#endif
+        }
+      while (bytes_read == -1 && errno == EINTR);
+    }
+
+  return bytes_read;
+}
+
+/* Write function for W32 handle objects.  */
+static ssize_t
+es_func_w32_write (void *cookie, const void *buffer, size_t size)
+{
+  estream_cookie_w32_t w32_cookie = cookie;
+  ssize_t bytes_written;
+
+  if (w32_cookie->hd == INVALID_HANDLE_VALUE)
+    {
+      ESTREAM_SYS_YIELD ();
+      bytes_written = size; /* Yeah:  Success writing to the bit bucket.  */
+    }
+  else
+    {
+      do
+        {
+#ifdef HAVE_PTH
+          /* Note: Our pth_write actually uses HANDLE! */
+          bytes_written = pth_write ((int)w32_cookie->hd, buffer, size);
+#else
+          DWORD nwritten;
+
+	  if (!WriteFile (w32_cookie->hd, buffer, size, &nwritten, NULL))
+	    {
+	      _set_errno (map_w32_to_errno (GetLastError ()));
+	      bytes_written = -1;
+	    }
+	  else
+	    bytes_written = (int)nwritten;
+#endif
+        }
+      while (bytes_written == -1 && errno == EINTR);
+    }
+
+  return bytes_written;
+}
+
+/* Seek function for W32 handle objects.  */
+static int
+es_func_w32_seek (void *cookie, off_t *offset, int whence)
+{
+  estream_cookie_w32_t w32_cookie = cookie;
+  DWORD method;
+  LARGE_INTEGER distance, newoff;
+
+  if (w32_cookie->hd == INVALID_HANDLE_VALUE)
+    {
+      _set_errno (ESPIPE);
+      return -1;
+    }
+
+  if (whence == SEEK_SET)
+    {
+      method = FILE_BEGIN;
+      distance.QuadPart = (unsigned long long)(*offset);
+    }
+  else if (whence == SEEK_CUR)
+    {
+      method = FILE_CURRENT;
+      distance.QuadPart = (long long)(*offset);
+    }
+  else if (whence == SEEK_END)
+    {
+      method = FILE_END;
+      distance.QuadPart = (long long)(*offset);
+    }
+  else
+    {
+      _set_errno (EINVAL);
+      return -1;
+    }
+#ifdef HAVE_W32CE_SYSTEM
+# warning need to use SetFilePointer
+#else
+  if (!SetFilePointerEx (w32_cookie->hd, distance, &newoff, method))
+    {
+      _set_errno (map_w32_to_errno (GetLastError ()));
+      return -1;
+    }
+#endif
+  *offset = (unsigned long long)newoff.QuadPart;
+  return 0;
+}
+
+/* Destroy function for W32 handle objects.  */
+static int
+es_func_w32_destroy (void *cookie)
+{
+  estream_cookie_w32_t w32_cookie = cookie;
+  int err;
+
+  if (w32_cookie)
+    {
+      if (w32_cookie->hd == INVALID_HANDLE_VALUE)
+        err = 0;
+      else if (w32_cookie->no_close)
+        err = 0;
+      else
+        { 
+          if (!CloseHandle (w32_cookie->hd))
+            {
+	      _set_errno (map_w32_to_errno (GetLastError ()));
+              err = -1;
+            }
+          else
+            err = 0;
+        }
+      mem_free (w32_cookie);
+    }
+  else
+    err = 0;
+
+  return err;
+}
+
+
+static es_cookie_io_functions_t estream_functions_w32 =
+  {
+    es_func_w32_read,
+    es_func_w32_write,
+    es_func_w32_seek,
+    es_func_w32_destroy
+  };
+#endif /*HAVE_W32_SYSTEM*/
+
+
+
+
 /* Implementation of FILE* I/O.  */
 
 /* Cookie for fp objects.  */
@@ -1049,7 +1293,7 @@
 
 /* Implementation of file I/O.  */
 
-/* Create function for file objects.  */
+/* Create function for fd objects.  */
 static int
 es_func_file_create (void **cookie, int *filedes,
 		     const char *path, unsigned int modeflags)
@@ -1269,7 +1513,8 @@
 /* Initialize STREAM.  */
 static void
 es_initialize (estream_t stream,
-	       void *cookie, int fd, es_cookie_io_functions_t functions,
+	       void *cookie, es_syshd_t *syshd,
+               es_cookie_io_functions_t functions,
                unsigned int modeflags)
 {
   stream->intern->cookie = cookie;
@@ -1280,7 +1525,7 @@
   stream->intern->func_seek = functions.func_seek;
   stream->intern->func_close = functions.func_close;
   stream->intern->strategy = _IOFBF;
-  stream->intern->fd = fd;
+  stream->intern->syshd = *syshd;
   stream->intern->print_ntotal = 0;
   stream->intern->indicators.err = 0;
   stream->intern->indicators.eof = 0;
@@ -1329,7 +1574,7 @@
 
 /* Create a new stream object, initialize it.  */
 static int
-es_create (estream_t *stream, void *cookie, int fd,
+es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
 	   es_cookie_io_functions_t functions, unsigned int modeflags,
            int with_locked_list)
 {
@@ -1361,7 +1606,7 @@
   stream_new->intern = stream_internal_new;
 
   ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock);
-  es_initialize (stream_new, cookie, fd, functions, modeflags);
+  es_initialize (stream_new, cookie, syshd, functions, modeflags);
 
   err = es_list_add (stream_new, with_locked_list);
   if (err)
@@ -1385,9 +1630,9 @@
 
 /* Deinitialize a stream object and destroy it.  */
 static int
-es_destroy (estream_t stream, int with_locked_list)
+do_close (estream_t stream, int with_locked_list)
 {
-  int err = 0;
+  int err;
 
   if (stream)
     {
@@ -1396,6 +1641,8 @@
       mem_free (stream->intern);
       mem_free (stream);
     }
+  else
+    err = 0;
 
   return err;
 }
@@ -1897,6 +2144,7 @@
   unsigned char *data;
   size_t data_len;
   int err;
+  es_syshd_t syshd;
 
   line_new = NULL;
   line_stream = NULL;
@@ -1910,7 +2158,8 @@
   if (err)
     goto out;
 
-  err = es_create (&line_stream, line_stream_cookie, -1,
+  memset (&syshd, 0, sizeof syshd);
+  err = es_create (&line_stream, line_stream_cookie, &syshd,
 		   estream_functions_mem, O_RDWR, 0);
   if (err)
     goto out;
@@ -1996,7 +2245,7 @@
  out:
 
   if (line_stream)
-    es_destroy (line_stream, 0);
+    do_close (line_stream, 0);
   else if (line_stream_cookie)
     es_func_mem_destroy (line_stream_cookie);
 
@@ -2152,12 +2401,6 @@
 }
 
 
-static int
-es_get_fd (estream_t stream)
-{
-  return stream->intern->fd;
-}
-
 
 
 /* API.  */
@@ -2172,6 +2415,8 @@
   return err;
 }
 
+
+
 estream_t
 es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode)
 {
@@ -2181,6 +2426,7 @@
   void *cookie;
   int err;
   int fd;
+  es_syshd_t syshd;
 
   stream = NULL;
   cookie = NULL;
@@ -2193,9 +2439,12 @@
   err = es_func_file_create (&cookie, &fd, path, modeflags);
   if (err)
     goto out;
+  
+  syshd.type = ES_SYSHD_FD;
+  syshd.u.fd = fd;
 
   create_called = 1;
-  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
+  err = es_create (&stream, cookie, &syshd, estream_functions_fd, modeflags, 0);
   if (err)
     goto out;
 
@@ -2211,6 +2460,7 @@
 }
 
 
+
 estream_t
 es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len,
 	  unsigned int grow,
@@ -2222,6 +2472,7 @@
   estream_t stream;
   void *cookie;
   int err;
+  es_syshd_t syshd;
 
   cookie = 0;
   stream = NULL;
@@ -2237,8 +2488,10 @@
   if (err)
     goto out;
   
+  memset (&syshd, 0, sizeof syshd);
   create_called = 1;
-  err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0);
+  err = es_create (&stream, cookie, &syshd,
+                   estream_functions_mem, modeflags, 0);
 
  out:
 
@@ -2249,12 +2502,14 @@
 }
 
 
+
 estream_t
 es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode)
 {
   unsigned int modeflags;
   estream_t stream = NULL;
   void *cookie = NULL;
+  es_syshd_t syshd;
 
   /* Memory streams are always read/write.  We use MODE only to get
      the append flag.  */
@@ -2269,14 +2524,15 @@
                           memlimit))
     return NULL;
   
-  if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0))
+  memset (&syshd, 0, sizeof syshd);
+  if (es_create (&stream, cookie, &syshd, estream_functions_mem, modeflags, 0))
     (*estream_functions_mem.func_close) (cookie);
 
   return stream;
 }
 
 
-
+
 estream_t
 es_fopencookie (void *ES__RESTRICT cookie,
 		const char *ES__RESTRICT mode,
@@ -2285,6 +2541,7 @@
   unsigned int modeflags;
   estream_t stream;
   int err;
+  es_syshd_t syshd;
 
   stream = NULL;
   modeflags = 0;
@@ -2293,16 +2550,17 @@
   if (err)
     goto out;
 
-  err = es_create (&stream, cookie, -1, functions, modeflags, 0);
+  memset (&syshd, 0, sizeof syshd);
+  err = es_create (&stream, cookie, &syshd, functions, modeflags, 0);
   if (err)
     goto out;
 
  out:
-
   return stream;
 }
 
 
+
 estream_t
 do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list)
 {
@@ -2311,6 +2569,7 @@
   estream_t stream;
   void *cookie;
   int err;
+  es_syshd_t syshd;
 
   stream = NULL;
   cookie = NULL;
@@ -2324,12 +2583,13 @@
   if (err)
     goto out;
 
+  syshd.type = ES_SYSHD_FD;
+  syshd.u.fd = filedes;
   create_called = 1;
-  err = es_create (&stream, cookie, filedes, estream_functions_fd,
+  err = es_create (&stream, cookie, &syshd, estream_functions_fd,
                    modeflags, with_locked_list);
 
  out:
-
   if (err && create_called)
     (*estream_functions_fd.func_close) (cookie);
 
@@ -2350,6 +2610,7 @@
 }
 
 
+
 estream_t
 do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list)
 {
@@ -2358,6 +2619,7 @@
   estream_t stream;
   void *cookie;
   int err;
+  es_syshd_t syshd;
 
   stream = NULL;
   cookie = NULL;
@@ -2372,9 +2634,11 @@
   err = es_func_fp_create (&cookie, fp, modeflags, no_close);
   if (err)
     goto out;
-  
+
+  syshd.type = ES_SYSHD_FD;
+  syshd.u.fd = fp? fileno (fp): -1;
   create_called = 1;
-  err = es_create (&stream, cookie, fp? fileno (fp):-1, estream_functions_fp,
+  err = es_create (&stream, cookie, &syshd, estream_functions_fp,
                    modeflags, with_locked_list);
 
  out:
@@ -2409,6 +2673,87 @@
 }
 
 
+
+#ifdef HAVE_W32_SYSTEM
+estream_t
+do_w32open (HANDLE hd, const char *mode,
+            int no_close, int with_locked_list)
+{
+  unsigned int modeflags;
+  int create_called = 0;
+  estream_t stream = NULL;
+  void *cookie = NULL;
+  int err;
+  es_syshd_t syshd;
+
+  err = es_convert_mode (mode, &modeflags);
+  if (err)
+    goto leave;
+
+  err = es_func_w32_create (&cookie, hd, modeflags, no_close);
+  if (err)
+    goto leave;
+
+  syshd.type = ES_SYSHD_HANDLE;
+  syshd.u.handle = hd;
+  create_called = 1;
+  err = es_create (&stream, cookie, &syshd, estream_functions_w32,
+                   modeflags, with_locked_list);
+
+ leave:
+  if (err && create_called)
+    (*estream_functions_w32.func_close) (cookie);
+
+  return stream;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+static estream_t
+do_sysopen (es_syshd_t *syshd, const char *mode, int no_close)
+{
+  estream_t stream;
+
+  switch (syshd->type)
+    {
+    case ES_SYSHD_FD:
+    case ES_SYSHD_SOCK:
+      stream = do_fdopen (syshd->u.fd, mode, no_close, 0);
+      break;
+      
+#ifdef HAVE_W32_SYSTEM
+    case ES_SYSHD_HANDLE:
+      stream = do_w32open (syshd->u.handle, mode, no_close, 0);
+      break;
+#endif
+
+    /* FIXME: Support RVIDs under Wince?  */
+
+    default:
+      _set_errno (EINVAL);
+      stream = NULL;
+    }
+  return stream;
+}
+
+/* On POSIX systems this function is an alias for es_fdopen.  Under
+   Windows it uses the bare W32 API and thus a HANDLE instead of a
+   file descriptor.  */
+estream_t
+es_sysopen (es_syshd_t *syshd, const char *mode)
+{
+  return do_sysopen (syshd, mode, 0);
+}
+
+/* Same as es_sysopen but the handle/fd will not be closed by
+   es_fclose.  */
+estream_t
+es_sysopen_nc (es_syshd_t *syshd, const char *mode)
+{
+  return do_sysopen (syshd, mode, 1);
+}
+
+
+
 /* Set custom standard descriptors to be used for stdin, stdout and
    stderr.  This function needs to be called before any of the
    standard streams are accessed.  */
@@ -2500,6 +2845,7 @@
       int create_called;
       void *cookie;
       int fd;
+      es_syshd_t syshd;
 
       cookie = NULL;
       create_called = 0;
@@ -2516,8 +2862,10 @@
       if (err)
 	goto leave;
 
+      syshd.type = ES_SYSHD_FD;
+      syshd.u.fd = fd;
       create_called = 1;
-      es_initialize (stream, cookie, fd, estream_functions_fd, modeflags);
+      es_initialize (stream, cookie, &syshd, estream_functions_fd, modeflags);
 
     leave:
 
@@ -2526,7 +2874,7 @@
 	  if (create_called)
 	    es_func_fd_destroy (cookie);
       
-	  es_destroy (stream, 0);
+	  do_close (stream, 0);
 	  stream = NULL;
 	}
       else
@@ -2541,7 +2889,7 @@
       /* FIXME?  We don't support re-opening at the moment.  */
       _set_errno (EINVAL);
       es_deinitialize (stream);
-      es_destroy (stream, 0);
+      do_close (stream, 0);
       stream = NULL;
     }
 
@@ -2554,18 +2902,50 @@
 {
   int err;
 
-  err = es_destroy (stream, 0);
+  err = do_close (stream, 0);
 
   return err;
 }
 
+
 int
 es_fileno_unlocked (estream_t stream)
 {
-  return es_get_fd (stream);
+  es_syshd_t syshd;
+
+  if (es_syshd (stream, &syshd))
+    return -1;
+  switch (syshd.type)
+    {
+    case ES_SYSHD_FD:   return syshd.u.fd;
+    case ES_SYSHD_SOCK: return syshd.u.sock;
+    default: 
+      _set_errno (EINVAL);
+      return -1;
+    }
 }
 
 
+/* Return the handle of a stream which has been opened by es_sysopen.
+   The caller needs to pass a structure which will be filled with the
+   sys handle.  Return 0 on success or true on error and sets errno.
+   This is the unlocked version.  */
+int
+es_syshd_unlocked (estream_t stream, es_syshd_t *syshd)
+{
+  if (!stream || !syshd || stream->intern->syshd.type == ES_SYSHD_NONE)
+    {
+      if (syshd)
+        syshd->type = ES_SYSHD_NONE;
+      _set_errno (EINVAL);
+      return -1;
+    }
+  
+  *syshd = stream->intern->syshd;
+  return 0;
+}
+
+
 void
 es_flockfile (estream_t stream)
 {
@@ -2600,7 +2980,24 @@
 }
 
 
+/* Return the handle of a stream which has been opened by es_sysopen.
+   The caller needs to pass a structure which will be filled with the
+   sys handle.  Return 0 on success or true on error and sets errno.
+   This is the unlocked version.  */
 int
+es_syshd (estream_t stream, es_syshd_t *syshd)
+{
+  int ret;
+
+  ESTREAM_LOCK (stream);
+  ret = es_syshd_unlocked (stream, syshd);
+  ESTREAM_UNLOCK (stream);
+
+  return ret;
+}
+
+
+int
 es_feof_unlocked (estream_t stream)
 {
   return es_get_indicator (stream, 0, 1);
@@ -3371,6 +3768,7 @@
   void *cookie;
   int err;
   int fd;
+  es_syshd_t syshd;
 
   create_called = 0;
   stream = NULL;
@@ -3388,11 +3786,12 @@
   if (err)
     goto out;
 
+  syshd.type = ES_SYSHD_FD;
+  syshd.u.fd = fd;
   create_called = 1;
-  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
+  err = es_create (&stream, cookie, &syshd, estream_functions_fd, modeflags, 0);
 
  out:
-
   if (err)
     {
       if (create_called)

Modified: trunk/common/estream.h
===================================================================
--- trunk/common/estream.h	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/estream.h	2010-08-20 12:18:38 UTC (rev 5401)
@@ -78,6 +78,8 @@
 #define es_fopenmem           _ESTREAM_PREFIX(es_fopenmem)
 #define es_fdopen             _ESTREAM_PREFIX(es_fdopen)
 #define es_fdopen_nc          _ESTREAM_PREFIX(es_fdopen_nc)
+#define es_sysopen            _ESTREAM_PREFIX(es_sysopen)
+#define es_sysopen_nc         _ESTREAM_PREFIX(es_sysopen_nc)
 #define es_fpopen             _ESTREAM_PREFIX(es_fpopen)
 #define es_fpopen_nc          _ESTREAM_PREFIX(es_fpopen_nc)
 #define _es_set_std_fd        _ESTREAM_PREFIX(_es_set_std_fd)
@@ -211,6 +213,29 @@
   es_cookie_close_function_t func_close;
 } es_cookie_io_functions_t;
 
+
+enum es_syshd_types 
+  {
+    ES_SYSHD_NONE,  /* No system handle available.  */
+    ES_SYSHD_FD,    /* A file descriptor as returned by open().  */
+    ES_SYSHD_SOCK,  /* A socket as returned by socket().        */
+    ES_SYSHD_RVID,  /* A rendevous id (see libassuan's gpgcedev.c).  */
+    ES_SYSHD_HANDLE /* A HANDLE object (Windows).  */
+  };
+
+typedef struct
+{
+  enum es_syshd_types type;
+  union {
+    int fd;
+    int sock;
+    int rvid;
+    void *handle;
+  } u;
+} es_syshd_t;
+
+
+
 
 #ifndef _ESTREAM_GCC_A_PRINTF
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
@@ -245,6 +270,8 @@
 estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode);
 estream_t es_fdopen (int filedes, const char *mode);
 estream_t es_fdopen_nc (int filedes, const char *mode);
+estream_t es_sysopen (es_syshd_t *syshd, const char *mode);
+estream_t es_sysopen_nc (es_syshd_t *syshd, const char *mode);
 estream_t es_fpopen (FILE *fp, const char *mode);
 estream_t es_fpopen_nc (FILE *fp, const char *mode);
 estream_t es_freopen (const char *ES__RESTRICT path,
@@ -256,6 +283,8 @@
 int es_fclose (estream_t stream);
 int es_fileno (estream_t stream);
 int es_fileno_unlocked (estream_t stream);
+int es_syshd (estream_t stream, es_syshd_t *syshd);
+int es_syshd_unlocked (estream_t stream, es_syshd_t *syshd);
 
 void _es_set_std_fd (int no, int fd);
 estream_t _es_get_std_stream (int fd);

Modified: trunk/common/exechelp-posix.c
===================================================================
--- trunk/common/exechelp-posix.c	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/exechelp-posix.c	2010-08-20 12:18:38 UTC (rev 5401)
@@ -299,45 +299,95 @@
 }
 
 
+
+static gpg_error_t
+create_pipe_and_estream (int filedes[2], estream_t *r_fp,
+                         gpg_err_source_t errsource)
+{
+  gpg_error_t err;
+
+  if (pipe (filedes) == -1)
+    {
+      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+      filedes[0] = filedes[1] = -1;
+      *r_fp = NULL;
+      return err;
+    }
+
+  *r_fp = es_fdopen (filedes[0], "r");
+  if (!*r_fp)
+    {
+      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      log_error (_("error creating a stream for a pipe: %s\n"),
+                 gpg_strerror (err));
+      close (filedes[0]);
+      close (filedes[1]);
+      filedes[0] = filedes[1] = -1;
+      return err;
+    }
+  return 0;
+}
+  
+
+
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     estream_t infile, estream_t outfile,
+                     gpg_err_source_t errsource,
                      void (*preexec)(void), unsigned int flags,
-                     estream_t *statusfile, pid_t *pid)
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid)
 {
   gpg_error_t err;
-  int fd, fdout, rp[2];
+  int infd = -1;
+  int outpipe[2] = {-1, -1};
+  int errpipe[2] = {-1, -1};
+  estream_t outfp = NULL;
+  estream_t errfp = NULL;
 
   (void)flags; /* Currently not used.  */
 
-  *statusfile = NULL;
-  *pid = (pid_t)(-1);
+  if (r_outfp)
+    *r_outfp = NULL;
+  if (r_errfp)
+    *r_errfp = NULL;
+  *pid = (pid_t)(-1); /* Always required.  */
 
-  if (infile)
+  if (infp)
     {
-      es_fflush (infile);
-      es_rewind (infile);
-      fd = es_fileno (infile);
+      es_fflush (infp);
+      es_rewind (infp);
+      infd = es_fileno (infp);
+      if (infd == -1)
+        return gpg_err_make (errsource, GPG_ERR_INV_VALUE);
     }
-  else
-    fd = -1;
 
-  if (outfile)
-    fdout = es_fileno (outfile);
-  else
-    fdout = -1;
+  if (r_outfp)
+    {
+      err = create_pipe_and_estream (outpipe, &outfp, errsource);
+      if (err)
+        return err;
+    }
 
-  if ((infile && fd == -1) || (outfile && fdout == -1))
-    log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
-
-  if (pipe (rp) == -1)
+  if (r_errfp)
     {
-      err = gpg_error_from_syserror ();
-      log_error (_("error creating a pipe: %s\n"), strerror (errno));
-      return err;
+      err = create_pipe_and_estream (errpipe, &errfp, errsource);
+      if (err)
+        {
+          if (outfp)
+            es_fclose (outfp);
+          else if (outpipe[0] != -1)
+            close (outpipe[0]);
+          if (outpipe[1] != -1)
+            close (outpipe[1]);
+          return err;
+        }
     }
 
+
 #ifdef USE_GNU_PTH      
   *pid = pth_fork? pth_fork () : fork ();
 #else
@@ -345,33 +395,45 @@
 #endif
   if (*pid == (pid_t)(-1))
     {
-      err = gpg_error_from_syserror ();
-      log_error (_("error forking process: %s\n"), strerror (errno));
-      close (rp[0]);
-      close (rp[1]);
+      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      log_error (_("error forking process: %s\n"), gpg_strerror (err));
+
+      if (outfp)
+        es_fclose (outfp);
+      else if (outpipe[0] != -1)
+        close (outpipe[0]);
+      if (outpipe[1] != -1)
+        close (outpipe[1]);
+
+      if (errfp)
+        es_fclose (errfp);
+      else if (errpipe[0] != -1)
+        close (errpipe[0]);
+      if (errpipe[1] != -1)
+        close (errpipe[1]);
       return err;
     }
 
   if (!*pid)
     { 
+      /* This is the child. */
       gcry_control (GCRYCTL_TERM_SECMEM);
-      /* Run child. */
-      do_exec (pgmname, argv, fd, fdout, rp[1], preexec);
+      es_fclose (outfp);
+      es_fclose (errfp);
+      do_exec (pgmname, argv, infd, outpipe[1], errpipe[1], preexec);
       /*NOTREACHED*/
     }
 
-  /* Parent. */
-  close (rp[1]);
+  /* This is the parent. */
+  if (outpipe[1] != -1)
+    close (outpipe[1]);
+  if (errpipe[1] != -1)
+    close (errpipe[1]);
 
-  *statusfile = es_fdopen (rp[0], "r");
-  if (!*statusfile)
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno));
-      kill (*pid, SIGTERM);
-      *pid = (pid_t)(-1);
-      return err;
-    }
+  if (r_outfp)
+    *r_outfp = outfp;
+  if (r_errfp)
+    *r_errfp = errfp;
 
   return 0;
 }

Modified: trunk/common/exechelp-w32.c
===================================================================
--- trunk/common/exechelp-w32.c	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/exechelp-w32.c	2010-08-20 12:18:38 UTC (rev 5401)
@@ -257,7 +257,7 @@
 /* Create pipe where one end is inheritable: With an INHERIT_IDX of 0
    the read end is inheritable, with 1 the write end is inheritable.  */
 static int
-create_inheritable_pipe (int filedes[2], int inherit_idx)
+create_inheritable_pipe (HANDLE filedes[2], int inherit_idx)
 {
   HANDLE r, w, h;
   SECURITY_ATTRIBUTES sec_attr;
@@ -290,8 +290,8 @@
       r = h;
     }
 
-  filedes[0] = handle_to_fd (r);
-  filedes[1] = handle_to_fd (w);
+  filedes[0] = r;
+  filedes[1] = w;
   return 0;
 }
 
@@ -315,27 +315,27 @@
 do_create_pipe (int filedes[2], int inherit_idx)
 {
   gpg_error_t err = 0;
-  int fds[2];
+  HANDLE fds[2];
 
   filedes[0] = filedes[1] = -1;
   err = gpg_error (GPG_ERR_GENERAL);
   if (!create_inheritable_pipe (fds, inherit_idx))
     {
-      filedes[0] = _open_osfhandle (fds[0], 0);
+      filedes[0] = _open_osfhandle (handle_to_fd (fds[0]), 0);
       if (filedes[0] == -1)
         {
-          log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
-          CloseHandle (fd_to_handle (fds[1]));
+          log_error ("failed to translate osfhandle %p\n", fds[0]);
+          CloseHandle (fds[1]);
         }
       else 
         {
-          filedes[1] = _open_osfhandle (fds[1], 1);
+          filedes[1] = _open_osfhandle (handle_to_fd (fds[1]), 1);
           if (filedes[1] == -1)
             {
-              log_error ("failed to translate osfhandle %p\n", (void*)fds[1]);
+              log_error ("failed to translate osfhandle %p\n", fds[1]);
               close (filedes[0]);
               filedes[0] = -1;
-              CloseHandle (fd_to_handle (fds[1]));
+              CloseHandle (fds[1]);
             }
           else
             err = 0;
@@ -365,9 +365,12 @@
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     estream_t infile, estream_t outfile,
+                     gpg_err_source_t errsource,
                      void (*preexec)(void), unsigned int flags,
-                     estream_t *statusfile, pid_t *pid)
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid)
 {
   gpg_error_t err;
   SECURITY_ATTRIBUTES sec_attr;
@@ -381,33 +384,104 @@
   STARTUPINFO si;
   int cr_flags;
   char *cmdline;
-  int fd, fdout, rp[2];
-  HANDLE nullhd[2];
+  HANDLE inhandle = INVALID_HANDLE_VALUE;
+  HANDLE outpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
+  HANDLE errpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
+  estream_t outfp = NULL;
+  estream_t errfp = NULL;
+  HANDLE nullhd[3] = {INVALID_HANDLE_VALUE,
+                      INVALID_HANDLE_VALUE,
+                      INVALID_HANDLE_VALUE};
   int i;
+  es_syshd_t syshd;
 
-  (void)preexec;
-
-  /* Setup return values.  */
-  *statusfile = NULL;
-  *pid = (pid_t)(-1);
+  if (r_outfp)
+    *r_outfp = NULL;
+  if (r_errfp)
+    *r_errfp = NULL;
+  *pid = (pid_t)(-1); /* Always required.  */
   
-  if (infile)
+  if (infp)
     {
-      es_fflush (infile);
-      es_rewind (infile);
-      fd = _get_osfhandle (es_fileno (infile));
+      es_fflush (infp);
+      es_rewind (infp);
+      es_syshd (infp, &syshd);
+      switch (syshd.type)
+        {
+        case ES_SYSHD_FD:
+          inhandle = (HANDLE)_get_osfhandle (syshd.u.fd);
+          break;
+        case ES_SYSHD_SOCK:
+          inhandle = (HANDLE)_get_osfhandle (syshd.u.sock);
+          break;
+        case ES_SYSHD_HANDLE:
+          inhandle = syshd.u.handle;
+          break;
+        default:
+          inhandle = INVALID_HANDLE_VALUE;
+          break;
+        }      
+      if (inhandle == INVALID_HANDLE_VALUE)
+        return gpg_err_make (errsource, GPG_ERR_INV_VALUE);
+      /* FIXME: In case we can't get a system handle (e.g. due to
+         es_fopencookie we should create a piper and a feeder
+         thread.  */
     }
-  else
-    fd = -1;
 
-  if (outfile)
-    fdout = _get_osfhandle (es_fileno (outfile));
-  else
-    fdout = -1;
+  if (r_outfp)
+    {
+      if (create_inheritable_pipe (outpipe, 1))
+        {
+          err = gpg_err_make (errsource, GPG_ERR_GENERAL);
+          log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+          return err;
+        }
 
-  if ( (infile && fd == -1) || (outfile && fdout == -1))
-    log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = outpipe[0];
+      outfp = es_sysopen (&syshd, "r");
+      if (!outfp)
+        {
+          err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+          log_error (_("error creating a stream for a pipe: %s\n"),
+                     gpg_strerror (err));
+          CloseHandle (outpipe[0]);
+          CloseHandle (outpipe[1]);
+          outpipe[0] = outpipe[1] = INVALID_HANDLE_VALUE;
+          return err;
+        }
+    }
 
+  if (r_errfp)
+    {
+      if (create_inheritable_pipe (errpipe, 1))
+        {
+          err = gpg_err_make (errsource, GPG_ERR_GENERAL);
+          log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+          return err;
+        }
+
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = errpipe[0];
+      errfp = es_sysopen (&syshd, "r");
+      if (!errfp)
+        {
+          err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+          log_error (_("error creating a stream for a pipe: %s\n"),
+                     gpg_strerror (err));
+          CloseHandle (errpipe[0]);
+          CloseHandle (errpipe[1]);
+          errpipe[0] = errpipe[1] = INVALID_HANDLE_VALUE;
+          if (outfp)
+            es_fclose (outfp);
+          else if (outpipe[0] != INVALID_HANDLE_VALUE)
+            CloseHandle (outpipe[0]);
+          if (outpipe[1] != INVALID_HANDLE_VALUE)
+            CloseHandle (outpipe[1]);
+          return err;
+        }
+    }
+
   /* Prepare security attributes.  */
   memset (&sec_attr, 0, sizeof sec_attr );
   sec_attr.nLength = sizeof sec_attr;
@@ -418,27 +492,24 @@
   if (err)
     return err; 
 
-  /* Create a pipe.  */
-  if (create_inheritable_pipe (rp, 1))
-    {
-      err = gpg_error (GPG_ERR_GENERAL);
-      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
-      xfree (cmdline);
-      return err;
-    }
-  
-  nullhd[0] =    fd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE;
-  nullhd[1] = fdout == -1? w32_open_null (1) : INVALID_HANDLE_VALUE;
+  if (inhandle != INVALID_HANDLE_VALUE)
+    nullhd[0] = w32_open_null (0);
+  if (outpipe[1] != INVALID_HANDLE_VALUE)
+    nullhd[1] = w32_open_null (0);
+  if (errpipe[1] != INVALID_HANDLE_VALUE)
+    nullhd[2] = w32_open_null (0);
 
   /* Start the process.  Note that we can't run the PREEXEC function
-     because this would change our own environment. */
+     because this might change our own environment. */
+  (void)preexec;
+
   memset (&si, 0, sizeof si);
   si.cb = sizeof (si);
   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
-  si.hStdInput  =    fd == -1? nullhd[0] : fd_to_handle (fd);
-  si.hStdOutput = fdout == -1? nullhd[1] : fd_to_handle (fdout);
-  si.hStdError  = fd_to_handle (rp[1]);
+  si.hStdInput  =   inhandle == INVALID_HANDLE_VALUE? nullhd[0] : inhandle;
+  si.hStdOutput = outpipe[1] == INVALID_HANDLE_VALUE? nullhd[1] : outpipe[1];
+  si.hStdError  = errpipe[1] == INVALID_HANDLE_VALUE? nullhd[2] : errpipe[1];
 
   cr_flags = (CREATE_DEFAULT_ERROR_MODE
               | ((flags & 128)? DETACHED_PROCESS : 0)
@@ -459,9 +530,19 @@
     {
       log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
       xfree (cmdline);
-      CloseHandle (fd_to_handle (rp[0]));
-      CloseHandle (fd_to_handle (rp[1]));
-      return gpg_error (GPG_ERR_GENERAL);
+      if (outfp)
+        es_fclose (outfp);
+      else if (outpipe[0] != INVALID_HANDLE_VALUE)
+        CloseHandle (outpipe[0]);
+      if (outpipe[1] != INVALID_HANDLE_VALUE)
+        CloseHandle (outpipe[1]);
+      if (errfp)
+        es_fclose (errfp);
+      else if (errpipe[0] != INVALID_HANDLE_VALUE)
+        CloseHandle (errpipe[0]);
+      if (errpipe[1] != INVALID_HANDLE_VALUE)
+        CloseHandle (errpipe[1]);
+      return gpg_err_make (errsource, GPG_ERR_GENERAL);
     }
   xfree (cmdline);
   cmdline = NULL;
@@ -471,17 +552,21 @@
     if (nullhd[i] != INVALID_HANDLE_VALUE)
       CloseHandle (nullhd[i]);
 
-  /* Close the other end of the pipe.  */
-  CloseHandle (fd_to_handle (rp[1]));
+  /* Close the inherited ends of the pipes.  */
+  if (outpipe[1] != INVALID_HANDLE_VALUE)
+    CloseHandle (outpipe[1]);
+  if (errpipe[1] != INVALID_HANDLE_VALUE)
+    CloseHandle (errpipe[1]);
   
-/*   log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
-/*              " dwProcessID=%d dwThreadId=%d\n", */
-/*              pi.hProcess, pi.hThread, */
-/*              (int) pi.dwProcessId, (int) pi.dwThreadId); */
-  
+  /* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
+  /*            " dwProcessID=%d dwThreadId=%d\n", */
+  /*            pi.hProcess, pi.hThread, */
+  /*            (int) pi.dwProcessId, (int) pi.dwThreadId); */
+  /* log_debug ("                     outfp=%p errfp=%p\n", outfp, errfp); */
+
   /* Fixme: For unknown reasons AllowSetForegroundWindow returns an
-     invalid argument error if we pass the correct processID to
-     it.  As a workaround we use -1 (ASFW_ANY).  */
+     invalid argument error if we pass it the correct processID.  As a
+     workaround we use -1 (ASFW_ANY).  */
   if ( (flags & 64) )
     gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
 
@@ -489,23 +574,11 @@
   ResumeThread (pi.hThread);
   CloseHandle (pi.hThread); 
 
-  {
-    int x;
+  if (r_outfp)
+    *r_outfp = outfp;
+  if (r_errfp)
+    *r_errfp = errfp;
 
-    x = _open_osfhandle (rp[0], 0);
-    if (x == -1)
-      log_error ("failed to translate osfhandle %p\n", (void*)rp[0] );
-    else 
-      *statusfile = es_fdopen (x, "r");
-  }
-  if (!*statusfile)
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err));
-      CloseHandle (pi.hProcess);
-      return err;
-    }
-
   *pid = handle_to_pid (pi.hProcess);
   return 0;
 

Modified: trunk/common/exechelp-w32ce.c
===================================================================
--- trunk/common/exechelp-w32ce.c	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/exechelp-w32ce.c	2010-08-20 12:18:38 UTC (rev 5401)
@@ -83,7 +83,7 @@
 };
 
 
-/* The thread started by start_feeded.  */
+/* The thread started by start_feede3.  */
 static void *
 feeder_thread (void *arg)
 {
@@ -485,10 +485,14 @@
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     estream_t infile, estream_t outfile,
+                     gpg_err_source_t errsource,
                      void (*preexec)(void), unsigned int flags,
-                     estream_t *statusfile, pid_t *pid)
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid)
 {
+#if 0
   gpg_error_t err;
   PROCESS_INFORMATION pi = {NULL };
   char *cmdline;
@@ -598,7 +602,9 @@
 
   *pid = handle_to_pid (pi.hProcess);
   return 0;
-
+#else
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
 }
 
 

Modified: trunk/common/exechelp.h
===================================================================
--- trunk/common/exechelp.h	2010-08-19 13:38:37 UTC (rev 5400)
+++ trunk/common/exechelp.h	2010-08-20 12:18:38 UTC (rev 5401)
@@ -52,16 +52,25 @@
 gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
 
 
-/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
-   stdin, write the output to OUTFILE.  INFILE or PUTFILE may be NULL
-   to connect thenm to /dev/null.  Returns a new stream in STATUSFILE
-   for stderr and the pid of the process in PID. The arguments for the
-   process are expected in the NULL terminated array ARGV.  The
-   program name itself should not be included there.  If PREEXEC is
-   not NULL, that function will be called right before the exec.
-   Calling gnupg_wait_process and gnupg_release_process is required.
-   Returns 0 on success or an error code.
+/* Fork and exec the PGMNAME.  If INFP is NULL connect /dev/null to
+   stdin of the new process; if it is not NULL connect the file
+   descriptor retrieved from INFP to stdin.  If R_OUTFP is NULL
+   connect stdout of the new process to /dev/null; if it is not NULL
+   store the address of a pointer to a new estream there.  If R_ERRFP
+   is NULL connect stderr of the new process to /dev/null; if it is
+   not NULL store the address of a pointer to a new estream there.  On
+   success the pid of the new process is stored at PID.  On error -1
+   is stored at PID and if R_OUTFP or R_ERRFP are not NULL, NULL is
+   stored there.
 
+   The arguments for the process are expected in the NULL terminated
+   array ARGV.  The program name itself should not be included there.
+   If PREEXEC is not NULL, the given function will be called right
+   before the exec. 
+
+   Returns 0 on success or an error code.  Calling gnupg_wait_process
+   and gnupg_release_process is required if the function succeeded.
+
    FLAGS is a bit vector:
 
    Bit 7: If set the process will be started as a background process.
@@ -74,10 +83,14 @@
           allows SetForegroundWindow for all childs of this process.
 
  */
-gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[],
-                                 estream_t infile, estream_t outfile,
-                                 void (*preexec)(void), unsigned int flags,
-                                 estream_t *statusfile, pid_t *pid);
+gpg_error_t
+gnupg_spawn_process (const char *pgmname, const char *argv[],
+                     gpg_err_source_t errsource,




More information about the Gnupg-commits mailing list