about summary refs log tree commit homepage
path: root/test/epoll-wrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/epoll-wrap.c')
-rw-r--r--test/epoll-wrap.c53
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 */