diff options
author | Jérémie Courrèges-Anglas <jca@wxcvbn.org> | 2013-04-16 11:09:42 +0200 |
---|---|---|
committer | Jérémie Courrèges-Anglas <jca@wxcvbn.org> | 2013-04-16 11:09:42 +0200 |
commit | 24b078a5a126fc7c7c207747d5f2e20022264e9f (patch) | |
tree | 0882bc0f54c9e2fd49666def43ebaa5b93a90413 | |
parent | fbd2d184fb37a10ec7199ba72e83d4274a605387 (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.ac | 2 | ||||
-rw-r--r-- | src/util/select.h | 21 |
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. */ |