summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémie Courrèges-Anglas <jca@wxcvbn.org>2013-04-16 11:09:42 +0200
committerJérémie Courrèges-Anglas <jca@wxcvbn.org>2013-04-16 11:09:42 +0200
commit24b078a5a126fc7c7c207747d5f2e20022264e9f (patch)
tree0882bc0f54c9e2fd49666def43ebaa5b93a90413
parentfbd2d184fb37a10ec7199ba72e83d4274a605387 (diff)
workaround for systems not providing pselect
using a mix of good old select and sigprocmask Signed-off-by: Jérémie Courrèges-Anglas <jca@wxcvbn.org>
-rw-r--r--configure.ac2
-rw-r--r--src/util/select.h21
2 files changed, 20 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 5be21c8..11153ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -195,7 +195,7 @@ AC_TYPE_UINTPTR_T
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_MBRTOWC
-AC_CHECK_FUNCS([gettimeofday setrlimit inet_ntoa iswprint memchr memset nl_langinfo posix_memalign setenv setlocale sigaction socket strchr strdup strncasecmp strtok strerror strtol wcwidth cfmakeraw])
+AC_CHECK_FUNCS([gettimeofday setrlimit inet_ntoa iswprint memchr memset nl_langinfo posix_memalign setenv setlocale sigaction socket strchr strdup strncasecmp strtok strerror strtol wcwidth cfmakeraw pselect])
AC_SEARCH_LIBS([clock_gettime], [rt], [AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if clock_gettime is available.])])
diff --git a/src/util/select.h b/src/util/select.h
index dc06716..6d9922f 100644
--- a/src/util/select.h
+++ b/src/util/select.h
@@ -118,6 +118,7 @@ public:
fatal_assert( 0 == sigaction( signum, &sa, NULL ) );
}
+ /* timeout unit: milliseconds; negative timeout means wait forever */
int select( int timeout )
{
memcpy( &read_fds, &all_fds, sizeof( read_fds ) );
@@ -125,18 +126,34 @@ public:
clear_got_signal();
got_any_signal = 0;
+#ifdef HAVE_PSELECT
struct timespec ts;
struct timespec *tsp = NULL;
if ( timeout >= 0 ) {
- // timeout in milliseconds
ts.tv_sec = timeout / 1000;
ts.tv_nsec = 1000000 * (long( timeout ) % 1000);
tsp = &ts;
}
- // negative timeout means wait forever
int ret = ::pselect( max_fd + 1, &read_fds, NULL, &error_fds, tsp, &empty_sigset );
+#else
+ struct timeval tv;
+ struct timeval *tvp = NULL;
+ sigset_t old_sigset;
+
+ if ( timeout >= 0 ) {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = 1000 * (long( timeout ) % 1000);
+ tvp = &tv;
+ }
+
+ int ret = sigprocmask( SIG_SETMASK, &empty_sigset, &old_sigset );
+ if ( ret != -1 ) {
+ ret = ::select( max_fd + 1, &read_fds, NULL, &error_fds, tvp );
+ sigprocmask( SIG_SETMASK, &old_sigset, NULL );
+ }
+#endif
if ( ( ret == -1 ) && ( errno == EINTR ) ) {
/* The user should process events as usual. */