summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2019-06-26 09:59:59 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2019-06-26 10:04:42 +0900
commita21a7de8c2cf986235382e7e04805744f6df116e (patch)
treee605ab6a3da933924487a5d63647ae089e3b06d7
parent6c2fc52d72b4dbd9dac44d9c3105dc3e8a4d5605 (diff)
downloadlibgpg-error-a21a7de8c2cf986235382e7e04805744f6df116e.tar.gz
estream: Use poll(2) when available.
* configure.ac: Detect poll.h. * src/estream.c [HAVE_POLL_H] (_gpgrt_poll): Use poll. -- Here, we use C99 feature of array declaration with variable. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--configure.ac2
-rw-r--r--src/estream.c82
2 files changed, 83 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index dc93071..4c78f45 100644
--- a/configure.ac
+++ b/configure.ac
@@ -190,7 +190,7 @@ AM_GNU_GETTEXT([external])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h locale.h stdint.h sys/select.h sys/time.h \
- signal.h])
+ signal.h poll.h])
AC_FUNC_STRERROR_R
case "${host_os}" in
diff --git a/src/estream.c b/src/estream.c
index 8b7ccc5..668eb1b 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -89,6 +89,10 @@
# include <winsock2.h>
# endif
# include <windows.h>
+#else
+# ifdef HAVE_POLL_H
+# include <poll.h>
+# endif
#endif
/* Enable tracing. The value is the module name to be printed. */
@@ -4782,9 +4786,14 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
int count = 0;
int idx;
#ifndef HAVE_W32_SYSTEM
+# ifdef HAVE_POLL_H
+ struct pollfd poll_fds[nfds];
+ nfds_t poll_nfds;
+# else
fd_set readfds, writefds, exceptfds;
int any_readfd, any_writefd, any_exceptfd;
int max_fd;
+#endif
int fd, ret, any;
#endif /*HAVE_W32_SYSTEM*/
@@ -4841,7 +4850,33 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
_gpgrt_post_syscall ();
#else /*!HAVE_W32_SYSTEM*/
+# ifdef HAVE_POLL_H
+ poll_nfds = 0;
+ for (item = fds, idx = 0; idx < nfds; item++, idx++)
+ {
+ if (item->ignore)
+ continue;
+ fd = _gpgrt_fileno (item->stream);
+ if (fd == -1)
+ continue; /* Stream does not support polling. */
+
+ if (item->want_read || item->want_write || item->want_oob)
+ {
+ poll_fds[poll_nfds].fd = fd;
+ poll_fds[poll_nfds].events = ((item->want_read ? POLLIN : 0)
+ | (item->want_write ? POLLOUT : 0)
+ |(item->want_read ? POLLPRI : 0));
+ poll_fds[poll_nfds].revents = 0;
+ poll_nfds++;
+ }
+ }
+ _gpgrt_pre_syscall ();
+ do
+ ret = poll (poll_fds, poll_nfds, timeout);
+ while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+ _gpgrt_post_syscall ();
+# else /* !HAVE_POLL_H */
any_readfd = any_writefd = any_exceptfd = 0;
max_fd = 0;
for (item = fds, idx = 0; idx < nfds; item++, idx++)
@@ -4902,10 +4937,15 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
}
while (ret == -1 && errno == EINTR);
_gpgrt_post_syscall ();
+# endif
if (ret == -1)
{
+# ifdef HAVE_POLL_H
+ trace_errno (1, ("poll failed: "));
+# else
trace_errno (1, ("select failed: "));
+# endif
count = -1;
goto leave;
}
@@ -4917,6 +4957,47 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
goto leave;
}
+# ifdef HAVE_POLL_H
+ poll_nfds = 0;
+ for (item = fds, idx = 0; idx < nfds; item++, idx++)
+ {
+ if (item->ignore)
+ continue;
+ fd = _gpgrt_fileno (item->stream);
+ if (fd == -1)
+ {
+ item->got_err = 1; /* Stream does not support polling. */
+ count++;
+ continue;
+ }
+
+ any = 0;
+ if (item->stream->intern->indicators.hup)
+ {
+ item->got_hup = 1;
+ any = 1;
+ }
+ if (item->want_read && (poll_fds[poll_nfds].revents & POLLIN))
+ {
+ item->got_read = 1;
+ any = 1;
+ }
+ if (item->want_write && (poll_fds[poll_nfds].revents & POLLOUT))
+ {
+ item->got_write = 1;
+ any = 1;
+ }
+ if (item->want_oob && (poll_fds[poll_nfds].revents & ~(POLLIN|POLLOUT)))
+ {
+ item->got_oob = 1;
+ any = 1;
+ }
+
+ poll_nfds++;
+ if (any)
+ count++;
+ }
+# else
for (item = fds, idx = 0; idx < nfds; item++, idx++)
{
if (item->ignore)
@@ -4954,6 +5035,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
if (any)
count++;
}
+# endif
#endif /*!HAVE_W32_SYSTEM*/
leave: