diff --git a/configure.in b/configure.in index 7b9bb969..2669be12 100644 --- a/configure.in +++ b/configure.in @@ -207,7 +207,7 @@ AC_CHECK_HEADERS([net/if.h], [], [], AC_CHECK_HEADERS(stdint.h inttypes.h) AC_CHECK_HEADERS(locale.h pwd.h) AC_CHECK_HEADERS(termios.h) - +AC_CHECK_HEADERS(poll.h) AC_CHECK_HEADERS(sys/un.h, [CONFIG_INTERLINK=yes @@ -312,6 +312,8 @@ AC_CHECK_FUNCS(kill, HAVE_KILL=yes) AC_CHECK_FUNCS(fpathconf, HAVE_FPATHCONF=yes) +AC_CHECK_FUNCS(poll, HAVE_POLL=yes) + if test x"$HAVE_RAISE" = x; then if test x"$HAVE_KILL" = x || test x"$HAVE_GETPID" = x; then AC_MSG_ERROR([Unable to emulate raise()]) diff --git a/src/main/select.c b/src/main/select.c index 48d28921..3f15800d 100644 --- a/src/main/select.c +++ b/src/main/select.c @@ -25,10 +25,23 @@ #ifdef HAVE_INTTYPES_H #include /* OMG */ #endif + +#if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(INTERIX) && !defined(__HOS_AIX__) +#define USE_POLL +#include +#endif + #ifdef HAVE_SYS_SELECT_H #include #endif +#define EINTRLOOPX(ret_, call_, x_) \ +do { \ + (ret_) = (call_); \ +} while ((ret_) == (x_) && errno == EINTR) + +#define EINTRLOOP(ret_, call_) EINTRLOOPX(ret_, call_, -1) + #include "elinks.h" #include "intl/gettext/libintl.h" @@ -340,6 +353,17 @@ select_loop(void (*init)(void)) static int can_read_or_write(int fd, int write) { +#if defined(USE_POLL) + struct pollfd p; + int rs; + p.fd = fd; + p.events = !write ? POLLIN : POLLOUT; + EINTRLOOP(rs, poll(&p, 1, 0)); + if (rs < 0) elinks_internal("ERROR: poll for %s (%d) failed: %s", !write ? "read" : "write", fd, strerror(errno)); + if (!rs) return 0; + if (p.revents & POLLNVAL) elinks_internal("ERROR: poll for %s (%d) failed: %s", !write ? "read" : "write", fd, strerror(errno)); + return 1; +#else struct timeval tv = {0, 0}; fd_set fds; fd_set *rfds = NULL; @@ -354,6 +378,7 @@ can_read_or_write(int fd, int write) rfds = &fds; return select(fd + 1, rfds, wfds, NULL, &tv); +#endif } int