* [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase
@ 2015-12-30 10:44 Guangwen Feng
2015-12-30 10:44 ` [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Guangwen Feng @ 2015-12-30 10:44 UTC (permalink / raw)
To: ltp
Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
on a epoll instance and that struct epoll_event is set correctly.
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 2 +
runtest/stress.part3 | 2 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/epoll_wait/Makefile | 23 ++
.../kernel/syscalls/epoll_wait/epoll_wait01.c | 263 +++++++++++++++++++++
6 files changed, 292 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/Makefile
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 1aa93e6..59be3ba 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -160,6 +160,8 @@ dup203 dup203
dup204 dup204
dup205 dup205
+epoll_wait01 epoll_wait01
+
execl01 execl01
execle01 execle01
execlp01 execlp01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 87f42ea..3ed10ca 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -101,6 +101,8 @@ dup203 dup203
dup204 dup204
dup205 dup205
+epoll_wait01 epoll_wait01
+
execl01 execl01
execle01 execle01
execlp01 execlp01
diff --git a/runtest/syscalls b/runtest/syscalls
index 7173f22..5dbd00f 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -123,6 +123,7 @@ dup3_02 dup3_02
epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
+epoll_wait01 epoll_wait01
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index d5f21ef..7b83307 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -98,6 +98,7 @@
/dup3/dup3_02
/epoll/epoll-ltp
/epoll_create1/epoll_create1_01
+/epoll_wait/epoll_wait01
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/Makefile b/testcases/kernel/syscalls/epoll_wait/Makefile
new file mode 100644
index 0000000..fa233c8
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2015 Fujitsu Ltd.
+# Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
new file mode 100644
index 0000000..46058a2
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * Basic test for epoll_wait(2).
+ * Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
+ * on a epoll instance and that struct epoll_event is set correctly.
+ */
+
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+#include "lapi/fcntl.h"
+
+char *TCID = "epoll_wait01";
+int TST_TOTAL = 3;
+
+static int write_size, epfd, fds[2];
+static struct epoll_event epevs[2];
+
+static void setup(void);
+static int get_writesize(void);
+static void verify_epollout(void);
+static void verify_epollin(void);
+static void verify_epollio(void);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_epollout();
+ verify_epollin();
+ verify_epollio();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ int pipe_capacity;
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ SAFE_PIPE(NULL, fds);
+
+ /* fcntl()'s F_GETPIPE_SZ flag availbility check */
+ if ((tst_kvercmp(2, 6, 35)) < 0) {
+ write_size = get_writesize();
+ } else {
+ pipe_capacity = fcntl(fds[1], F_GETPIPE_SZ);
+ if (pipe_capacity == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to get the pipe capacity");
+ }
+
+ write_size = pipe_capacity - getpagesize() + 1;
+ }
+
+ epfd = epoll_create(2);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].events = EPOLLIN;
+ epevs[0].data.fd = fds[0];
+ epevs[1].events = EPOLLOUT;
+ epevs[1].data.fd = fds[1];
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
+ epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+/*
+ * fcntl(fd, F_GETPIPE_SZ) not supported on kernels which
+ * version lower than 2.6.35, so use this function instead
+ */
+static int get_writesize(void)
+{
+ int nfd, write_size;
+
+ struct pollfd pfd[] = {
+ {.fd = fds[0], .events = POLLIN},
+ {.fd = fds[1], .events = POLLOUT},
+ };
+
+ write_size = 0;
+ do {
+ SAFE_WRITE(cleanup, 1, fds[1], "a", 1);
+ write_size++;
+ nfd = poll(pfd, 2, -1);
+ if (nfd == -1)
+ tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
+ } while (nfd == 2);
+
+ char buf[write_size];
+
+ SAFE_READ(cleanup, 1, fds[0], buf, write_size);
+
+ return write_size;
+}
+
+static void verify_epollout(void)
+{
+ TEST(epoll_wait(epfd, epevs, 2, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
+ return;
+ }
+
+ if (TEST_RETURN != 1) {
+ tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
+ return;
+ }
+
+ if (epevs[0].data.fd != fds[1]) {
+ tst_resm(TFAIL, "epoll_wait() failed to set write fd");
+ return;
+ }
+
+ if (epevs[0].events != EPOLLOUT) {
+ tst_resm(TFAIL, "epoll_wait() failed to set EPOLLOUT");
+ return;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollout");
+}
+
+static void verify_epollin(void)
+{
+ char write_buf[write_size];
+ char read_buf[sizeof(write_buf)];
+
+ memset(write_buf, 'a', sizeof(write_buf));
+
+ SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+ TEST(epoll_wait(epfd, epevs, 2, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
+ goto end;
+ }
+
+ if (TEST_RETURN != 1) {
+ tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
+ goto end;
+ }
+
+ if (epevs[0].data.fd != fds[0]) {
+ tst_resm(TFAIL, "epoll_wait() failed to set read fd");
+ goto end;
+ }
+
+ if (epevs[0].events != EPOLLIN) {
+ tst_resm(TFAIL, "epoll_wait() failed to set EPOLLIN");
+ goto end;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollin");
+
+end:
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static void verify_epollio(void)
+{
+ int i, checked0, checked1;
+ char write_buf[] = "Testing";
+ char read_buf[sizeof(write_buf)];
+
+ SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+ TEST(epoll_wait(epfd, epevs, 2, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
+ goto end;
+ }
+
+ if (TEST_RETURN != 2) {
+ tst_resm(TFAIL, "epoll_wait() failed to get two fds ready");
+ goto end;
+ }
+
+ checked0 = 0;
+ checked1 = 0;
+ for (i = 0; i < TEST_RETURN; i++) {
+ if (checked0 == 0 && epevs[i].data.fd == fds[0]) {
+ if (epevs[i].events != EPOLLIN) {
+ tst_resm(TFAIL, "epoll_wait()"
+ "failed to set EPOLLIN");
+ goto end;
+ }
+ checked0 = 1;
+ } else if (checked1 == 0 && epevs[i].data.fd == fds[1]) {
+ if (epevs[i].events != EPOLLOUT) {
+ tst_resm(TFAIL, "epoll_wait()"
+ "failed to set EPOLLOUT");
+ goto end;
+ }
+ checked1 = 1;
+ } else {
+ tst_resm(TFAIL, "epoll_wait()"
+ "failed to set write or read fd");
+ goto end;
+ }
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollio");
+
+end:
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "failed to close fds[0]");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "failed to close fds[1]");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: add new testcase
2015-12-30 10:44 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase Guangwen Feng
@ 2015-12-30 10:44 ` Guangwen Feng
2016-01-28 16:35 ` Cyril Hrubis
2015-12-30 10:44 ` [LTP] [PATCH 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
` (2 subsequent siblings)
3 siblings, 1 reply; 15+ messages in thread
From: Guangwen Feng @ 2015-12-30 10:44 UTC (permalink / raw)
To: ltp
Check that epoll_wait(2) timeouts correctly.
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/epoll_wait/Makefile | 2 +
.../kernel/syscalls/epoll_wait/epoll_wait02.c | 144 +++++++++++++++++++++
6 files changed, 150 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 59be3ba..08bca9a 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -161,6 +161,7 @@ dup204 dup204
dup205 dup205
epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
execl01 execl01
execle01 execle01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 3ed10ca..fb6bc0e 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -102,6 +102,7 @@ dup204 dup204
dup205 dup205
epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
execl01 execl01
execle01 execle01
diff --git a/runtest/syscalls b/runtest/syscalls
index 5dbd00f..6c79584 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -124,6 +124,7 @@ dup3_02 dup3_02
epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 7b83307..46258ba 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -99,6 +99,7 @@
/epoll/epoll-ltp
/epoll_create1/epoll_create1_01
/epoll_wait/epoll_wait01
+/epoll_wait/epoll_wait02
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/Makefile b/testcases/kernel/syscalls/epoll_wait/Makefile
index fa233c8..94ca683 100644
--- a/testcases/kernel/syscalls/epoll_wait/Makefile
+++ b/testcases/kernel/syscalls/epoll_wait/Makefile
@@ -18,6 +18,8 @@
top_srcdir ?= ../../../..
+epoll_wait02: LDLIBS+=-lrt
+
include $(top_srcdir)/include/mk/testcases.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
new file mode 100644
index 0000000..3312902
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * Check that epoll_wait(2) timeouts correctly.
+ */
+
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "epoll_wait02";
+int TST_TOTAL = 1;
+
+static int epfd, fds[2];
+static char *opt_sleep_ms;
+static struct epoll_event epevs[1];
+
+static option_t opts[] = {
+ {"s:", NULL, &opt_sleep_ms},
+ {NULL, NULL, NULL},
+};
+
+static void setup(void);
+static void cleanup(void);
+static void help(void);
+
+int main(int ac, char **av)
+{
+ int lc, threshold;
+ long long elapsed_ms, sleep_ms = 100;
+
+ tst_parse_opts(ac, av, opts, help);
+
+ if (opt_sleep_ms) {
+ sleep_ms = atoll(opt_sleep_ms);
+
+ if (sleep_ms == 0) {
+ tst_brkm(TBROK, NULL,
+ "Invalid timeout '%s'", opt_sleep_ms);
+ }
+ }
+
+ threshold = sleep_ms / 100 + 10;
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ tst_timer_start(CLOCK_MONOTONIC);
+ TEST(epoll_wait(epfd, epevs, 1, sleep_ms));
+ tst_timer_stop();
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() failed");
+ continue;
+ }
+
+ if (TEST_RETURN != 0) {
+ tst_resm(TFAIL, "epoll_wait() unexpectedly get %li, "
+ "expected 0", TEST_RETURN);
+ continue;
+ }
+
+ elapsed_ms = tst_timer_elapsed_ms();
+
+ if (elapsed_ms < sleep_ms) {
+ tst_resm(TFAIL, "epoll_wait() woken up too early %llims, "
+ "expected %llims", elapsed_ms, sleep_ms);
+ continue;
+ }
+
+ if (elapsed_ms - sleep_ms > threshold) {
+ tst_resm(TFAIL, "epoll_wait() slept too long %llims, "
+ "expected %llims, threshold %i",
+ elapsed_ms, sleep_ms, threshold);
+ continue;
+ }
+
+ tst_resm(TPASS, "epoll_wait() slept %llims, expected %llims, "
+ "threshold %i", elapsed_ms, sleep_ms, threshold);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_timer_check(CLOCK_MONOTONIC);
+
+ SAFE_PIPE(NULL, fds);
+
+ epfd = epoll_create(1);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].events = EPOLLIN;
+ epevs[0].data.fd = fds[0];
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
+
+static void help(void)
+{
+ printf(" -s epoll_wait() timeout length in ms\n");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH 3/3] epoll_wait/epoll_wait03.c: add new testcase
2015-12-30 10:44 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase Guangwen Feng
2015-12-30 10:44 ` [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
@ 2015-12-30 10:44 ` Guangwen Feng
2016-01-28 17:16 ` Cyril Hrubis
2016-01-06 1:19 ` [LTP] [PATCH 4/4] epoll_wait/epoll_wait04.c: " Guangwen Feng
2016-01-28 16:19 ` [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
3 siblings, 1 reply; 15+ messages in thread
From: Guangwen Feng @ 2015-12-30 10:44 UTC (permalink / raw)
To: ltp
Verify that:
1) epoll_wait(2) fails if epfd is not a valid file descriptor
2) epoll_wait(2) fails if epfd is not an epoll file descriptor
3) epoll_wait(2) fails if maxevents is less than zero
4) epoll_wait(2) fails if maxevents is equal to zero
Expected result:
1) epoll_wait(2) should return -1 and set errno to EBADF
2) epoll_wait(2) should return -1 and set errno to EINVAL
3) epoll_wait(2) should return -1 and set errno to EINVAL
4) epoll_wait(2) should return -1 and set errno to EINVAL
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait03.c | 146 +++++++++++++++++++++
5 files changed, 150 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 08bca9a..4686c08 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -162,6 +162,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
execl01 execl01
execle01 execle01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index fb6bc0e..e198fb4 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -103,6 +103,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
execl01 execl01
execle01 execle01
diff --git a/runtest/syscalls b/runtest/syscalls
index 6c79584..88c748c 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -125,6 +125,7 @@ epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 46258ba..f63077a 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -100,6 +100,7 @@
/epoll_create1/epoll_create1_01
/epoll_wait/epoll_wait01
/epoll_wait/epoll_wait02
+/epoll_wait/epoll_wait03
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
new file mode 100644
index 0000000..34009c5
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * 1) epoll_wait(2) fails if epfd is not a valid file descriptor
+ * 2) epoll_wait(2) fails if epfd is not an epoll file descriptor
+ * 3) epoll_wait(2) fails if maxevents is less than zero
+ * 4) epoll_wait(2) fails if maxevents is equal to zero
+ *
+ * Expected Result:
+ * 1) epoll_wait(2) should return -1 and set errno to EBADF
+ * 2) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 3) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 4) epoll_wait(2) should return -1 and set errno to EINVAL
+ */
+
+#include <sys/epoll.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+static int epfd, fds[2];
+static struct epoll_event epevs[1];
+
+static struct test_case_t {
+ int epfd;
+ int maxevents;
+ int exp_errno;
+} test_cases[] = {
+ /* test1 */
+ {-1, 1, EBADF},
+ /* test2 */
+ {0, 1, EINVAL},
+ /*
+ * test3
+ * temporarily set epfd to 0
+ * will be set to an epoll instance later
+ */
+ {0, -1, EINVAL},
+ /*
+ * test4
+ * temporarily set epfd to 0
+ * will be set to an epoll instance later
+ */
+ {0, 0, EINVAL},
+};
+
+char *TCID = "epoll_wait03";
+int TST_TOTAL = ARRAY_SIZE(test_cases);
+
+static void setup(void);
+static void verify_epoll_wait(struct test_case_t *test_cases);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc, tc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ for (tc = 0; tc < TST_TOTAL; tc++)
+ verify_epoll_wait(&test_cases[tc]);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ SAFE_PIPE(NULL, fds);
+
+ epfd = epoll_create(1);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ test_cases[2].epfd = epfd;
+ test_cases[3].epfd = epfd;
+
+ epevs[0].events = EPOLLOUT;
+ epevs[0].data.fd = fds[1];
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static void verify_epoll_wait(struct test_case_t *test_cases)
+{
+ TEST(epoll_wait(test_cases->epfd, epevs, test_cases->maxevents, -1));
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "epoll_wait() succeed unexpectedly");
+ } else {
+ if (TEST_ERRNO == test_cases->exp_errno) {
+ tst_resm(TPASS | TTERRNO,
+ "epoll_wait() fails as expected");
+ } else {
+ tst_resm(TFAIL | TTERRNO,
+ "epoll_wait() fails unexpectedly, "
+ "expected %d: %s", test_cases->exp_errno,
+ strerror(test_cases->exp_errno));
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH 4/4] epoll_wait/epoll_wait04.c: add new testcase
2015-12-30 10:44 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase Guangwen Feng
2015-12-30 10:44 ` [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
2015-12-30 10:44 ` [LTP] [PATCH 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
@ 2016-01-06 1:19 ` Guangwen Feng
2016-01-28 17:24 ` Cyril Hrubis
2016-01-28 16:19 ` [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
3 siblings, 1 reply; 15+ messages in thread
From: Guangwen Feng @ 2016-01-06 1:19 UTC (permalink / raw)
To: ltp
Verify that:
epoll_wait(2) fails if the memory area pointed to by events is not
accessible with write permissions.
Expected result:
epoll_wait(2) should return -1 and set errno to EFAULT
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait04.c | 119 +++++++++++++++++++++
5 files changed, 123 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 4686c08..d30e596 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -163,6 +163,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
epoll_wait03 epoll_wait03
+epoll_wait04 epoll_wait04
execl01 execl01
execle01 execle01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index e198fb4..9d8b87a 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -104,6 +104,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
epoll_wait03 epoll_wait03
+epoll_wait04 epoll_wait04
execl01 execl01
execle01 execle01
diff --git a/runtest/syscalls b/runtest/syscalls
index 88c748c..df1a267 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -126,6 +126,7 @@ epoll01 epoll-ltp
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
epoll_wait03 epoll_wait03
+epoll_wait04 epoll_wait04
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index f63077a..23bd9ac 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -101,6 +101,7 @@
/epoll_wait/epoll_wait01
/epoll_wait/epoll_wait02
/epoll_wait/epoll_wait03
+/epoll_wait/epoll_wait04
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
new file mode 100644
index 0000000..36110f3
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * epoll_wait(2) fails if the memory area pointed to by events is not
+ * accessible with write permissions.
+ *
+ * Expected Result:
+ * epoll_wait(2) should return -1 and set errno to EFAULT
+ */
+
+#include <sys/epoll.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "epoll_wait04";
+int TST_TOTAL = 1;
+
+static int page_size, epfd, fds[2];
+static struct epoll_event *epevs;
+
+static void setup(void);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ TEST(epoll_wait(epfd, epevs, 1, -1));
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "epoll_wait() succeed unexpectedly");
+ } else {
+ if (TEST_ERRNO == EFAULT) {
+ tst_resm(TPASS | TTERRNO,
+ "epoll_wait() fails as expected");
+ } else {
+ tst_resm(TFAIL | TTERRNO,
+ "epoll_wait() fails unexpectedly, "
+ "expected errno is EFAULT");
+ }
+ }
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ page_size = getpagesize();
+
+ epevs = SAFE_MMAP(NULL, NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ SAFE_PIPE(NULL, fds);
+
+ epfd = epoll_create(1);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs->events = EPOLLOUT;
+ epevs->data.fd = fds[1];
+
+ if (mprotect(epevs, page_size, PROT_READ)) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to set memory area read-only");
+ }
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], epevs)) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase
2015-12-30 10:44 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase Guangwen Feng
` (2 preceding siblings ...)
2016-01-06 1:19 ` [LTP] [PATCH 4/4] epoll_wait/epoll_wait04.c: " Guangwen Feng
@ 2016-01-28 16:19 ` Cyril Hrubis
2016-02-01 5:28 ` Guangwen Feng
3 siblings, 1 reply; 15+ messages in thread
From: Cyril Hrubis @ 2016-01-28 16:19 UTC (permalink / raw)
To: ltp
Hi!
> diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
> new file mode 100644
> index 0000000..46058a2
> --- /dev/null
> +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
> @@ -0,0 +1,263 @@
> +/*
> + * Copyright (c) 2015 Fujitsu Ltd.
> + * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
> + * the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.
> + */
> +
> +/*
> + * Description:
> + * Basic test for epoll_wait(2).
> + * Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
> + * on a epoll instance and that struct epoll_event is set correctly.
> + */
> +
> +#include <sys/epoll.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <poll.h>
> +#include <errno.h>
> +
> +#include "test.h"
> +#include "safe_macros.h"
> +#include "lapi/fcntl.h"
> +
> +char *TCID = "epoll_wait01";
> +int TST_TOTAL = 3;
> +
> +static int write_size, epfd, fds[2];
> +static struct epoll_event epevs[2];
> +
> +static void setup(void);
> +static int get_writesize(void);
> +static void verify_epollout(void);
> +static void verify_epollin(void);
> +static void verify_epollio(void);
> +static void cleanup(void);
> +
> +int main(int ac, char **av)
> +{
> + int lc;
> +
> + tst_parse_opts(ac, av, NULL, NULL);
> +
> + setup();
> +
> + for (lc = 0; TEST_LOOPING(lc); lc++) {
> + tst_count = 0;
> +
> + verify_epollout();
> + verify_epollin();
> + verify_epollio();
> + }
> +
> + cleanup();
> + tst_exit();
> +}
> +
> +static void setup(void)
> +{
> + int pipe_capacity;
> +
> + tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +
> + TEST_PAUSE;
> +
> + SAFE_PIPE(NULL, fds);
> +
> + /* fcntl()'s F_GETPIPE_SZ flag availbility check */
> + if ((tst_kvercmp(2, 6, 35)) < 0) {
> + write_size = get_writesize();
> + } else {
> + pipe_capacity = fcntl(fds[1], F_GETPIPE_SZ);
> + if (pipe_capacity == -1) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to get the pipe capacity");
> + }
> +
> + write_size = pipe_capacity - getpagesize() + 1;
> + }
I would rather go with runtime detection even for newer kernels. Since
otherwise we have two different codepaths to test.
> + epfd = epoll_create(2);
> + if (epfd == -1) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to create epoll instance");
> + }
> +
> + epevs[0].events = EPOLLIN;
> + epevs[0].data.fd = fds[0];
> + epevs[1].events = EPOLLOUT;
> + epevs[1].data.fd = fds[1];
> +
> + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
> + epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1])) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to register epoll target");
> + }
> +}
> +
> +/*
> + * fcntl(fd, F_GETPIPE_SZ) not supported on kernels which
> + * version lower than 2.6.35, so use this function instead
> + */
> +static int get_writesize(void)
> +{
> + int nfd, write_size;
> +
> + struct pollfd pfd[] = {
> + {.fd = fds[0], .events = POLLIN},
> + {.fd = fds[1], .events = POLLOUT},
> + };
> +
> + write_size = 0;
> + do {
> + SAFE_WRITE(cleanup, 1, fds[1], "a", 1);
> + write_size++;
> + nfd = poll(pfd, 2, -1);
> + if (nfd == -1)
> + tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
> + } while (nfd == 2);
Why don't we write larger chunks and add the return from SAFE_WRITE to
the write_size? That should work if we pass 0 as len strict, the last
write should just end up truncated.
> + char buf[write_size];
> +
> + SAFE_READ(cleanup, 1, fds[0], buf, write_size);
> +
> + return write_size;
> +}
> +
> +static void verify_epollout(void)
> +{
> + TEST(epoll_wait(epfd, epevs, 2, -1));
> +
> + if (TEST_RETURN == -1) {
> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
> + return;
> + }
> +
> + if (TEST_RETURN != 1) {
> + tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
^
We should add the TEST_RETURN
value to the output here
I would go for:
tst_resm(TFAIL, "epoll_wait() returned %i expected 1",
TEST_RETURN);
> + return;
> + }
> +
> + if (epevs[0].data.fd != fds[1]) {
> + tst_resm(TFAIL, "epoll_wait() failed to set write fd");
And maybe write the actuall fds here:
tst_resm(TFAIL, "epoll.data.fd %i expected %i", ...);
> + return;
> + }
> +
> + if (epevs[0].events != EPOLLOUT) {
> + tst_resm(TFAIL, "epoll_wait() failed to set EPOLLOUT");
And perhaps print the value of events as hexadecimal here.
> + return;
> + }
> +
> + tst_resm(TPASS, "epoll_wait() epollout");
> +}
> +
> +static void verify_epollin(void)
> +{
> + char write_buf[write_size];
> + char read_buf[sizeof(write_buf)];
> +
> + memset(write_buf, 'a', sizeof(write_buf));
> +
> + SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
> +
> + TEST(epoll_wait(epfd, epevs, 2, -1));
> +
> + if (TEST_RETURN == -1) {
> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
> + goto end;
> + }
> +
> + if (TEST_RETURN != 1) {
> + tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
> + goto end;
> + }
> +
> + if (epevs[0].data.fd != fds[0]) {
> + tst_resm(TFAIL, "epoll_wait() failed to set read fd");
> + goto end;
> + }
> +
> + if (epevs[0].events != EPOLLIN) {
> + tst_resm(TFAIL, "epoll_wait() failed to set EPOLLIN");
> + goto end;
> + }
And I would be more verbose about the values in these messages as well.
> + tst_resm(TPASS, "epoll_wait() epollin");
> +
> +end:
> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
> +}
> +
> +static void verify_epollio(void)
> +{
> + int i, checked0, checked1;
> + char write_buf[] = "Testing";
> + char read_buf[sizeof(write_buf)];
> +
> + SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
> +
> + TEST(epoll_wait(epfd, epevs, 2, -1));
^
Shouldn't we pass at least 3 here (and
declare epevs to have three elements as
well). Since if there were three events
queued the epoll_wait() would return just
2 and the test will pass.
> +
> + if (TEST_RETURN == -1) {
> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
> + goto end;
> + }
> +
> + if (TEST_RETURN != 2) {
> + tst_resm(TFAIL, "epoll_wait() failed to get two fds ready");
> + goto end;
> + }
> +
> + checked0 = 0;
> + checked1 = 0;
> + for (i = 0; i < TEST_RETURN; i++) {
> + if (checked0 == 0 && epevs[i].data.fd == fds[0]) {
> + if (epevs[i].events != EPOLLIN) {
> + tst_resm(TFAIL, "epoll_wait()"
> + "failed to set EPOLLIN");
> + goto end;
> + }
> + checked0 = 1;
> + } else if (checked1 == 0 && epevs[i].data.fd == fds[1]) {
> + if (epevs[i].events != EPOLLOUT) {
> + tst_resm(TFAIL, "epoll_wait()"
> + "failed to set EPOLLOUT");
> + goto end;
> + }
> + checked1 = 1;
> + } else {
> + tst_resm(TFAIL, "epoll_wait()"
> + "failed to set write or read fd");
> + goto end;
> + }
> + }
Hmm, this is kind of messy. I would implement this as function that
checks if the array has event with specific values and would have called
it twice once with read fd and once with write fd.
static int has_event(struct epoll_event *events, int events_len,
int fd, uint32_t events)
{
...
}
...
if (!has_event(epevs, 2, fds[0], EPOLLIN))
tst_resm(TFAIL, ...);
if (!has_event(epevs, 2, fds[1], EPOLLOUT))
tst_resm(TFAIL, ...);
...
And perhaps we can add a function to dump the epevs array with
tst_resm(TINFO, "") and call it on the array whenever we find that
something went wrong before we do tst_resm(TFAIL, ...);
> + tst_resm(TPASS, "epoll_wait() epollio");
> +
> +end:
> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
> +}
> +
> +static void cleanup(void)
> +{
> + if (epfd > 0 && close(epfd))
> + tst_resm(TWARN | TERRNO, "failed to close epfd");
> +
> + if (close(fds[0]))
> + tst_resm(TWARN | TERRNO, "failed to close fds[0]");
> +
> + if (close(fds[1]))
> + tst_resm(TWARN | TERRNO, "failed to close fds[1]");
> +}
The rest looks good.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: add new testcase
2015-12-30 10:44 ` [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
@ 2016-01-28 16:35 ` Cyril Hrubis
0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2016-01-28 16:35 UTC (permalink / raw)
To: ltp
Hi!
> +
> + if (TEST_RETURN != 0) {
> + tst_resm(TFAIL, "epoll_wait() unexpectedly get %li, "
^
Should rather be:
"returned %li, expected 0"
The sentence does not make sense as it is.
> + "expected 0", TEST_RETURN);
> + continue;
> + }
> +
> + elapsed_ms = tst_timer_elapsed_ms();
> +
> + if (elapsed_ms < sleep_ms) {
> + tst_resm(TFAIL, "epoll_wait() woken up too early %llims, "
> + "expected %llims", elapsed_ms, sleep_ms);
> + continue;
> + }
> +
> + if (elapsed_ms - sleep_ms > threshold) {
> + tst_resm(TFAIL, "epoll_wait() slept too long %llims, "
> + "expected %llims, threshold %i",
> + elapsed_ms, sleep_ms, threshold);
> + continue;
> + }
> +
> + tst_resm(TPASS, "epoll_wait() slept %llims, expected %llims, "
> + "threshold %i", elapsed_ms, sleep_ms, threshold);
> + }
> +
> + cleanup();
> + tst_exit();
> +}
> +
> +static void setup(void)
> +{
> + tst_timer_check(CLOCK_MONOTONIC);
> +
> + SAFE_PIPE(NULL, fds);
> +
> + epfd = epoll_create(1);
> + if (epfd == -1) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to create epoll instance");
> + }
> +
> + epevs[0].events = EPOLLIN;
> + epevs[0].data.fd = fds[0];
> +
> + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0])) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to register epoll target");
> + }
> +}
> +
> +static void cleanup(void)
> +{
> + if (epfd > 0 && close(epfd))
> + tst_resm(TWARN | TERRNO, "failed to close epfd");
> +
> + if (close(fds[0]))
> + tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
> +
> + if (close(fds[1]))
> + tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
> +}
> +
> +static void help(void)
> +{
> + printf(" -s epoll_wait() timeout length in ms\n");
> +}
The rest looks good.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH 3/3] epoll_wait/epoll_wait03.c: add new testcase
2015-12-30 10:44 ` [LTP] [PATCH 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
@ 2016-01-28 17:16 ` Cyril Hrubis
0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2016-01-28 17:16 UTC (permalink / raw)
To: ltp
Hi!
> +#include <sys/epoll.h>
> +#include <string.h>
> +#include <errno.h>
> +
> +#include "test.h"
> +#include "safe_macros.h"
> +
> +static int epfd, fds[2];
> +static struct epoll_event epevs[1];
> +
> +static struct test_case_t {
> + int epfd;
> + int maxevents;
> + int exp_errno;
> +} test_cases[] = {
> + /* test1 */
> + {-1, 1, EBADF},
> + /* test2 */
> + {0, 1, EINVAL},
> + /*
> + * test3
> + * temporarily set epfd to 0
> + * will be set to an epoll instance later
> + */
Instead of this comment the epfd should rather be pointer to an integer
that is initialized in setup(). Changing this structure in setup() by
explicit position is a bad habbit and will lead to unexpected side
effect when this structure gets changed.
> + {0, -1, EINVAL},
> + /*
> + * test4
> + * temporarily set epfd to 0
> + * will be set to an epoll instance later
> + */
> + {0, 0, EINVAL},
> +};
> +
> +char *TCID = "epoll_wait03";
> +int TST_TOTAL = ARRAY_SIZE(test_cases);
> +
> +static void setup(void);
> +static void verify_epoll_wait(struct test_case_t *test_cases);
> +static void cleanup(void);
> +
> +int main(int ac, char **av)
> +{
> + int lc, tc;
> +
> + tst_parse_opts(ac, av, NULL, NULL);
> +
> + setup();
> +
> + for (lc = 0; TEST_LOOPING(lc); lc++) {
> + tst_count = 0;
> +
> + for (tc = 0; tc < TST_TOTAL; tc++)
> + verify_epoll_wait(&test_cases[tc]);
> + }
> +
> + cleanup();
> + tst_exit();
> +}
> +
> +static void setup(void)
> +{
> + tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +
> + TEST_PAUSE;
> +
> + SAFE_PIPE(NULL, fds);
> +
> + epfd = epoll_create(1);
> + if (epfd == -1) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to create epoll instance");
> + }
> +
> + test_cases[2].epfd = epfd;
> + test_cases[3].epfd = epfd;
> +
> + epevs[0].events = EPOLLOUT;
> + epevs[0].data.fd = fds[1];
This should be initialized statically as:
static struct epoll_event epevs[1] = {
{.events = EPOLLOUT, .data = {.fd = fds[1]}}
};
> + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0])) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to register epoll target");
> + }
> +}
> +
> +static void verify_epoll_wait(struct test_case_t *test_cases)
> +{
> + TEST(epoll_wait(test_cases->epfd, epevs, test_cases->maxevents, -1));
> + if (TEST_RETURN != -1) {
> + tst_resm(TFAIL, "epoll_wait() succeed unexpectedly");
> + } else {
> + if (TEST_ERRNO == test_cases->exp_errno) {
> + tst_resm(TPASS | TTERRNO,
> + "epoll_wait() fails as expected");
> + } else {
> + tst_resm(TFAIL | TTERRNO,
> + "epoll_wait() fails unexpectedly, "
> + "expected %d: %s", test_cases->exp_errno,
> + strerror(test_cases->exp_errno));
^
you shoud use tst_strerrno() instead
> + }
> + }
> +}
> +
> +static void cleanup(void)
> +{
> + if (epfd > 0 && close(epfd))
> + tst_resm(TWARN | TERRNO, "failed to close epfd");
> +
> + if (close(fds[0]))
> + tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
> +
> + if (close(fds[1]))
> + tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
> +}
The rest looks good.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH 4/4] epoll_wait/epoll_wait04.c: add new testcase
2016-01-06 1:19 ` [LTP] [PATCH 4/4] epoll_wait/epoll_wait04.c: " Guangwen Feng
@ 2016-01-28 17:24 ` Cyril Hrubis
0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2016-01-28 17:24 UTC (permalink / raw)
To: ltp
Hi!
> Verify that:
> epoll_wait(2) fails if the memory area pointed to by events is not
> accessible with write permissions.
>
> Expected result:
> epoll_wait(2) should return -1 and set errno to EFAULT
Is there any reason why this is not part of the previous (epoll_wait03)
test? All that needs to be done is that the test_case structrue would
have to have epoll_event **ev member that would either pointing to
epoll_event * variable initialized in the setup by mmap() or different
one that will point to the static array (since we cannot get pointer to
variable holding the array).
The code would look like:
epoll_event *ev_efault;
epoll_event *ev = &evps;
{
{&fd, 1, &ev_efault, EFAULT},
{&fd, -1, &ev, EINVAL},
...
}
...
TEST(epoll_wait(*(tc->epfd), *(tc->ev), tc->maxevents, -1));
...
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase
2016-01-28 16:19 ` [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
@ 2016-02-01 5:28 ` Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
0 siblings, 1 reply; 15+ messages in thread
From: Guangwen Feng @ 2016-02-01 5:28 UTC (permalink / raw)
To: ltp
Hi!
Thanks for your review!
I will modify these test cases according to your suggestion.
Best Regards,
Guangwen Feng
On 01/29/2016 12:19 AM, Cyril Hrubis wrote:
> Hi!
>> diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
>> new file mode 100644
>> index 0000000..46058a2
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
>> @@ -0,0 +1,263 @@
>> +/*
>> + * Copyright (c) 2015 Fujitsu Ltd.
>> + * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
>> + * the GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.
>> + */
>> +
>> +/*
>> + * Description:
>> + * Basic test for epoll_wait(2).
>> + * Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
>> + * on a epoll instance and that struct epoll_event is set correctly.
>> + */
>> +
>> +#include <sys/epoll.h>
>> +#include <unistd.h>
>> +#include <fcntl.h>
>> +#include <poll.h>
>> +#include <errno.h>
>> +
>> +#include "test.h"
>> +#include "safe_macros.h"
>> +#include "lapi/fcntl.h"
>> +
>> +char *TCID = "epoll_wait01";
>> +int TST_TOTAL = 3;
>> +
>> +static int write_size, epfd, fds[2];
>> +static struct epoll_event epevs[2];
>> +
>> +static void setup(void);
>> +static int get_writesize(void);
>> +static void verify_epollout(void);
>> +static void verify_epollin(void);
>> +static void verify_epollio(void);
>> +static void cleanup(void);
>> +
>> +int main(int ac, char **av)
>> +{
>> + int lc;
>> +
>> + tst_parse_opts(ac, av, NULL, NULL);
>> +
>> + setup();
>> +
>> + for (lc = 0; TEST_LOOPING(lc); lc++) {
>> + tst_count = 0;
>> +
>> + verify_epollout();
>> + verify_epollin();
>> + verify_epollio();
>> + }
>> +
>> + cleanup();
>> + tst_exit();
>> +}
>> +
>> +static void setup(void)
>> +{
>> + int pipe_capacity;
>> +
>> + tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> +
>> + TEST_PAUSE;
>> +
>> + SAFE_PIPE(NULL, fds);
>> +
>> + /* fcntl()'s F_GETPIPE_SZ flag availbility check */
>> + if ((tst_kvercmp(2, 6, 35)) < 0) {
>> + write_size = get_writesize();
>> + } else {
>> + pipe_capacity = fcntl(fds[1], F_GETPIPE_SZ);
>> + if (pipe_capacity == -1) {
>> + tst_brkm(TBROK | TERRNO, cleanup,
>> + "failed to get the pipe capacity");
>> + }
>> +
>> + write_size = pipe_capacity - getpagesize() + 1;
>> + }
>
> I would rather go with runtime detection even for newer kernels. Since
> otherwise we have two different codepaths to test.
>
>> + epfd = epoll_create(2);
>> + if (epfd == -1) {
>> + tst_brkm(TBROK | TERRNO, cleanup,
>> + "failed to create epoll instance");
>> + }
>> +
>> + epevs[0].events = EPOLLIN;
>> + epevs[0].data.fd = fds[0];
>> + epevs[1].events = EPOLLOUT;
>> + epevs[1].data.fd = fds[1];
>> +
>> + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
>> + epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1])) {
>> + tst_brkm(TBROK | TERRNO, cleanup,
>> + "failed to register epoll target");
>> + }
>> +}
>> +
>> +/*
>> + * fcntl(fd, F_GETPIPE_SZ) not supported on kernels which
>> + * version lower than 2.6.35, so use this function instead
>> + */
>> +static int get_writesize(void)
>> +{
>> + int nfd, write_size;
>> +
>> + struct pollfd pfd[] = {
>> + {.fd = fds[0], .events = POLLIN},
>> + {.fd = fds[1], .events = POLLOUT},
>> + };
>> +
>> + write_size = 0;
>> + do {
>> + SAFE_WRITE(cleanup, 1, fds[1], "a", 1);
>> + write_size++;
>> + nfd = poll(pfd, 2, -1);
>> + if (nfd == -1)
>> + tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
>> + } while (nfd == 2);
>
> Why don't we write larger chunks and add the return from SAFE_WRITE to
> the write_size? That should work if we pass 0 as len strict, the last
> write should just end up truncated.
>
>> + char buf[write_size];
>> +
>> + SAFE_READ(cleanup, 1, fds[0], buf, write_size);
>> +
>> + return write_size;
>> +}
>> +
>> +static void verify_epollout(void)
>> +{
>> + TEST(epoll_wait(epfd, epevs, 2, -1));
>> +
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
>> + return;
>> + }
>> +
>> + if (TEST_RETURN != 1) {
>> + tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
> ^
> We should add the TEST_RETURN
> value to the output here
> I would go for:
> tst_resm(TFAIL, "epoll_wait() returned %i expected 1",
> TEST_RETURN);
>
>
>> + return;
>> + }
>> +
>> + if (epevs[0].data.fd != fds[1]) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set write fd");
>
> And maybe write the actuall fds here:
>
> tst_resm(TFAIL, "epoll.data.fd %i expected %i", ...);
>
>> + return;
>> + }
>> +
>> + if (epevs[0].events != EPOLLOUT) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set EPOLLOUT");
>
> And perhaps print the value of events as hexadecimal here.
>
>> + return;
>> + }
>> +
>> + tst_resm(TPASS, "epoll_wait() epollout");
>> +}
>> +
>> +static void verify_epollin(void)
>> +{
>> + char write_buf[write_size];
>> + char read_buf[sizeof(write_buf)];
>> +
>> + memset(write_buf, 'a', sizeof(write_buf));
>> +
>> + SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
>> +
>> + TEST(epoll_wait(epfd, epevs, 2, -1));
>> +
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
>> + goto end;
>> + }
>> +
>> + if (TEST_RETURN != 1) {
>> + tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
>> + goto end;
>> + }
>> +
>> + if (epevs[0].data.fd != fds[0]) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set read fd");
>> + goto end;
>> + }
>> +
>> + if (epevs[0].events != EPOLLIN) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set EPOLLIN");
>> + goto end;
>> + }
>
> And I would be more verbose about the values in these messages as well.
>
>> + tst_resm(TPASS, "epoll_wait() epollin");
>> +
>> +end:
>> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
>> +}
>> +
>> +static void verify_epollio(void)
>> +{
>> + int i, checked0, checked1;
>> + char write_buf[] = "Testing";
>> + char read_buf[sizeof(write_buf)];
>> +
>> + SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
>> +
>> + TEST(epoll_wait(epfd, epevs, 2, -1));
> ^
> Shouldn't we pass at least 3 here (and
> declare epevs to have three elements as
> well). Since if there were three events
> queued the epoll_wait() would return just
> 2 and the test will pass.
>
>> +
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
>> + goto end;
>> + }
>> +
>> + if (TEST_RETURN != 2) {
>> + tst_resm(TFAIL, "epoll_wait() failed to get two fds ready");
>> + goto end;
>> + }
>> +
>> + checked0 = 0;
>> + checked1 = 0;
>> + for (i = 0; i < TEST_RETURN; i++) {
>> + if (checked0 == 0 && epevs[i].data.fd == fds[0]) {
>> + if (epevs[i].events != EPOLLIN) {
>> + tst_resm(TFAIL, "epoll_wait()"
>> + "failed to set EPOLLIN");
>> + goto end;
>> + }
>> + checked0 = 1;
>> + } else if (checked1 == 0 && epevs[i].data.fd == fds[1]) {
>> + if (epevs[i].events != EPOLLOUT) {
>> + tst_resm(TFAIL, "epoll_wait()"
>> + "failed to set EPOLLOUT");
>> + goto end;
>> + }
>> + checked1 = 1;
>> + } else {
>> + tst_resm(TFAIL, "epoll_wait()"
>> + "failed to set write or read fd");
>> + goto end;
>> + }
>> + }
>
>
> Hmm, this is kind of messy. I would implement this as function that
> checks if the array has event with specific values and would have called
> it twice once with read fd and once with write fd.
>
> static int has_event(struct epoll_event *events, int events_len,
> int fd, uint32_t events)
> {
> ...
> }
>
> ...
> if (!has_event(epevs, 2, fds[0], EPOLLIN))
> tst_resm(TFAIL, ...);
>
> if (!has_event(epevs, 2, fds[1], EPOLLOUT))
> tst_resm(TFAIL, ...);
> ...
>
>
> And perhaps we can add a function to dump the epevs array with
> tst_resm(TINFO, "") and call it on the array whenever we find that
> something went wrong before we do tst_resm(TFAIL, ...);
>
>> + tst_resm(TPASS, "epoll_wait() epollio");
>> +
>> +end:
>> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
>> +}
>> +
>> +static void cleanup(void)
>> +{
>> + if (epfd > 0 && close(epfd))
>> + tst_resm(TWARN | TERRNO, "failed to close epfd");
>> +
>> + if (close(fds[0]))
>> + tst_resm(TWARN | TERRNO, "failed to close fds[0]");
>> +
>> + if (close(fds[1]))
>> + tst_resm(TWARN | TERRNO, "failed to close fds[1]");
>> +}
>
> The rest looks good.
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH v2 1/3] epoll_wait/epoll_wait01.c: add new testcase
2016-02-01 5:28 ` Guangwen Feng
@ 2016-02-17 10:51 ` Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Guangwen Feng @ 2016-02-17 10:51 UTC (permalink / raw)
To: ltp
Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
on a epoll instance and that struct epoll_event is set correctly.
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 2 +
runtest/stress.part3 | 2 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/epoll_wait/Makefile | 23 ++
.../kernel/syscalls/epoll_wait/epoll_wait01.c | 281 +++++++++++++++++++++
6 files changed, 310 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/Makefile
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 89accc4..79ab6a1 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -159,6 +159,8 @@ dup203 dup203
dup204 dup204
dup205 dup205
+epoll_wait01 epoll_wait01
+
execl01 execl01
execle01 execle01
execlp01 execlp01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 85950bf..20fe314 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -100,6 +100,8 @@ dup203 dup203
dup204 dup204
dup205 dup205
+epoll_wait01 epoll_wait01
+
execl01 execl01
execle01 execle01
execlp01 execlp01
diff --git a/runtest/syscalls b/runtest/syscalls
index 5f169a3..a1591ec 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -122,6 +122,7 @@ dup3_02 dup3_02
epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
+epoll_wait01 epoll_wait01
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index de403e4..01a3cc0 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -97,6 +97,7 @@
/dup3/dup3_02
/epoll/epoll-ltp
/epoll_create1/epoll_create1_01
+/epoll_wait/epoll_wait01
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/Makefile b/testcases/kernel/syscalls/epoll_wait/Makefile
new file mode 100644
index 0000000..289aaaf
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2016 Fujitsu Ltd.
+# Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
new file mode 100644
index 0000000..9ae7580
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2016 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * Basic test for epoll_wait(2).
+ * Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
+ * on a epoll instance and that struct epoll_event is set correctly.
+ */
+
+#include <sys/epoll.h>
+#include <poll.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "epoll_wait01";
+int TST_TOTAL = 3;
+
+static int write_size, epfd, fds[2], fds2[2];
+static struct epoll_event epevs[3] = {
+ {.events = EPOLLIN},
+ {.events = EPOLLOUT},
+ {.events = EPOLLIN}
+};
+
+static void setup(void);
+static int get_writesize(void);
+static void verify_epollout(void);
+static void verify_epollin(void);
+static void verify_epollio(void);
+static int has_event(struct epoll_event *, int, int, uint32_t);
+static void dump_epevs(struct epoll_event *, int);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_epollout();
+ verify_epollin();
+ verify_epollio();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ SAFE_PIPE(NULL, fds);
+ SAFE_PIPE(cleanup, fds2);
+
+ write_size = get_writesize();
+
+ epfd = epoll_create(3);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].data.fd = fds[0];
+ epevs[1].data.fd = fds[1];
+ epevs[2].data.fd = fds2[0];
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
+ epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1]) ||
+ epoll_ctl(epfd, EPOLL_CTL_ADD, fds2[0], &epevs[2])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static int get_writesize(void)
+{
+ int nfd, write_size;
+ char buf[4096];
+
+ memset(buf, 'a', sizeof(buf));
+
+ struct pollfd pfd[] = {
+ {.fd = fds[0], .events = POLLIN},
+ {.fd = fds[1], .events = POLLOUT},
+ };
+
+ write_size = 0;
+ do {
+ write_size += SAFE_WRITE(cleanup, 0, fds[1], buf, sizeof(buf));
+ nfd = poll(pfd, 2, -1);
+ if (nfd == -1)
+ tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
+ } while (nfd == 2);
+
+ char read_buf[write_size];
+
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(read_buf));
+
+ return write_size;
+}
+
+static void verify_epollout(void)
+{
+ TEST(epoll_wait(epfd, epevs, 3, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
+ return;
+ }
+
+ if (TEST_RETURN != 1) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 1",
+ TEST_RETURN);
+ return;
+ }
+
+ if (epevs[0].data.fd != fds[1]) {
+ tst_resm(TFAIL, "epoll.data.fd %i, expected %i",
+ epevs[0].data.fd, fds[1]);
+ return;
+ }
+
+ if (epevs[0].events != EPOLLOUT) {
+ tst_resm(TFAIL, "epoll.events %x, expected EPOLLOUT %x",
+ epevs[0].events, EPOLLOUT);
+ return;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollout");
+}
+
+static void verify_epollin(void)
+{
+ char write_buf[write_size];
+ char read_buf[sizeof(write_buf)];
+
+ memset(write_buf, 'a', sizeof(write_buf));
+
+ SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+ TEST(epoll_wait(epfd, epevs, 3, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
+ goto end;
+ }
+
+ if (TEST_RETURN != 1) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 1",
+ TEST_RETURN);
+ goto end;
+ }
+
+ if (epevs[0].data.fd != fds[0]) {
+ tst_resm(TFAIL, "epoll.data.fd %i, expected %i",
+ epevs[0].data.fd, fds[0]);
+ goto end;
+ }
+
+ if (epevs[0].events != EPOLLIN) {
+ tst_resm(TFAIL, "epoll.events %x, expected EPOLLIN %x",
+ epevs[0].events, EPOLLIN);
+ goto end;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollin");
+
+end:
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static void verify_epollio(void)
+{
+ char write_buf[] = "Testing";
+ char read_buf[sizeof(write_buf)];
+
+ SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+ TEST(epoll_wait(epfd, epevs, 3, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
+ goto end;
+ }
+
+ if (TEST_RETURN != 2) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 2",
+ TEST_RETURN);
+ goto end;
+ }
+
+ if (!has_event(epevs, 2, fds[0], EPOLLIN)) {
+ dump_epevs(epevs, 2);
+ tst_resm(TFAIL, "epoll_wait() expected %d and EPOLLIN %x",
+ fds[0], EPOLLIN);
+ goto end;
+ }
+
+ if (!has_event(epevs, 2, fds[1], EPOLLOUT)) {
+ dump_epevs(epevs, 2);
+ tst_resm(TFAIL, "epoll_wait() expected %d and EPOLLOUT %x",
+ fds[1], EPOLLOUT);
+ goto end;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollio");
+
+end:
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static int has_event(struct epoll_event *epevs, int epevs_len,
+ int fd, uint32_t events)
+{
+ int i, result;
+
+ result = 0;
+ for (i = 0; i < epevs_len; i++) {
+ if ((epevs[i].data.fd == fd) && (epevs[i].events == events)) {
+ result = 1;
+ break;
+ }
+ }
+
+ return result;
+}
+
+static void dump_epevs(struct epoll_event *epevs, int epevs_len)
+{
+ int i;
+
+ for (i = 0; i < epevs_len; i++) {
+ tst_resm(TINFO, "epevs[%d]: epoll.data.fd %d, epoll.events %x",
+ i, epevs[i].data.fd, epevs[i].events);
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "failed to close fds[0]");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "failed to close fds[1]");
+
+ if (fds2[0] > 0 && close(fds2[0]))
+ tst_resm(TWARN | TERRNO, "failed to close fds2[0]");
+
+ if (fds2[1] > 0 && close(fds2[1]))
+ tst_resm(TWARN | TERRNO, "failed to close fds2[1]");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
@ 2016-02-17 10:51 ` Guangwen Feng
2016-02-25 12:37 ` Cyril Hrubis
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
2016-02-24 16:11 ` [LTP] [PATCH v2 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
2 siblings, 1 reply; 15+ messages in thread
From: Guangwen Feng @ 2016-02-17 10:51 UTC (permalink / raw)
To: ltp
Check that epoll_wait(2) timeouts correctly.
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/epoll_wait/Makefile | 2 +
.../kernel/syscalls/epoll_wait/epoll_wait02.c | 145 +++++++++++++++++++++
6 files changed, 151 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 79ab6a1..aa4ebdc 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -160,6 +160,7 @@ dup204 dup204
dup205 dup205
epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
execl01 execl01
execle01 execle01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 20fe314..7d629c5 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -101,6 +101,7 @@ dup204 dup204
dup205 dup205
epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
execl01 execl01
execle01 execle01
diff --git a/runtest/syscalls b/runtest/syscalls
index a1591ec..23d7adc 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -123,6 +123,7 @@ dup3_02 dup3_02
epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 01a3cc0..85feeac 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -98,6 +98,7 @@
/epoll/epoll-ltp
/epoll_create1/epoll_create1_01
/epoll_wait/epoll_wait01
+/epoll_wait/epoll_wait02
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/Makefile b/testcases/kernel/syscalls/epoll_wait/Makefile
index 289aaaf..f29b9a7 100644
--- a/testcases/kernel/syscalls/epoll_wait/Makefile
+++ b/testcases/kernel/syscalls/epoll_wait/Makefile
@@ -18,6 +18,8 @@
top_srcdir ?= ../../../..
+epoll_wait02: LDLIBS+=-lrt
+
include $(top_srcdir)/include/mk/testcases.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
new file mode 100644
index 0000000..a32e82e
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * Check that epoll_wait(2) timeouts correctly.
+ */
+
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "epoll_wait02";
+int TST_TOTAL = 1;
+
+static int epfd, fds[2];
+static char *opt_sleep_ms;
+static struct epoll_event epevs[1] = {
+ {.events = EPOLLIN}
+};
+
+static option_t opts[] = {
+ {"s:", NULL, &opt_sleep_ms},
+ {NULL, NULL, NULL}
+};
+
+static void setup(void);
+static void cleanup(void);
+static void help(void);
+
+int main(int ac, char **av)
+{
+ int lc, threshold;
+ long long elapsed_ms, sleep_ms = 100;
+
+ tst_parse_opts(ac, av, opts, help);
+
+ if (opt_sleep_ms) {
+ sleep_ms = atoll(opt_sleep_ms);
+
+ if (sleep_ms == 0) {
+ tst_brkm(TBROK, NULL,
+ "Invalid timeout '%s'", opt_sleep_ms);
+ }
+ }
+
+ threshold = sleep_ms / 100 + 10;
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ tst_timer_start(CLOCK_MONOTONIC);
+ TEST(epoll_wait(epfd, epevs, 1, sleep_ms));
+ tst_timer_stop();
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() failed");
+ continue;
+ }
+
+ if (TEST_RETURN != 0) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 0",
+ TEST_RETURN);
+ continue;
+ }
+
+ elapsed_ms = tst_timer_elapsed_ms();
+
+ if (elapsed_ms < sleep_ms) {
+ tst_resm(TFAIL, "epoll_wait() woken up too early %llims, "
+ "expected %llims", elapsed_ms, sleep_ms);
+ continue;
+ }
+
+ if (elapsed_ms - sleep_ms > threshold) {
+ tst_resm(TFAIL, "epoll_wait() slept too long %llims, "
+ "expected %llims, threshold %i",
+ elapsed_ms, sleep_ms, threshold);
+ continue;
+ }
+
+ tst_resm(TPASS, "epoll_wait() slept %llims, expected %llims, "
+ "threshold %i", elapsed_ms, sleep_ms, threshold);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_timer_check(CLOCK_MONOTONIC);
+
+ SAFE_PIPE(NULL, fds);
+
+ epfd = epoll_create(1);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].data.fd = fds[0];
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
+
+static void help(void)
+{
+ printf(" -s epoll_wait() timeout length in ms\n");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
@ 2016-02-17 10:51 ` Guangwen Feng
2016-02-25 13:52 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Cyril Hrubis
2016-02-24 16:11 ` [LTP] [PATCH v2 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
2 siblings, 1 reply; 15+ messages in thread
From: Guangwen Feng @ 2016-02-17 10:51 UTC (permalink / raw)
To: ltp
Verify that:
1) epoll_wait(2) fails if epfd is not a valid file descriptor
2) epoll_wait(2) fails if epfd is not an epoll file descriptor
3) epoll_wait(2) fails if maxevents is less than zero
4) epoll_wait(2) fails if maxevents is equal to zero
5) epoll_wait(2) fails if the memory area pointed to by events
is not accessible with write permissions.
Expected result:
1) epoll_wait(2) should return -1 and set errno to EBADF
2) epoll_wait(2) should return -1 and set errno to EINVAL
3) epoll_wait(2) should return -1 and set errno to EINVAL
4) epoll_wait(2) should return -1 and set errno to EINVAL
5) epoll_wait(2) should return -1 and set errno to EFAULT
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait03.c | 158 +++++++++++++++++++++
5 files changed, 162 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
diff --git a/runtest/ltplite b/runtest/ltplite
index aa4ebdc..ced593f 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -161,6 +161,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
execl01 execl01
execle01 execle01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 7d629c5..ab2c531 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -102,6 +102,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
execl01 execl01
execle01 execle01
diff --git a/runtest/syscalls b/runtest/syscalls
index 23d7adc..dbef381 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -124,6 +124,7 @@ epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 85feeac..97b8fd8 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -99,6 +99,7 @@
/epoll_create1/epoll_create1_01
/epoll_wait/epoll_wait01
/epoll_wait/epoll_wait02
+/epoll_wait/epoll_wait03
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
new file mode 100644
index 0000000..56b32da
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * 1) epoll_wait(2) fails if epfd is not a valid file descriptor
+ * 2) epoll_wait(2) fails if epfd is not an epoll file descriptor
+ * 3) epoll_wait(2) fails if maxevents is less than zero
+ * 4) epoll_wait(2) fails if maxevents is equal to zero
+ * 5) epoll_wait(2) fails if the memory area pointed to by events
+ * is not accessible with write permissions.
+ *
+ * Expected Result:
+ * 1) epoll_wait(2) should return -1 and set errno to EBADF
+ * 2) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 3) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 4) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 5) epoll_wait(2) should return -1 and set errno to EFAULT
+ */
+
+#include <sys/epoll.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+static int page_size, fds[2], epfd, inv_epfd, bad_epfd = -1;
+
+static struct epoll_event epevs[1] = {
+ {.events = EPOLLOUT}
+};
+
+static struct epoll_event *ev_rdwr = epevs;
+static struct epoll_event *ev_rdonly;
+
+static struct test_case_t {
+ int *epfd;
+ struct epoll_event **ev;
+ int maxevents;
+ int exp_errno;
+} tc[] = {
+ /* test1 */
+ {&bad_epfd, &ev_rdwr, 1, EBADF},
+ /* test2 */
+ {&inv_epfd, &ev_rdwr, 1, EINVAL},
+ /* test3 */
+ {&epfd, &ev_rdwr, -1, EINVAL},
+ /* test4 */
+ {&epfd, &ev_rdwr, 0, EINVAL},
+ /* test5 */
+ {&epfd, &ev_rdonly, 1, EFAULT}
+};
+
+char *TCID = "epoll_wait03";
+int TST_TOTAL = ARRAY_SIZE(tc);
+
+static void setup(void);
+static void verify_epoll_wait(struct test_case_t *tc);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc, i;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ for (i = 0; i < TST_TOTAL; i++)
+ verify_epoll_wait(&tc[i]);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ page_size = getpagesize();
+
+ ev_rdonly = SAFE_MMAP(NULL, NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ SAFE_PIPE(NULL, fds);
+
+ epfd = epoll_create(1);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].data.fd = fds[1];
+
+ if (mprotect(ev_rdonly, page_size, PROT_READ)) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to set memory area read-only");
+ }
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static void verify_epoll_wait(struct test_case_t *tc)
+{
+ TEST(epoll_wait(*(tc->epfd), *(tc->ev), tc->maxevents, -1));
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "epoll_wait() succeed unexpectedly");
+ } else {
+ if (tc->exp_errno == TEST_ERRNO) {
+ tst_resm(TPASS | TTERRNO,
+ "epoll_wait() fails as expected");
+ } else {
+ tst_resm(TFAIL | TTERRNO,
+ "epoll_wait() fails unexpectedly, "
+ "expected %d: %s", tc->exp_errno,
+ tst_strerrno(tc->exp_errno));
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [LTP] [PATCH v2 1/3] epoll_wait/epoll_wait01.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
@ 2016-02-24 16:11 ` Cyril Hrubis
2 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2016-02-24 16:11 UTC (permalink / raw)
To: ltp
Hi!
Pushed with minor changes. Thanks.
> +static int get_writesize(void)
> +{
> + int nfd, write_size;
> + char buf[4096];
> +
> + memset(buf, 'a', sizeof(buf));
> +
> + struct pollfd pfd[] = {
> + {.fd = fds[0], .events = POLLIN},
> + {.fd = fds[1], .events = POLLOUT},
> + };
> +
> + write_size = 0;
> + do {
> + write_size += SAFE_WRITE(cleanup, 0, fds[1], buf, sizeof(buf));
> + nfd = poll(pfd, 2, -1);
> + if (nfd == -1)
> + tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
> + } while (nfd == 2);
I've removed the fds[0] from the pollfd structure and instead of that
changed the poll() to have 1 ms timeout. Since making sure that it
returns on timeout is less confusing than making sure the poll returns
because we passed another file descriptor that has some data to be
read...
> + char read_buf[write_size];
> +
> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(read_buf));
> +
> + return write_size;
> +}
...
> +static int has_event(struct epoll_event *epevs, int epevs_len,
> + int fd, uint32_t events)
> +{
> + int i, result;
> +
> + result = 0;
> + for (i = 0; i < epevs_len; i++) {
> + if ((epevs[i].data.fd == fd) && (epevs[i].events == events)) {
> + result = 1;
> + break;
> + }
> + }
> +
> + return result;
> +}
And simplified this part to:
...
{
int i;
for (i = 0; i < epevs_len; i++) {
if ((epevs[i].data.fd == fd) && (epevs[i].events == events))
return 1;
}
return 0;
}
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
@ 2016-02-25 12:37 ` Cyril Hrubis
0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2016-02-25 12:37 UTC (permalink / raw)
To: ltp
Hi!
Applied, thanks.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
@ 2016-02-25 13:52 ` Cyril Hrubis
0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2016-02-25 13:52 UTC (permalink / raw)
To: ltp
Hi!
> + ev_rdonly = SAFE_MMAP(NULL, NULL, page_size, PROT_READ | PROT_WRITE,
> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> +
...
> + if (mprotect(ev_rdonly, page_size, PROT_READ)) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to set memory area read-only");
> + }
I've removed the PROT_WRITE from the mmap() flags and the mprotect() and
pushed, thanks.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2016-02-25 13:52 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-30 10:44 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase Guangwen Feng
2015-12-30 10:44 ` [LTP] [PATCH 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
2016-01-28 16:35 ` Cyril Hrubis
2015-12-30 10:44 ` [LTP] [PATCH 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
2016-01-28 17:16 ` Cyril Hrubis
2016-01-06 1:19 ` [LTP] [PATCH 4/4] epoll_wait/epoll_wait04.c: " Guangwen Feng
2016-01-28 17:24 ` Cyril Hrubis
2016-01-28 16:19 ` [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
2016-02-01 5:28 ` Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 2/3] epoll_wait/epoll_wait02.c: " Guangwen Feng
2016-02-25 12:37 ` Cyril Hrubis
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
2016-02-25 13:52 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Cyril Hrubis
2016-02-24 16:11 ` [LTP] [PATCH v2 1/3] epoll_wait/epoll_wait01.c: " Cyril Hrubis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox