* starttls.c (main): Use poll(2) emulation from gnulib; avoid some
authorueno <ueno>
Thu, 10 Aug 2006 22:25:22 +0000 (22:25 +0000)
committerueno <ueno>
Thu, 10 Aug 2006 22:25:22 +0000 (22:25 +0000)
race condition when waiting fd/signal.

ChangeLog
bootstrap
configure.in
starttls.c

index 42463f7..074639b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2006-08-10  Daiki Ueno  <ueno@unixuser.org>
 
+       * starttls.c (main): Use poll(2) emulation from gnulib; avoid some
+       race condition when waiting fd/signal.
+
+2006-08-10  Daiki Ueno  <ueno@unixuser.org>
+
        * Use gnulib.
 
        * starttls.c (main): Don't use basename.
index 084f373..2b7e481 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-gnulib-tool --import getaddrinfo getopt
+gnulib-tool --import getaddrinfo getopt poll
 autoreconf -f -i
 
 exit 0
index 13190a1..5fbf99f 100644 (file)
@@ -10,9 +10,7 @@ AC_PROG_INSTALL
 AC_PROG_MAKE_SET
 AC_PROG_RANLIB
 
-AC_CHECK_HEADERS(sys/select.h sys/poll.h)
 AC_CHECK_LIB(socket, socket)
-AC_CHECK_FUNC(poll)
 
 AC_ARG_WITH(openssl, AC_HELP_STRING([--with-openssl=PATH], [use OpenSSL from PATH]))
 AC_ARG_WITH(gnutls, AC_HELP_STRING([--with-gnutls], [use GnuTLS instead of OpenSSL]),
index a3ddf94..34a74eb 100644 (file)
 #include <signal.h>
 #include <fcntl.h>
 #include <netinet/in.h>
-#ifdef HAVE_POLL_H
-#include <sys/poll.h>
-#endif
-#include "getopt.h"
+#include <poll.h>
+#include <getopt.h>
 #include "getaddrinfo.h"
 #include "gettext.h"
 #include "inet_ntop.h"
@@ -124,15 +122,12 @@ main (argc, argv)
   int argc;
   char **argv;
 {
-  int in = fileno (stdin), out = fileno (stdout), 
+  int in = fileno (stdin), out = fileno (stdout),
     nbuffer, wrote;
-#ifdef HAVE_POLL
   struct pollfd readfds[2], writefds[1];
-#else
-  fd_set readfds, writefds;
-#endif
   char buffer[BUFSIZ], *retry;
   struct sigaction act;
+  sigset_t orig_mask;
 
   int this_option_optind = optind ? optind : 1;
   int option_index = 0, c;
@@ -179,37 +174,29 @@ main (argc, argv)
   memset (&act, 0, sizeof (act));
   act.sa_handler = do_tls_negotiate;
   sigemptyset (&act.sa_mask);
+  sigaddset (&act.sa_mask, SIGALRM);
   act.sa_flags = SA_RESTART|SA_RESETHAND;
   sigaction (SIGALRM, &act, NULL);
 
-#ifdef HAVE_POLL
   readfds[0].fd = in;
   readfds[1].fd = tls_fd;
   readfds[0].events = POLLIN;
   readfds[1].events = POLLIN;
   writefds[0].events = POLLOUT;
-#endif
 
   while (1)
     {
-#ifdef HAVE_POLL
-      if (poll (readfds, 2, -1) == -1 && errno != EINTR)
-#else
-      FD_ZERO (&readfds);
-      FD_SET (tls_fd, &readfds);
-      FD_SET (in, &readfds);
-      if (select (tls_fd+1, &readfds, NULL, NULL, NULL) == -1
-         && errno != EINTR )
-#endif
+      int ready;
+
+      sigprocmask (SIG_SETMASK, &act.sa_mask, &orig_mask);
+      ready = poll (readfds, 2, -1);
+      sigprocmask (SIG_SETMASK, &orig_mask, NULL);
+      if (ready == -1 && errno != EINTR)
        {
          perror ("poll");
          return 1;
        }
-#ifdef HAVE_POLL
       if (readfds[0].revents & POLLIN)
-#else
-      if (FD_ISSET (in, &readfds))
-#endif
        {
          nbuffer = read (in, buffer, sizeof buffer -1);
 
@@ -217,14 +204,11 @@ main (argc, argv)
            goto finish;
          for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote)
            {
-#ifdef HAVE_POLL
+             sigprocmask (SIG_SETMASK, &act.sa_mask, &orig_mask);
              writefds[0].fd = tls_fd;
-             if (poll (writefds, 1, -1) == -1)
-#else
-             FD_ZERO (&writefds);
-             FD_SET (tls_fd, &writefds);
-             if (select (tls_fd+1, NULL, &writefds, NULL, NULL) == -1)
-#endif
+             ready = poll (writefds, 1, -1);
+             sigprocmask (SIG_SETMASK, &orig_mask, NULL);
+             if (ready == -1 && errno != EINTR)
                {
                  perror ("poll");
                  return 1;
@@ -233,11 +217,7 @@ main (argc, argv)
              if (wrote < 0) goto finish;
            }
        }
-#ifdef HAVE_POLL
       if (readfds[1].revents & POLLIN)
-#else
-      if (FD_ISSET (tls_fd, &readfds))
-#endif
        {
 readtop:
          nbuffer = tls_read(tls_fd, buffer, sizeof buffer -1);
@@ -245,14 +225,11 @@ readtop:
            goto finish;
          for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote)
            {
-#ifdef HAVE_POLL
+             sigprocmask (SIG_SETMASK, &act.sa_mask, &orig_mask);
              writefds[0].fd = out;
-             if (poll (writefds, 1, -1) == -1)
-#else
-             FD_ZERO (&writefds);
-             FD_SET (out, &writefds);
-             if (select (out+1, NULL, &writefds, NULL, NULL) == -1)
-#endif
+             ready = poll (writefds, 1, -1);
+             sigprocmask (SIG_SETMASK, &orig_mask, NULL);
+             if (ready == -1 && errno != EINTR)
                {
                  perror ("poll");
                  return 1;