[mosh-devel] [PATCH 1/2] workaround for systems not providing pselect
Jérémie Courrèges-Anglas
jca at wxcvbn.org
Tue Mar 12 06:46:42 EDT 2013
using a mix of good old select and sigprocmask
---
configure.ac | 2 +-
src/util/select.h | 21 +++++++++++++++++++--
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 8220621..a3d3419 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. */
--
1.8.1.2
More information about the mosh-devel
mailing list