diff options
Diffstat (limited to 'test/epoll-wrap.c')
-rw-r--r-- | test/epoll-wrap.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/test/epoll-wrap.c b/test/epoll-wrap.c new file mode 100644 index 0000000..a527e20 --- /dev/null +++ b/test/epoll-wrap.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012-2013, Eric Wong <normalperson@yhbt.net> + * License: GPLv3 or later (see COPYING for details) + */ +/* + * fault injection wrapper for epoll + */ +#include "cmogstored.h" +#if defined(HAVE_EPOLL_WAIT) && ! MOG_LIBKQUEUE +static sig_atomic_t epoll_ctl_fail; +#define EMIT(s) write(STDERR_FILENO, (s), sizeof(s)-1) + +/* test/epoll_enospc depends on the following line */ +static const char msg[] = "epoll_ctl failure injection\n"; + +int __real_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +int __real_epoll_create(int flags); + +int __wrap_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + if (epoll_ctl_fail) { + EMIT(msg); + errno = epoll_ctl_fail; + return -1; + } + + return __real_epoll_ctl(epfd, op, fd, event); +} + +static void set_wrap_epoll_ctl(int signum) +{ + if (signum == SIGTTIN) { + epoll_ctl_fail = ENOSPC; + EMIT("epoll_ctl ENOSPC on\n"); + } else { + epoll_ctl_fail = 0; + EMIT("epoll_ctl ENOSPC off\n"); + } +} + +int __wrap_epoll_create(int flags) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(struct sigaction)); + CHECK(int, 0, sigemptyset(&sa.sa_mask) ); + sa.sa_handler = set_wrap_epoll_ctl; + CHECK(int, 0, sigaction(SIGTTIN, &sa, NULL)); + CHECK(int, 0, sigaction(SIGTTOU, &sa, NULL)); + + return __real_epoll_create(flags); +} +#endif /* defined(HAVE_EPOLL_WAIT) && ! MOG_LIBKQUEUE */ |