From 23e92a4f733713745a8f3dd38f109c35bb94f6fa Mon Sep 17 00:00:00 2001 From: ueno Date: Thu, 10 Aug 2006 22:25:22 +0000 Subject: [PATCH] * starttls.c (main): Use poll(2) emulation from gnulib; avoid some race condition when waiting fd/signal. --- ChangeLog | 5 +++++ bootstrap | 2 +- configure.in | 2 -- starttls.c | 61 ++++++++++++++++++---------------------------------------- 4 files changed, 25 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42463f7..074639b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2006-08-10 Daiki Ueno + * starttls.c (main): Use poll(2) emulation from gnulib; avoid some + race condition when waiting fd/signal. + +2006-08-10 Daiki Ueno + * Use gnulib. * starttls.c (main): Don't use basename. diff --git a/bootstrap b/bootstrap index 084f373..2b7e481 100755 --- 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 diff --git a/configure.in b/configure.in index 13190a1..5fbf99f 100644 --- a/configure.in +++ b/configure.in @@ -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]), diff --git a/starttls.c b/starttls.c index a3ddf94..34a74eb 100644 --- a/starttls.c +++ b/starttls.c @@ -44,10 +44,8 @@ #include #include #include -#ifdef HAVE_POLL_H -#include -#endif -#include "getopt.h" +#include +#include #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; -- 1.7.10.4