diff options
author | Wolfgang Hommel <wolfgang.hommel@unibw.de> | 2019-08-22 23:29:48 +0200 |
---|---|---|
committer | Wolfgang Hommel <wolfgang.hommel@unibw.de> | 2019-08-22 23:29:48 +0200 |
commit | 5f033fe4867a9cf0c1a525c43f80e2ec30497490 (patch) | |
tree | 0fbbc96e0347b34f97b99b1007779cb6966ba8bf | |
parent | 52108dba7a79559712d3b2272fdf258c0baaa6dd (diff) | |
download | libfaketime-5f033fe4867a9cf0c1a525c43f80e2ec30497490.tar.gz |
Intercept epoll_wait(), epoll_pwait(), and pselect() (#115)
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/libfaketime.c | 116 |
2 files changed, 119 insertions, 0 deletions
@@ -9,6 +9,8 @@ Since 0.9.7: - Added FAKETIME_DONT_RESET environment variable to avoid faketime resets when subprocesses are started (similar to the old v0.9.6 behavior) + - Added FAKETIME_XRESET to avoid large clock jumps when + the 'x' modifier is used and changed during run-time - Do not fake time during libfaketime initialization to improve compatibility with memory allocation libraries that use time-related functions themselves @@ -16,6 +18,7 @@ Since 0.9.7: not using the faketime wrapper - Updated glibc compatibility settings for various platforms - Support for clock_nanosleep() with realtime and monotonic clocks + - Support for epoll_wait(), epoll_pwait(), and pselect() Since 0.9.6: - Julien Gilli added an option to disable monotonic time faking diff --git a/src/libfaketime.c b/src/libfaketime.c index 714dcb0..f775810 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -30,6 +30,9 @@ #include <unistd.h> #include <fcntl.h> #include <poll.h> +#ifdef __linux__ +#include <sys/epoll.h> +#endif #include <time.h> #include <math.h> #include <errno.h> @@ -174,10 +177,21 @@ static unsigned int (*real_sleep) (unsigned int seconds); static unsigned int (*real_alarm) (unsigned int seconds); static int (*real_poll) (struct pollfd *, nfds_t, int); static int (*real_ppoll) (struct pollfd *, nfds_t, const struct timespec *, const sigset_t *); +#ifdef __linux__ +static int (*real_epoll_wait) (int epfd, struct epoll_event *events, int maxevents, int timeout); +static int (*real_epoll_pwait) (int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask); +#endif static int (*real_select) (int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout); +#ifdef __linux__ +static int (*real_pselect) (int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, + fd_set *restrict errorfds, + const struct timespec *timeout, + const sigset_t *sigmask); +#endif static int (*real_sem_timedwait) (sem_t*, const struct timespec*); #endif #ifdef __APPLEOSX__ @@ -1290,6 +1304,60 @@ int ppoll(struct pollfd *fds, nfds_t nfds, } /* + * Faked epoll_wait() + */ +int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) +{ + int ret, real_timeout; + + if (!initialized) + { + ftpl_init(); + } + if (real_epoll_wait == NULL) + { + return -1; + } + if (user_rate_set && !dont_fake && timeout > 0) + { + real_timeout = (int) timeout * 1.0/user_rate; + } + else + { + real_timeout = timeout; + } + DONT_FAKE_TIME(ret = (*real_epoll_wait)(epfd, events, maxevents, real_timeout)); + return ret; +} + +/* + * Faked epoll_pwait() + */ +int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask) +{ + int ret, real_timeout; + + if (!initialized) + { + ftpl_init(); + } + if (real_epoll_pwait == NULL) + { + return -1; + } + if (user_rate_set && !dont_fake && timeout > 0) + { + real_timeout = (int) timeout * 1.0/user_rate; + } + else + { + real_timeout = timeout; + } + DONT_FAKE_TIME(ret = (*real_epoll_pwait)(epfd, events, maxevents, real_timeout, sigmask)); + return ret; +} + +/* * Faked poll() */ int poll(struct pollfd *fds, nfds_t nfds, int timeout) @@ -1355,6 +1423,47 @@ int select(int nfds, fd_set *readfds, return ret; } +#ifdef __linux__ +/* + * Faked pselect() + */ +int pselect(int nfds, fd_set *readfds, + fd_set *writefds, + fd_set *errorfds, + const struct timespec *timeout, + const sigset_t *sigmask) +{ + int ret; + struct timespec timeout_real; + + if (!initialized) + { + ftpl_init(); + } + + if (real_pselect == NULL) + { + return -1; + } + + if (timeout != NULL) + { + if (user_rate_set && !dont_fake && (timeout->tv_sec > 0 || timeout->tv_nsec > 0)) + { + timespecmul(timeout, 1.0 / user_rate, &timeout_real); + } + else + { + timeout_real.tv_sec = timeout->tv_sec; + timeout_real.tv_nsec = timeout->tv_nsec; + } + } + + DONT_FAKE_TIME(ret = (*real_pselect)(nfds, readfds, writefds, errorfds, timeout == NULL ? timeout : &timeout_real, sigmask)); + return ret; +} +#endif + int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) { int result; @@ -2038,7 +2147,14 @@ static void ftpl_init(void) real_alarm = dlsym(RTLD_NEXT, "alarm"); real_poll = dlsym(RTLD_NEXT, "poll"); real_ppoll = dlsym(RTLD_NEXT, "ppoll"); +#ifdef linux + real_epoll_wait = dlsym(RTLD_NEXT, "epoll_wait"); + real_epoll_pwait = dlsym(RTLD_NEXT, "epoll_pwait"); +#endif real_select = dlsym(RTLD_NEXT, "select"); +#ifdef __linux__ + real_pselect = dlsym(RTLD_NEXT, "pselect"); +#endif real_sem_timedwait = dlsym(RTLD_NEXT, "sem_timedwait"); #endif #ifdef FAKE_INTERNAL_CALLS |