aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2018-02-07 03:43:07 +0000
committerNIIBE Yutaka <[email protected]>2018-02-07 03:43:07 +0000
commit015fe1c47b91da340e9df6bed908e0747ae8c60b (patch)
tree0aea137c75cabedc084bef46a7c312179a8b6831
parentgpg: Update list of card vendors from master (diff)
downloadgnupg-015fe1c47b91da340e9df6bed908e0747ae8c60b.tar.gz
gnupg-015fe1c47b91da340e9df6bed908e0747ae8c60b.zip
scd: Use pipe to kick the loop on NetBSD.
* 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 <[email protected]>
-rw-r--r--configure.ac16
-rw-r--r--scd/scdaemon.c39
2 files changed, 52 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 420af92f9..bdb614696 100644
--- a/configure.ac
+++ b/configure.ac
@@ -639,6 +639,7 @@ have_android_system=no
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
@@ -715,10 +716,20 @@ case "${host}" in
AC_DEFINE(_DARWIN_C_SOURCE, 900000L,
Expose all libc features (__DARWIN_C_FULL).)
;;
+ *-*-netbsd*)
+ require_pipe_to_unblock_pselect=yes
+ ;;
*)
- ;;
+ ;;
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
@@ -820,7 +831,8 @@ if test x"$LIBUSB_NAME" != x ; then
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}"
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 3ad265781..cebeea9d3 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -236,6 +236,10 @@ static HANDLE the_event;
/* 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
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));
+#elif defined(HAVE_PSELECT_NO_EINTR)
+ write (notify_fd, "", 1);
#else
ret = kill (main_thread_pid, SIGCONT);
if (ret < 0)
@@ -1241,6 +1247,17 @@ handle_connections (int listen_fd)
#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)
@@ -1298,6 +1315,7 @@ handle_connections (int listen_fd)
for (;;)
{
int periodical_check;
+ int max_fd = nfd;
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;
+#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
- 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;
@@ -1353,6 +1377,15 @@ handle_connections (int listen_fd)
/* 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;
@@ -1394,6 +1427,10 @@ handle_connections (int listen_fd)
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);