From 9c6935e81854d1585bbfa48c35b185849d746864 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2018 09:03:25 +0100 Subject: add test for aio poll and io_pgetevents Signed-off-by: Christoph Hellwig Signed-off-by: Jeff Moyer --- harness/cases/22.t | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 harness/cases/22.t (limited to 'harness') diff --git a/harness/cases/22.t b/harness/cases/22.t new file mode 100644 index 0000000..c7e7c0e --- /dev/null +++ b/harness/cases/22.t @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2006-2018 Free Software Foundation, Inc. + * Copyright (C) 2018 Christoph Hellwig. + * License: LGPLv2.1 or later. + * + * Description: test aio poll and io_pgetevents signal handling. + * + * Very roughly based on glibc tst-pselect.c. + */ +#include +#include +#include +#include +#include +#include +#include + +static volatile int handler_called; + +static void +handler(int sig) +{ + handler_called = 1; +} + +int test_main(void) +{ + struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 }; + pid_t parent = getpid(), p; + int pipe1[2], pipe2[2]; + struct sigaction sa = { .sa_flags = 0 }; + sigset_t sigmask; + struct io_context *ctx = NULL; + struct io_event ev; + struct iocb iocb; + struct iocb *iocbs[] = { &iocb }; + int ret; + + sigemptyset(&sa.sa_mask); + + sa.sa_handler = handler; + if (sigaction(SIGUSR1, &sa, NULL) != 0) { + printf("sigaction(1) failed\n"); + return 1; + } + + sa.sa_handler = SIG_IGN; + if (sigaction(SIGCHLD, &sa, NULL) != 0) { + printf("sigaction(2) failed\n"); + return 1; + } + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + if (sigprocmask(SIG_BLOCK, &sigmask, NULL) != 0) { + printf("sigprocmask failed\n"); + return 1; + } + + if (pipe(pipe1) != 0 || pipe(pipe2) != 0) { + printf("pipe failed\n"); + return 1; + } + + sigprocmask(SIG_SETMASK, NULL, &sigmask); + sigdelset(&sigmask, SIGUSR1); + + p = fork(); + switch (p) { + case -1: + printf("fork failed\n"); + exit(2); + case 0: + close(pipe1[1]); + close(pipe2[0]); + + ret = io_setup(1, &ctx); + if (ret) { + printf("child: io_setup failed\n"); + return 1; + } + + io_prep_poll(&iocb, pipe1[0], POLLIN); + ret = io_submit(ctx, 1, iocbs); + if (ret != 1) { + printf("child: io_submit failed\n"); + return 1; + } + + do { + if (getppid() != parent) { + printf("parent died\n"); + exit(2); + } + ret = io_pgetevents(ctx, 1, 1, &ev, &to, &sigmask); + } while (ret == 0); + + if (ret != -EINTR) { + printf("child: io_pgetevents did not set errno to EINTR\n"); + return 1; + } + + do { + errno = 0; + ret = write(pipe2[1], "foo", 3); + } while (ret == -1 && errno == EINTR); + + exit(0); + default: + close(pipe1[0]); + close(pipe2[1]); + + io_prep_poll(&iocb, pipe2[0], POLLIN); + + ret = io_setup(1, &ctx); + if (ret) { + printf("parent: io_setup failed\n"); + return 1; + } + + ret = io_submit(ctx, 1, iocbs); + if (ret != 1) { + printf("parent: io_submit failed\n"); + return 1; + } + + kill(p, SIGUSR1); + + ret = io_pgetevents(ctx, 1, 1, &ev, NULL, &sigmask); + if (ret < 0) { + printf("parent: io_pgetevents failed\n"); + return 1; + } + if (ret != 1) { + printf("parent: io_pgetevents did not report event\n"); + return 1; + } + if (ev.obj != &iocb) { + printf("parent: io_pgetevents reports wrong fd\n"); + return 1; + } + if (ev.res != POLLIN) { + printf("parent: io_pgetevents did not report readable fd\n"); + return 1; + } + + return 0; + } +} -- cgit v1.2.1