1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Description: test that sigfd reading/polling works. A regression test for
4 * the upstream commit:
5 *
6 * fd7d6de22414 ("io_uring: don't recurse on tsk->sighand->siglock with signalfd")
7 */
8 #include <unistd.h>
9 #include <sys/signalfd.h>
10 #include <sys/epoll.h>
11 #include <poll.h>
12 #include <stdio.h>
13 #include "liburing.h"
14 #include "helpers.h"
15
setup_signal(void)16 static int setup_signal(void)
17 {
18 sigset_t mask;
19 int sfd;
20
21 sigemptyset(&mask);
22 sigaddset(&mask, SIGINT);
23
24 sigprocmask(SIG_BLOCK, &mask, NULL);
25 sfd = signalfd(-1, &mask, SFD_NONBLOCK);
26 if (sfd < 0)
27 perror("signalfd");
28 return sfd;
29 }
30
test_uring(int sfd)31 static int test_uring(int sfd)
32 {
33 struct io_uring_sqe *sqe;
34 struct io_uring_cqe *cqe;
35 struct io_uring ring;
36 int ret;
37
38 ret = io_uring_queue_init(32, &ring, 0);
39 if (ret)
40 return T_EXIT_FAIL;
41
42 sqe = io_uring_get_sqe(&ring);
43 io_uring_prep_poll_add(sqe, sfd, POLLIN);
44 ret = io_uring_submit(&ring);
45 if (ret < 0) {
46 ret = T_EXIT_FAIL;
47 goto err_exit;
48 }
49
50 kill(getpid(), SIGINT);
51
52 io_uring_wait_cqe(&ring, &cqe);
53 if (cqe->res == -EOPNOTSUPP) {
54 fprintf(stderr, "signalfd poll not supported\n");
55 ret = T_EXIT_SKIP;
56 } else if (cqe->res < 0) {
57 fprintf(stderr, "poll failed: %d\n", cqe->res);
58 ret = T_EXIT_FAIL;
59 } else if (cqe->res & POLLIN) {
60 ret = T_EXIT_PASS;
61 } else {
62 fprintf(stderr, "Unexpected poll mask %x\n", cqe->res);
63 ret = T_EXIT_FAIL;
64 }
65 io_uring_cqe_seen(&ring, cqe);
66 err_exit:
67 io_uring_queue_exit(&ring);
68 return ret;
69 }
70
main(int argc,char * argv[])71 int main(int argc, char *argv[])
72 {
73 int sfd, ret;
74
75 if (argc > 1)
76 return T_EXIT_PASS;
77
78 sfd = setup_signal();
79 if (sfd < 0)
80 return T_EXIT_FAIL;
81
82 ret = test_uring(sfd);
83 if (ret == T_EXIT_FAIL)
84 fprintf(stderr, "test_uring signalfd failed\n");
85
86 close(sfd);
87 return ret;
88 }
89