scd: Use pipe to kick the loop on NetBSD.
authorNIIBE Yutaka <gniibe@fsij.org>
Wed, 7 Feb 2018 03:43:07 +0000 (12:43 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Wed, 7 Feb 2018 03:43:07 +0000 (12:43 +0900)
* configure.ac (HAVE_PSELECT_NO_EINTR): New.
* scd/scdaemon.c (scd_kick_the_loop): Write to pipe.
(handle_connections): Use pipe.

--

On NetBSD, signal to the same process cannot unblock pselect,
with unknown reason.  Use pipe instead, for such systems.

GnuPG-bug-id: 3778
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
configure.ac
scd/scdaemon.c

index 420af92..bdb6146 100644 (file)
@@ -639,6 +639,7 @@ have_android_system=no
 use_simple_gettext=no
 use_ldapwrapper=yes
 mmap_needed=yes
 use_simple_gettext=no
 use_ldapwrapper=yes
 mmap_needed=yes
+require_pipe_to_unblock_pselect=no
 case "${host}" in
     *-mingw32*)
         # special stuff for Windoze NT
 case "${host}" in
     *-mingw32*)
         # special stuff for Windoze NT
@@ -715,10 +716,20 @@ case "${host}" in
         AC_DEFINE(_DARWIN_C_SOURCE, 900000L,
                   Expose all libc features (__DARWIN_C_FULL).)
         ;;
         AC_DEFINE(_DARWIN_C_SOURCE, 900000L,
                   Expose all libc features (__DARWIN_C_FULL).)
         ;;
+    *-*-netbsd*)
+        require_pipe_to_unblock_pselect=yes
+        ;;
     *)
     *)
-       ;;
+        ;;
 esac
 
 esac
 
+if test "$require_pipe_to_unblock_pselect" = yes; then
+   AC_DEFINE(HAVE_PSELECT_NO_EINTR, 1,
+             [Defined if we run on systems like NetBSD, where
+              pselect cannot be unblocked by signal from a thread
+              within the same process.  We use pipe in this case, instead.])
+fi
+
 if test "$have_dosish_system" = yes; then
    AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
              [Defined if we run on some of the PCDOS like systems
 if test "$have_dosish_system" = yes; then
    AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
              [Defined if we run on some of the PCDOS like systems
@@ -820,7 +831,8 @@ if test x"$LIBUSB_NAME" != x ; then
                   have_libusb=yes ])
    AC_MSG_CHECKING([libusb include dir])
    usb_incdir_found="no"
                   have_libusb=yes ])
    AC_MSG_CHECKING([libusb include dir])
    usb_incdir_found="no"
-   for _incdir in "" "/usr/include/libusb-1.0" "/usr/local/include/libusb-1.0"; do
+   for _incdir in "" "/usr/include/libusb-1.0" \
+       "/usr/local/include/libusb-1.0" "/usr/pkg/include/libusb-1.0"; do
      _libusb_save_cppflags=$CPPFLAGS
      if test -n "${_incdir}"; then
        CPPFLAGS="-I${_incdir} ${CPPFLAGS}"
      _libusb_save_cppflags=$CPPFLAGS
      if test -n "${_incdir}"; then
        CPPFLAGS="-I${_incdir} ${CPPFLAGS}"
index 3ad2657..cebeea9 100644 (file)
@@ -236,6 +236,10 @@ static HANDLE the_event;
 /* PID to notify update of usb devices.  */
 static pid_t main_thread_pid;
 #endif
 /* PID to notify update of usb devices.  */
 static pid_t main_thread_pid;
 #endif
+#ifdef HAVE_PSELECT_NO_EINTR
+/* FD to notify changes.  */
+static int notify_fd;
+#endif
 \f
 static char *create_socket_name (char *standard_name);
 static gnupg_fd_t create_server_socket (const char *name,
 \f
 static char *create_socket_name (char *standard_name);
 static gnupg_fd_t create_server_socket (const char *name,
@@ -1210,6 +1214,8 @@ scd_kick_the_loop (void)
   if (ret == 0)
     log_error ("SetEvent for scd_kick_the_loop failed: %s\n",
                w32_strerror (-1));
   if (ret == 0)
     log_error ("SetEvent for scd_kick_the_loop failed: %s\n",
                w32_strerror (-1));
+#elif defined(HAVE_PSELECT_NO_EINTR)
+  write (notify_fd, "", 1);
 #else
   ret = kill (main_thread_pid, SIGCONT);
   if (ret < 0)
 #else
   ret = kill (main_thread_pid, SIGCONT);
   if (ret < 0)
@@ -1241,6 +1247,17 @@ handle_connections (int listen_fd)
 #else
   int signo;
 #endif
 #else
   int signo;
 #endif
+#ifdef HAVE_PSELECT_NO_EINTR
+  int pipe_fd[2];
+
+  ret = gnupg_create_pipe (pipe_fd);
+  if (ret)
+    {
+      log_error ("pipe creation failed: %s\n", gpg_strerror (ret));
+      return;
+    }
+  notify_fd = pipe_fd[1];
+#endif
 
   ret = npth_attr_init(&tattr);
   if (ret)
 
   ret = npth_attr_init(&tattr);
   if (ret)
@@ -1298,6 +1315,7 @@ handle_connections (int listen_fd)
   for (;;)
     {
       int periodical_check;
   for (;;)
     {
       int periodical_check;
+      int max_fd = nfd;
 
       if (shutdown_pending)
         {
 
       if (shutdown_pending)
         {
@@ -1326,8 +1344,14 @@ handle_connections (int listen_fd)
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
+#ifdef HAVE_PSELECT_NO_EINTR
+      FD_SET (pipe_fd[0], &read_fdset);
+      if (max_fd < pipe_fd[0])
+        max_fd = pipe_fd[0];
+#endif
+
 #ifndef HAVE_W32_SYSTEM
 #ifndef HAVE_W32_SYSTEM
-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, t,
+      ret = npth_pselect (max_fd+1, &read_fdset, NULL, NULL, t,
                           npth_sigev_sigmask ());
       saved_errno = errno;
 
                           npth_sigev_sigmask ());
       saved_errno = errno;
 
@@ -1353,6 +1377,15 @@ handle_connections (int listen_fd)
         /* Timeout.  Will be handled when calculating the next timeout.  */
         continue;
 
         /* Timeout.  Will be handled when calculating the next timeout.  */
         continue;
 
+#ifdef HAVE_PSELECT_NO_EINTR
+      if (FD_ISSET (pipe_fd[0], &read_fdset))
+        {
+          char buf[256];
+
+          read (pipe_fd[0], buf, sizeof buf);
+        }
+#endif
+
       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
         {
           ctrl_t ctrl;
       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
         {
           ctrl_t ctrl;
@@ -1394,6 +1427,10 @@ handle_connections (int listen_fd)
   if (the_event != INVALID_HANDLE_VALUE)
     CloseHandle (the_event);
 #endif
   if (the_event != INVALID_HANDLE_VALUE)
     CloseHandle (the_event);
 #endif
+#ifdef HAVE_PSELECT_NO_EINTR
+  close (pipe_fd[0]);
+  close (pipe_fd[1]);
+#endif
   cleanup ();
   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
   npth_attr_destroy (&tattr);
   cleanup ();
   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
   npth_attr_destroy (&tattr);