2007-07-13 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Fri, 13 Jul 2007 00:43:17 +0000 (00:43 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Fri, 13 Jul 2007 00:43:17 +0000 (00:43 +0000)
* assuan/assuan-io.c (_assuan_simple_read, _assuan_simple_write):
Always use read/write (which means _gpgme_io_read and
_gpgme_io_write).

gpgme/
2007-07-13  Marcus Brinkmann  <marcus@g10code.de>

* priv-io.h (_gpgme_io_set_close_notify): Change type of HANDLER
to _gpgme_close_notify_handler.
(_gpgme_close_notify_handler): New type.
(_gpgme_io_dup): Remove prototype.
* posix-io.c (notify_table, _gpgme_io_set_close_notify): Change
type of HANDLER to _gpgme_close_notify_handler_t.
(_gpgme_io_close): Do not close the FD if handler returns 0.
(_gpgme_io_dup): Remove function.
* w32-io.c (notify_table, _gpgme_io_set_close_notify,
_gpgme_io_close): Change type of HANDLER to
_gpgme_close_notify_handler_t.
(_gpgme_io_close): Do not close the FD if handler returns 0.
(_gpgme_io_dup): Remove function.
* w32-glib-io.c (_gpgme_io_dup): Remove function.
(_gpgme_io_set_close_notify, notify_table): Change type of HANDLER
to _gpgme_close_notify_handler_t.
(_gpgme_io_close): Do not close the FD if handler returns 0.
* rungpg.c (close_notify_handler): Change return type to int,
return 1.
* engine-gpgsm.c (close_notify_handler): Change return type to
int, return 0 for status FD and 1 for all other FDs.
(start): Do not duplicate the status FD.

ChangeLog
assuan/README.1st
assuan/assuan-io.c
gpgme/ChangeLog
gpgme/engine-gpgsm.c
gpgme/posix-io.c
gpgme/priv-io.h
gpgme/rungpg.c
gpgme/w32-glib-io.c
gpgme/w32-io.c

index ff4d875..e97bff3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-07-13  Marcus Brinkmann  <marcus@g10code.de>
+
+       * assuan/assuan-io.c (_assuan_simple_read, _assuan_simple_write):
+       Always use read/write (which means _gpgme_io_read and
+       _gpgme_io_write).
+
 2007-07-09  Marcus Brinkmann  <marcus@g10code.de>
 
        Released 1.1.5.
index c755cfe..8e805c3 100644 (file)
@@ -27,7 +27,13 @@ updating this directory, are:
   We don't need this file as GPGME doesn't use sendmsg and recvmsg.
   If it would, we would need to pick up the W32 implementation.
 
- Copyright 2004 g10 Code GmbH
+* assuan-io.c
+** _assuan_simple_read() and _assuan_simple_write() must always use
+   read()/write() (which actually translates to _gpgme_io_read() and
+   _gpgme_io_write()).
+
+
+ Copyright 2004, 2007 g10 Code GmbH
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
index 066231f..a7f8449 100644 (file)
@@ -51,7 +51,7 @@ _assuan_waitpid (pid_t pid, int *status, int options)
 ssize_t
 _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
 {
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
   /* Due to the peculiarities of the W32 API we can't use read for a
      network socket and thus we try to use recv first and fallback to
      read if recv detects that it is not a network socket.  */
@@ -84,7 +84,7 @@ _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
 ssize_t
 _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
 {
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
   /* Due to the peculiarities of the W32 API we can't use write for a
      network socket and thus we try to use send first and fallback to
      write if send detects that it is not a network socket.  */
index 7b01625..33f9b23 100644 (file)
@@ -1,3 +1,28 @@
+2007-07-13  Marcus Brinkmann  <marcus@g10code.de>
+
+       * priv-io.h (_gpgme_io_set_close_notify): Change type of HANDLER
+       to _gpgme_close_notify_handler.
+       (_gpgme_close_notify_handler): New type.
+       (_gpgme_io_dup): Remove prototype.
+       * posix-io.c (notify_table, _gpgme_io_set_close_notify): Change
+       type of HANDLER to _gpgme_close_notify_handler_t.
+       (_gpgme_io_close): Do not close the FD if handler returns 0.
+       (_gpgme_io_dup): Remove function.
+       * w32-io.c (notify_table, _gpgme_io_set_close_notify,
+       _gpgme_io_close): Change type of HANDLER to
+       _gpgme_close_notify_handler_t.
+       (_gpgme_io_close): Do not close the FD if handler returns 0.
+       (_gpgme_io_dup): Remove function.
+       * w32-glib-io.c (_gpgme_io_dup): Remove function.
+       (_gpgme_io_set_close_notify, notify_table): Change type of HANDLER
+       to _gpgme_close_notify_handler_t.
+       (_gpgme_io_close): Do not close the FD if handler returns 0.
+       * rungpg.c (close_notify_handler): Change return type to int,
+       return 1.
+       * engine-gpgsm.c (close_notify_handler): Change return type to
+       int, return 0 for status FD and 1 for all other FDs.
+       (start): Do not duplicate the status FD.
+
 2007-07-12  Marcus Brinkmann  <marcus@g10code.de>
 
        * Makefile.am: Replace implicite rule by suffix rule.  Add
index 0b78c29..4827fbe 100644 (file)
@@ -112,7 +112,7 @@ gpgsm_get_req_version (void)
 }
 
 \f
-static void
+static int
 close_notify_handler (int fd, void *opaque)
 {
   engine_gpgsm_t gpgsm = opaque;
@@ -124,6 +124,9 @@ close_notify_handler (int fd, void *opaque)
        (*gpgsm->io_cbs.remove) (gpgsm->status_cb.tag);
       gpgsm->status_cb.fd = -1;
       gpgsm->status_cb.tag = NULL;
+      /* We do not want to close the status FD, as it is controled by
+        Assuan.  */
+      return 0;
     }
   else if (gpgsm->input_cb.fd == fd)
     {
@@ -146,6 +149,7 @@ close_notify_handler (int fd, void *opaque)
       gpgsm->message_cb.fd = -1;
       gpgsm->message_cb.tag = NULL;
     }
+  return 1;
 }
 
 
@@ -983,20 +987,16 @@ start (engine_gpgsm_t gpgsm, const char *command)
   if (nfds < 1)
     return gpg_error (GPG_ERR_GENERAL);        /* FIXME */
 
-  /* We duplicate the file descriptor, so we can close it without
-     disturbing assuan.  Alternatively, we could special case
-     status_fd and register/unregister it manually as needed, but this
-     increases code duplication and is more complicated as we can not
-     use the close notifications etc.  */
-
-  gpgsm->status_cb.fd = _gpgme_io_dup (fdlist[0]);
-  if (gpgsm->status_cb.fd < 0)
-    return gpg_error_from_syserror ();
+  /* We used to duplicate the file descriptor so that we do not
+  disturb Assuan.  But this gets in the way of the Handle-to-Thread
+  mapping in w32-io.c, so instead we just share the file descriptor
+  *carefully*, by avoiding to close it ourselves (this is achieved by
+  returning 0 from the close_notify_handler for this descriptor).  */
+  gpgsm->status_cb.fd = fdlist[0];
 
   if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
                                  close_notify_handler, gpgsm))
     {
-      close (gpgsm->status_cb.fd);
       gpgsm->status_cb.fd = -1;
       return gpg_error (GPG_ERR_GENERAL);
     }
index 82142f8..6ebe42a 100644 (file)
@@ -69,7 +69,7 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd)
 \f
 static struct
 {
-  void (*handler) (int,void*);
+  _gpgme_close_notify_handler_t handler;
   void *value;
 } notify_table[256];
 
@@ -139,6 +139,8 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
 int
 _gpgme_io_close (int fd)
 {
+  int really_close = 1;
+
   if (fd == -1)
     return -1;
   /* First call the notify handler.  */
@@ -147,18 +149,22 @@ _gpgme_io_close (int fd)
     {
       if (notify_table[fd].handler)
        {
-         notify_table[fd].handler (fd, notify_table[fd].value);
+         really_close = notify_table[fd].handler (fd, notify_table[fd].value);
          notify_table[fd].handler = NULL;
          notify_table[fd].value = NULL;
         }
     }
   /* Then do the close.  */    
-  return close (fd);
+  if (really_close)
+    return close (fd);
+
+  return 0;
 }
 
 
 int
-_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
+                           void *value)
 {
   assert (fd != -1);
 
@@ -493,10 +499,3 @@ _gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags)
   errno = saved_errno;
   return nwritten;
 }
-
-
-int
-_gpgme_io_dup (int fd)
-{
-  return dup (fd);
-}
index 6b42284..602fede 100644 (file)
@@ -47,7 +47,8 @@ int _gpgme_io_read (int fd, void *buffer, size_t count);
 int _gpgme_io_write (int fd, const void *buffer, size_t count);
 int _gpgme_io_pipe (int filedes[2], int inherit_idx);
 int _gpgme_io_close (int fd);
-int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *),
+typedef int (*_gpgme_close_notify_handler_t) (int,void*);
+int _gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
                                void *value);
 int _gpgme_io_set_nonblocking (int fd);
 
@@ -64,7 +65,4 @@ int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);
    line that the child process expects.  */
 int _gpgme_io_fd2str (char *buf, int buflen, int fd);
 
-/* Like dup().  */
-int _gpgme_io_dup (int fd);
-
 #endif /* IO_H */
index d6fd8fe..91fc1ad 100644 (file)
@@ -141,7 +141,7 @@ gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data)
 }
 
 
-static void
+static int
 close_notify_handler (int fd, void *opaque)
 {
   engine_gpg_t gpg = opaque;
@@ -183,6 +183,7 @@ close_notify_handler (int fd, void *opaque)
             }
         }
     }
+  return 1;
 }
 
 /* If FRONT is true, push at the front of the list.  Use this for
index 183a560..3372776 100644 (file)
@@ -123,10 +123,11 @@ _gpgme_io_subsystem_init (void)
 \f
 static struct
 {
-  void (*handler) (int,void*);
+  _gpgme_close_notify_handler_t handler;
   void *value;
 } notify_table[MAX_SLAFD];
 
+
 int
 _gpgme_io_read (int fd, void *buffer, size_t count)
 {
@@ -270,6 +271,7 @@ int
 _gpgme_io_close (int fd)
 {
   GIOChannel *chan;
+  int really_close = 1;
 
   if (fd < 0 || fd >= MAX_SLAFD)
     {
@@ -281,29 +283,32 @@ _gpgme_io_close (int fd)
   DEBUG1 ("closing fd %d", fd);
   if (notify_table[fd].handler)
     {
-      notify_table[fd].handler (fd, notify_table[fd].value);
+      really_close = notify_table[fd].handler (fd, notify_table[fd].value);
       notify_table[fd].handler = NULL;
       notify_table[fd].value = NULL;
     }
 
   /* Then do the close.  */    
-  chan = giochannel_table[fd];
-  if (chan)
+  if (really_close)
     {
-      g_io_channel_shutdown (chan, 1, NULL);
-      g_io_channel_unref (chan);
-      giochannel_table[fd] = NULL;
+      chan = giochannel_table[fd];
+      if (chan)
+       {
+         g_io_channel_shutdown (chan, 1, NULL);
+         g_io_channel_unref (chan);
+         giochannel_table[fd] = NULL;
+       }
+      else
+       _close (fd);
     }
-  else
-    _close (fd);
-
 
   return 0;
 }
 
 
 int
-_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
+                           void *value)
 {
   assert (fd != -1);
 
@@ -660,11 +665,3 @@ leave:
   free (pollfds_map);
   return count;
 }
-
-
-int
-_gpgme_io_dup (int fd)
-{
-  return _dup (fd);
-}  
-
index 947bb62..3b034f6 100644 (file)
 #define MAX_READERS 20
 #define MAX_WRITERS 20
 
-static struct {
-    int inuse;
-    int fd;
-    void (*handler)(int,void*);
-    void *value;
+static struct
+{
+  int inuse;
+  int fd;
+  _gpgme_close_notify_handler_t handler;
+  void *value;
 } notify_table[256];
 DEFINE_STATIC_LOCK (notify_table_lock);
 
@@ -726,8 +727,9 @@ int
 _gpgme_io_close ( int fd )
 {
     int i;
-    void (*handler)(int, void*) = NULL;
+    _gpgme_close_notify_handler_t handler = NULL;
     void *value = NULL;
+    int really_close = 1;
 
     if ( fd == -1 )
         return -1;
@@ -738,7 +740,7 @@ _gpgme_io_close ( int fd )
     LOCK (notify_table_lock);
     for ( i=0; i < DIM (notify_table); i++ ) {
         if (notify_table[i].inuse && notify_table[i].fd == fd) {
-            handler = notify_table[i].handler;
+           handler = notify_table[i].handler;
             value   = notify_table[i].value;
             notify_table[i].handler = NULL;
             notify_table[i].value = NULL;
@@ -748,9 +750,9 @@ _gpgme_io_close ( int fd )
     }
     UNLOCK (notify_table_lock);
     if (handler)
-        handler (fd, value);
+        really_close = handler (fd, value);
 
-    if ( !CloseHandle (fd_to_handle (fd)) ) { 
+    if ( really_close && !CloseHandle (fd_to_handle (fd)) ) { 
         DEBUG2 ("CloseHandle for fd %d failed: ec=%d\n",
                  fd, (int)GetLastError ());
         return -1;
@@ -760,7 +762,8 @@ _gpgme_io_close ( int fd )
 }
 
 int
-_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
+                           void *value)
 {
     int i;
 
@@ -1140,25 +1143,6 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd)
   return snprintf (buf, buflen, "%d", fd);
 }
 
-
-int
-_gpgme_io_dup (int fd)
-{
-  HANDLE handle = fd_to_handle (fd);
-  HANDLE new_handle = fd_to_handle (fd);
-    
-  /* For NT we have to set the sync flag.  It seems that the only
-   * way to do it is by duplicating the handle.  Tsss.. */
-  if (!DuplicateHandle( GetCurrentProcess(), handle,
-                       GetCurrentProcess(), &new_handle,
-                       0, FALSE, DUPLICATE_SAME_ACCESS))
-    {
-      DEBUG1 ("** DuplicateHandle failed: ec=%d\n", (int) GetLastError());
-    }
-
-  return handle_to_fd (new_handle);
-}  
-
 \f
 /* The following interface is only useful for GPGME Glib.  */