[git] GnuPG - branch, master, updated. gnupg-2.1.15-232-g2f7d4c3

by Werner Koch cvs at cvs.gnupg.org
Sat Oct 15 21:38:39 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  2f7d4c38c9e7bcc14e6e0bf219d688c40a4afecb (commit)
      from  c318561ef4c97f0c2767aef377531d58174060a1 (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 2f7d4c38c9e7bcc14e6e0bf219d688c40a4afecb
Author: Werner Koch <wk at gnupg.org>
Date:   Sat Oct 15 21:35:05 2016 +0200

    agent: Move inotify code to common and improve it.
    
    * common/sysutils.c: Include sys/inotify.h.
    (my_error_from_syserror, my_error): New.
    (gnupg_inotify_watch_socket): New.
    (gnupg_inotify_has_name): New.
    * agent/gpg-agent.c: Do not include sys/inotify.h.
    (my_inotify_is_name): Remove.
    (handle_connections): Remove HAVE_INOTIFY_INIT protected code and use
    the new functions.
    --
    
    When removing not a simple socket file but the entire directory the
    old code missed most events and thus did not worked properly.
    
    IN_DELETE_SELF has also been added to the watch list to detect a
    removal of the directory.  However, in all tests that event was not
    triggered.  The only way it could be triggered was by not watching
    the socket dir but an arbitary directory and rmdir that.
    
    GnuPG-bug-id: 2756
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 32e072b..16edae0 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -47,9 +47,6 @@
 #ifdef HAVE_SIGNAL_H
 # include <signal.h>
 #endif
-#ifdef HAVE_INOTIFY_INIT
-# include <sys/inotify.h>
-#endif /*HAVE_INOTIFY_INIT*/
 #include <npth.h>
 
 #define GNUPG_COMMON_NEED_AFLOCAL
@@ -2716,31 +2713,6 @@ start_connection_thread_ssh (void *arg)
 }
 
 
-#ifdef HAVE_INOTIFY_INIT
-/* Read an inotify event and return true if it matches NAME.  */
-static int
-my_inotify_is_name (int fd, const char *name)
-{
-  union {
-    struct inotify_event ev;
-    char _buf[sizeof (struct inotify_event) + 100 + 1];
-  } buf;
-  int n;
-
-  n = npth_read (fd, &buf, sizeof buf);
-  if (n < sizeof (struct inotify_event))
-    return 0;
-  if (buf.ev.len < strlen (name)+1)
-    return 0;
-  if (strcmp (buf.ev.name, name))
-    return 0; /* Not the desired file.  */
-
-  return 1; /* Found.  */
-}
-#endif /*HAVE_INOTIFY_INIT*/
-
-
-
 /* Connection handler loop.  Wait for connection requests and spawn a
    thread after accepting a connection.  */
 static void
@@ -2749,6 +2721,7 @@ handle_connections (gnupg_fd_t listen_fd,
                     gnupg_fd_t listen_fd_browser,
                     gnupg_fd_t listen_fd_ssh)
 {
+  gpg_error_t err;
   npth_attr_t tattr;
   struct sockaddr_un paddr;
   socklen_t plen;
@@ -2764,9 +2737,7 @@ handle_connections (gnupg_fd_t listen_fd,
   HANDLE events[2];
   unsigned int events_set;
 #endif
-#ifdef HAVE_INOTIFY_INIT
-  int my_inotify_fd;
-#endif /*HAVE_INOTIFY_INIT*/
+  int my_inotify_fd = -1;
   struct {
     const char *name;
     void *(*func) (void *arg);
@@ -2804,27 +2775,14 @@ handle_connections (gnupg_fd_t listen_fd,
 # endif
 #endif
 
-#ifdef HAVE_INOTIFY_INIT
   if (disable_check_own_socket)
     my_inotify_fd = -1;
-  else if ((my_inotify_fd = inotify_init ()) == -1)
-    log_info ("error enabling fast daemon termination: %s\n",
-              strerror (errno));
-  else
+  else if ((err = gnupg_inotify_watch_socket (&my_inotify_fd, socket_name)))
     {
-      /* We need to watch the directory for the file because there
-       * won't be an IN_DELETE_SELF for a socket file.  */
-      char *slash = strrchr (socket_name, '/');
-      log_assert (slash && slash[1]);
-      *slash = 0;
-      if (inotify_add_watch (my_inotify_fd, socket_name, IN_DELETE) == -1)
-        {
-          close (my_inotify_fd);
-          my_inotify_fd = -1;
-        }
-      *slash = '/';
+      if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
+        log_info ("error enabling fast daemon termination: %s\n",
+                  gpg_strerror (err));
     }
-#endif /*HAVE_INOTIFY_INIT*/
 
   /* On Windows we need to fire up a separate thread to listen for
      requests from Putty (an SSH client), so we can replace Putty's
@@ -2867,14 +2825,12 @@ handle_connections (gnupg_fd_t listen_fd,
       if (FD2INT (listen_fd_ssh) > nfd)
         nfd = FD2INT (listen_fd_ssh);
     }
-#ifdef HAVE_INOTIFY_INIT
   if (my_inotify_fd != -1)
     {
       FD_SET (my_inotify_fd, &fdset);
       if (my_inotify_fd > nfd)
         nfd = my_inotify_fd;
     }
-#endif /*HAVE_INOTIFY_INIT*/
 
   listentbl[0].l_fd = listen_fd;
   listentbl[1].l_fd = listen_fd_extra;
@@ -2949,14 +2905,13 @@ handle_connections (gnupg_fd_t listen_fd,
           ctrl_t ctrl;
           npth_t thread;
 
-#ifdef HAVE_INOTIFY_INIT
-          if (my_inotify_fd != -1 && FD_ISSET (my_inotify_fd, &read_fdset)
-              && my_inotify_is_name (my_inotify_fd, GPG_AGENT_SOCK_NAME))
+          if (my_inotify_fd != -1
+              && FD_ISSET (my_inotify_fd, &read_fdset)
+              && gnupg_inotify_has_name (my_inotify_fd, GPG_AGENT_SOCK_NAME))
             {
               shutdown_pending = 1;
               log_info ("socket file has been removed - shutting down\n");
             }
-#endif /*HAVE_INOTIFY_INIT*/
 
           for (idx=0; idx < DIM(listentbl); idx++)
             {
@@ -3004,10 +2959,8 @@ handle_connections (gnupg_fd_t listen_fd,
         }
     }
 
-#ifdef HAVE_INOTIFY_INIT
   if (my_inotify_fd != -1)
     close (my_inotify_fd);
-#endif /*HAVE_INOTIFY_INIT*/
   cleanup ();
   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
   npth_attr_destroy (&tattr);
diff --git a/common/sysutils.c b/common/sysutils.c
index 0f7b7f5..2e663bc 100644
--- a/common/sysutils.c
+++ b/common/sysutils.c
@@ -63,6 +63,9 @@
 # endif
 # include <windows.h>
 #endif
+#ifdef HAVE_INOTIFY_INIT
+# include <sys/inotify.h>
+#endif /*HAVE_INOTIFY_INIT*/
 #ifdef HAVE_NPTH
 # include <npth.h>
 #endif
@@ -78,6 +81,20 @@
 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
 
 
+static GPGRT_INLINE gpg_error_t
+my_error_from_syserror (void)
+{
+  return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+}
+
+static GPGRT_INLINE gpg_error_t
+my_error (int e)
+{
+  return gpg_err_make (default_errsource, (e));
+}
+
+
+
 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
 #warning using trap_unaligned
 static int
@@ -929,3 +946,113 @@ w32_get_user_sid (void)
   return sid;
 }
 #endif /*HAVE_W32_SYSTEM*/
+
+
+

+/* Support for inotify under Linux.  */
+
+/* Store a new inotify file handle for SOCKET_NAME at R_FD or return
+ * an error code. */
+gpg_error_t
+gnupg_inotify_watch_socket (int *r_fd, const char *socket_name)
+{
+#if HAVE_INOTIFY_INIT
+  gpg_error_t err;
+  char *fname;
+  int fd;
+  char *p;
+
+  *r_fd = -1;
+
+  fname = xtrystrdup (socket_name);
+  if (!fname)
+    return my_error_from_syserror ();
+
+  fd = inotify_init ();
+  if (fd == -1)
+    {
+      err = my_error_from_syserror ();
+      xfree (fname);
+      return err;
+    }
+
+  /* We need to watch the directory for the file because there won't
+   * be an IN_DELETE_SELF for a socket file.  To handle a removal of
+   * the directory we also watch the directory itself. */
+  p = strrchr (fname, '/');
+  if (p)
+    *p = 0;
+  if (inotify_add_watch (fd, fname,
+                         (IN_DELETE|IN_DELETE_SELF|IN_EXCL_UNLINK)) == -1)
+    {
+      err = my_error_from_syserror ();
+      close (fd);
+      xfree (fname);
+      return err;
+    }
+
+  xfree (fname);
+
+  *r_fd = fd;
+  return 0;
+#else /*!HAVE_INOTIFY_INIT*/
+
+  (void)socket_name;
+  *r_fd = -1;
+  return my_error (GPG_ERR_NOT_SUPPORTED);
+
+#endif /*!HAVE_INOTIFY_INIT*/
+}
+
+
+/* Read an inotify event and return true if it matches NAME or if it
+ * sees an IN_DELETE_SELF event for the directory of NAME.  */
+int
+gnupg_inotify_has_name (int fd, const char *name)
+{
+#if USE_NPTH && HAVE_INOTIFY_INIT
+  union {
+    struct inotify_event ev;
+    char _buf[sizeof (struct inotify_event) + 255 + 1];
+  } buf;
+  struct inotify_event *evp;
+  int n;
+
+  n = npth_read (fd, &buf, sizeof buf);
+  /* log_debug ("notify read: n=%d\n", n); */
+  evp = &buf.ev;
+  while (n >= sizeof (struct inotify_event))
+    {
+      /* log_debug ("             mask=%x len=%u name=(%s)\n", */
+      /*        evp->mask, (unsigned int)evp->len, evp->len? evp->name:""); */
+      if ((evp->mask & IN_UNMOUNT))
+        {
+          /* log_debug ("             found (dir unmounted)\n"); */
+          return 3; /* Directory was unmounted.  */
+        }
+      if ((evp->mask & IN_DELETE_SELF))
+        {
+          /* log_debug ("             found (dir removed)\n"); */
+          return 2; /* Directory was removed.  */
+        }
+      if ((evp->mask & IN_DELETE))
+        {
+          if (evp->len >= strlen (name) && !strcmp (evp->name, name))
+            {
+              /* log_debug ("             found (file removed)\n"); */
+              return 1; /* File was removed.  */
+            }
+        }
+      n -= sizeof (*evp) + evp->len;
+      evp = (struct inotify_event *)((char*)evp + sizeof (*evp) + evp->len);
+    }
+
+#else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
+
+  (void)fd;
+  (void)name;
+
+#endif  /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
+
+  return 0; /* Not found.  */
+}
diff --git a/common/sysutils.h b/common/sysutils.h
index ba66ce6..ea92e4c 100644
--- a/common/sysutils.h
+++ b/common/sysutils.h
@@ -67,6 +67,10 @@ int  gnupg_setenv (const char *name, const char *value, int overwrite);
 int  gnupg_unsetenv (const char *name);
 char *gnupg_getcwd (void);
 
+gpg_error_t gnupg_inotify_watch_socket (int *r_fd, const char *socket_name);
+int gnupg_inotify_has_name (int fd, const char *name);
+
+
 #ifdef HAVE_W32_SYSTEM
 void *w32_get_user_sid (void);
 

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

Summary of changes:
 agent/gpg-agent.c |  65 ++++------------------------
 common/sysutils.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 common/sysutils.h |   4 ++
 3 files changed, 140 insertions(+), 56 deletions(-)


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




More information about the Gnupg-commits mailing list