mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 00:26:16 +03:00
Intercept epoll_wait(), epoll_pwait(), and pselect() (#115)
This commit is contained in:
3
NEWS
3
NEWS
@@ -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
|
||||
|
||||
@@ -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__
|
||||
@@ -1289,6 +1303,60 @@ int ppoll(struct pollfd *fds, nfds_t nfds,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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()
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user