More work on the dirmngr. It now builds for W32 and W32CE and quick
[gnupg.git] / common / iobuf.c
index 759a498..b9bed32 100644 (file)
@@ -37,6 +37,8 @@
 # include <swis.h>
 #endif /* __riscos__ */
 
+#include <assuan.h>
+
 #include "util.h"
 #include "sysutils.h"
 #include "iobuf.h"
 
 
 #ifdef HAVE_W32_SYSTEM
-# define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
-# define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
+# ifdef HAVE_W32CE_SYSTEM
+#  define FD_FOR_STDIN  (es_fileno (es_stdin))
+#  define FD_FOR_STDOUT (es_fileno (es_stdout))
+# else
+#  define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
+#  define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
+# endif
 #else /*!HAVE_W32_SYSTEM*/
 # define FD_FOR_STDIN  (0)
 # define FD_FOR_STDOUT (1)
@@ -1156,18 +1163,10 @@ iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode)
 {
   iobuf_t a;
 
-  if (fd == -1)
+  if (fd == GNUPG_INVALID_FD)
     a = iobuf_open (fname);
   else
-    {
-      int fd2;
-
-      fd2 = dup (fd);
-      if (fd2 == -1)
-        a = NULL;
-      else
-        a = iobuf_fdopen (fd2, mode);
-    }
+    a = iobuf_fdopen_nc (FD2INT(fd), mode);
   return a;
 }
 
@@ -1214,36 +1213,50 @@ iobuf_open (const char *fname)
   return a;
 }
 
-/****************
- * Create a head iobuf for reading or writing from/to a file
- * Returns: NULL if an error occures and sets ERRNO.
- */
-iobuf_t
-iobuf_fdopen (int fd, const char *mode)
+
+static iobuf_t
+do_iobuf_fdopen (int fd, const char *mode, int keep_open)
 {
   iobuf_t a;
   gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
 
-  fp = (gnupg_fd_t) fd;
+  fp = INT2FD (fd);
 
   a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + 20);
   fcx->fp = fp;
   fcx->print_only_name = 1;
+  fcx->keep_open = keep_open;
   sprintf (fcx->fname, "[fd %d]", fd);
   a->filter = file_filter;
   a->filter_ov = fcx;
   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname);
-  iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
+    log_debug ("iobuf-%d.%d: fdopen%s `%s'\n",
+               a->no, a->subno, keep_open? "_nc":"", fcx->fname);
+  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
   return a;
 }
 
 
+/* Create a head iobuf for reading or writing from/to a file Returns:
+ * NULL and sets ERRNO if an error occured.  */
+iobuf_t
+iobuf_fdopen (int fd, const char *mode)
+{
+  return do_iobuf_fdopen (fd, mode, 0);
+}
+
+iobuf_t
+iobuf_fdopen_nc (int fd, const char *mode)
+{
+  return do_iobuf_fdopen (fd, mode, 1);
+}
+
+
 iobuf_t
 iobuf_sockopen (int fd, const char *mode)
 {
@@ -1263,7 +1276,7 @@ iobuf_sockopen (int fd, const char *mode)
   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
     log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
-  iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
+  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
 #else
   a = iobuf_fdopen (fd, mode);
 #endif
@@ -1311,40 +1324,6 @@ iobuf_create (const char *fname)
   return a;
 }
 
-/****************
- * append to an iobuf; if the file does not exist, create it.
- * cannot be used for stdout.
- * Note: This is not used.
- */
-#if 0                          /* not used */
-iobuf_t
-iobuf_append (const char *fname)
-{
-  iobuf_t a;
-  FILE *fp;
-  file_filter_ctx_t *fcx;
-  size_t len;
-
-  if (!fname)
-    return NULL;
-  else if (!(fp = direct_open (fname, "ab")))
-    return NULL;
-  a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
-  fcx = m_alloc (sizeof *fcx + strlen (fname));
-  fcx->fp = fp;
-  strcpy (fcx->fname, fname);
-  a->real_fname = m_strdup (fname);
-  a->filter = file_filter;
-  a->filter_ov = fcx;
-  file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
-  file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
-  if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno,
-               a->desc?a->desc:"?");
-
-  return a;
-}
-#endif
 
 iobuf_t
 iobuf_openrw (const char *fname)
@@ -1376,12 +1355,15 @@ iobuf_openrw (const char *fname)
 
 
 int
-iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
+iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
 {
-  if (cmd == 1)
-    {                          /* keep system filepointer/descriptor open */
+  if (cmd == IOBUF_IOCTL_KEEP_OPEN)
+    {                          
+      /* Keep system filepointer/descriptor open.  This was used in
+         the past by http.c; this ioctl is not directly used
+         anymore.  */
       if (DBG_IOBUF)
-       log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n",
+       log_debug ("iobuf-%d.%d: ioctl `%s' keep_open=%d\n",
                   a ? a->no : -1, a ? a->subno : -1, 
                    a && a->desc ? a->desc : "?",
                   intval);
@@ -1401,8 +1383,8 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          }
 #endif
     }
-  else if (cmd == 2)
-    {                          /* invalidate cache */
+  else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
+    {
       if (DBG_IOBUF)
        log_debug ("iobuf-*.*: ioctl `%s' invalidate\n",
                   ptrval ? (char *) ptrval : "?");
@@ -1413,8 +1395,8 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          return 0;
        }
     }
-  else if (cmd == 3)
-    {                          /* disallow/allow caching */
+  else if (cmd == IOBUF_IOCTL_NO_CACHE)
+    {
       if (DBG_IOBUF)
        log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
                   a ? a->no : -1, a ? a->subno : -1, 
@@ -1436,7 +1418,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          }
 #endif
     }
-  else if (cmd == 4)
+  else if (cmd == IOBUF_IOCTL_FSYNC)
     {
       /* Do a fsync on the open fd and return any errors to the caller
          of iobuf_ioctl.  Note that we work on a file name here. */
@@ -2386,7 +2368,12 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
 static int
 translate_file_handle (int fd, int for_write)
 {
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32CE_SYSTEM)
+  /* This is called only with one of the special filenames.  Under
+     W32CE the FD here is not a file descriptor but a rendezvous id,
+     thus we need to finish the pipe first.  */
+  fd = _assuan_w32ce_finish_pipe (fd, for_write);
+#elif defined(HAVE_W32_SYSTEM)
   {
     int x;