summaryrefslogtreecommitdiff
path: root/lib/util
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util')
-rw-r--r--lib/util/select.c26
-rw-r--r--lib/util/select.h1
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/util/select.c b/lib/util/select.c
index b40538c473..5f1c91cff6 100644
--- a/lib/util/select.c
+++ b/lib/util/select.c
@@ -286,3 +286,29 @@ int sys_poll(struct pollfd *fds, int num_fds, int timeout)
return ret;
}
+
+int sys_poll_intr(struct pollfd *fds, int num_fds, int timeout)
+{
+ int orig_timeout = timeout;
+ struct timespec start;
+ int ret;
+
+ clock_gettime_mono(&start);
+
+ while (true) {
+ struct timespec now;
+ int64_t elapsed;
+
+ ret = poll(fds, num_fds, timeout);
+ if (ret != -1) {
+ break;
+ }
+ if (errno != EINTR) {
+ break;
+ }
+ clock_gettime_mono(&now);
+ elapsed = nsec_time_diff(&now, &start);
+ timeout = (orig_timeout - elapsed) / 1000000;
+ };
+ return ret;
+}
diff --git a/lib/util/select.h b/lib/util/select.h
index 795c8fa454..3c762de2ad 100644
--- a/lib/util/select.h
+++ b/lib/util/select.h
@@ -28,5 +28,6 @@ void sys_select_signal(char c);
int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
int sys_poll(struct pollfd *fds, int num_fds, int timeout);
+int sys_poll_intr(struct pollfd *fds, int num_fds, int timeout);
#endif