t_compat_cancel.c revision 1.3.4.2 1 1.3.4.2 perseant /* $NetBSD: t_compat_cancel.c,v 1.3.4.2 2025/08/02 05:58:09 perseant Exp $ */
2 1.3.4.2 perseant
3 1.3.4.2 perseant /*
4 1.3.4.2 perseant * Copyright (c) 2025 The NetBSD Foundation, Inc.
5 1.3.4.2 perseant * All rights reserved.
6 1.3.4.2 perseant *
7 1.3.4.2 perseant * Redistribution and use in source and binary forms, with or without
8 1.3.4.2 perseant * modification, are permitted provided that the following conditions
9 1.3.4.2 perseant * are met:
10 1.3.4.2 perseant * 1. Redistributions of source code must retain the above copyright
11 1.3.4.2 perseant * notice, this list of conditions and the following disclaimer.
12 1.3.4.2 perseant * 2. Redistributions in binary form must reproduce the above copyright
13 1.3.4.2 perseant * notice, this list of conditions and the following disclaimer in the
14 1.3.4.2 perseant * documentation and/or other materials provided with the distribution.
15 1.3.4.2 perseant *
16 1.3.4.2 perseant * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.3.4.2 perseant * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.3.4.2 perseant * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.3.4.2 perseant * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.3.4.2 perseant * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.3.4.2 perseant * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.3.4.2 perseant * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.3.4.2 perseant * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.3.4.2 perseant * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.3.4.2 perseant * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.3.4.2 perseant * POSSIBILITY OF SUCH DAMAGE.
27 1.3.4.2 perseant */
28 1.3.4.2 perseant
29 1.3.4.2 perseant #define __LIBC12_SOURCE__ /* expose compat declarations */
30 1.3.4.2 perseant
31 1.3.4.2 perseant #include <sys/cdefs.h>
32 1.3.4.2 perseant __RCSID("$NetBSD: t_compat_cancel.c,v 1.3.4.2 2025/08/02 05:58:09 perseant Exp $");
33 1.3.4.2 perseant
34 1.3.4.2 perseant #include <sys/event.h>
35 1.3.4.2 perseant #include <sys/mman.h>
36 1.3.4.2 perseant
37 1.3.4.2 perseant #include <aio.h>
38 1.3.4.2 perseant #include <atf-c.h>
39 1.3.4.2 perseant #include <mqueue.h>
40 1.3.4.2 perseant #include <pthread.h>
41 1.3.4.2 perseant #include <signal.h>
42 1.3.4.2 perseant
43 1.3.4.2 perseant #include <compat/sys/event.h>
44 1.3.4.2 perseant #include <compat/sys/mman.h>
45 1.3.4.2 perseant #include <compat/sys/poll.h>
46 1.3.4.2 perseant #include <compat/sys/select.h>
47 1.3.4.2 perseant
48 1.3.4.2 perseant #include <compat/include/aio.h>
49 1.3.4.2 perseant #include <compat/include/mqueue.h>
50 1.3.4.2 perseant #include <compat/include/signal.h>
51 1.3.4.2 perseant #include <compat/include/time.h>
52 1.3.4.2 perseant
53 1.3.4.2 perseant #include "cancelpoint.h"
54 1.3.4.2 perseant #include "h_macros.h"
55 1.3.4.2 perseant
56 1.3.4.2 perseant pthread_barrier_t bar;
57 1.3.4.2 perseant bool cleanup_done;
58 1.3.4.2 perseant
59 1.3.4.2 perseant static void
60 1.3.4.2 perseant cancelpoint_compat100_kevent(void)
61 1.3.4.2 perseant {
62 1.3.4.2 perseant int kq;
63 1.3.4.2 perseant struct kevent100 ev;
64 1.3.4.2 perseant
65 1.3.4.2 perseant memset(&ev, 0, sizeof(ev));
66 1.3.4.2 perseant ev.ident = SIGUSR1;
67 1.3.4.2 perseant ev.filter = EVFILT_SIGNAL;
68 1.3.4.2 perseant ev.flags = EV_ADD|EV_ENABLE;
69 1.3.4.2 perseant ev.fflags = 0;
70 1.3.4.2 perseant ev.data = 0;
71 1.3.4.2 perseant ev.udata = 0;
72 1.3.4.2 perseant
73 1.3.4.2 perseant RL(kq = kqueue());
74 1.3.4.2 perseant RL(__kevent50(kq, &ev, 1, NULL, 1, &(const struct timespec){0,0}));
75 1.3.4.2 perseant cancelpointready();
76 1.3.4.2 perseant RL(__kevent50(kq, NULL, 0, &ev, 1, NULL));
77 1.3.4.2 perseant }
78 1.3.4.2 perseant
79 1.3.4.2 perseant static void
80 1.3.4.2 perseant cancelpoint_compat12_msync(void)
81 1.3.4.2 perseant {
82 1.3.4.2 perseant const unsigned long pagesize = sysconf(_SC_PAGESIZE);
83 1.3.4.2 perseant int fd;
84 1.3.4.2 perseant void *map;
85 1.3.4.2 perseant
86 1.3.4.2 perseant RL(fd = open("file", O_RDWR|O_CREAT, 0666));
87 1.3.4.2 perseant RL(ftruncate(fd, pagesize));
88 1.3.4.2 perseant REQUIRE_LIBC(map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
89 1.3.4.2 perseant MAP_SHARED, fd, 0),
90 1.3.4.2 perseant MAP_FAILED);
91 1.3.4.2 perseant cancelpointready();
92 1.3.4.2 perseant RL(msync(map, pagesize));
93 1.3.4.2 perseant }
94 1.3.4.2 perseant
95 1.3.4.2 perseant static void
96 1.3.4.2 perseant cancelpoint_compat50___sigtimedwait(void)
97 1.3.4.2 perseant {
98 1.3.4.2 perseant sigset_t mask, omask;
99 1.3.4.2 perseant siginfo_t info;
100 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
101 1.3.4.2 perseant
102 1.3.4.2 perseant RL(__sigfillset14(&mask));
103 1.3.4.2 perseant RL(__sigprocmask14(SIG_BLOCK, &mask, &omask));
104 1.3.4.2 perseant cancelpointready();
105 1.3.4.2 perseant RL(__sigtimedwait(&omask, &info, &t));
106 1.3.4.2 perseant }
107 1.3.4.2 perseant
108 1.3.4.2 perseant static void
109 1.3.4.2 perseant cancelpoint_compat50_aio_suspend(void)
110 1.3.4.2 perseant {
111 1.3.4.2 perseant int fd[2];
112 1.3.4.2 perseant char buf[32];
113 1.3.4.2 perseant struct aiocb aio = {
114 1.3.4.2 perseant .aio_offset = 0,
115 1.3.4.2 perseant .aio_buf = buf,
116 1.3.4.2 perseant .aio_nbytes = sizeof(buf),
117 1.3.4.2 perseant .aio_fildes = -1,
118 1.3.4.2 perseant };
119 1.3.4.2 perseant const struct aiocb *const aiolist[] = { &aio };
120 1.3.4.2 perseant
121 1.3.4.2 perseant RL(pipe(fd));
122 1.3.4.2 perseant aio.aio_fildes = fd[0];
123 1.3.4.2 perseant RL(aio_read(&aio));
124 1.3.4.2 perseant cancelpointready();
125 1.3.4.2 perseant RL(aio_suspend(aiolist, __arraycount(aiolist), NULL));
126 1.3.4.2 perseant }
127 1.3.4.2 perseant
128 1.3.4.2 perseant static void
129 1.3.4.2 perseant cancelpoint_compat50_kevent(void)
130 1.3.4.2 perseant {
131 1.3.4.2 perseant int kq;
132 1.3.4.2 perseant struct kevent100 ev;
133 1.3.4.2 perseant
134 1.3.4.2 perseant memset(&ev, 0, sizeof(ev));
135 1.3.4.2 perseant ev.ident = SIGUSR1;
136 1.3.4.2 perseant ev.filter = EVFILT_SIGNAL;
137 1.3.4.2 perseant ev.flags = EV_ADD|EV_ENABLE;
138 1.3.4.2 perseant ev.fflags = 0;
139 1.3.4.2 perseant ev.data = 0;
140 1.3.4.2 perseant ev.udata = 0;
141 1.3.4.2 perseant
142 1.3.4.2 perseant RL(kq = kqueue());
143 1.3.4.2 perseant RL(kevent(kq, &ev, 1, NULL, 1, &(const struct timespec50){0,0}));
144 1.3.4.2 perseant cancelpointready();
145 1.3.4.2 perseant RL(kevent(kq, NULL, 0, &ev, 1, NULL));
146 1.3.4.2 perseant }
147 1.3.4.2 perseant
148 1.3.4.2 perseant static void
149 1.3.4.2 perseant cancelpoint_compat50_mq_timedreceive(void)
150 1.3.4.2 perseant {
151 1.3.4.2 perseant mqd_t mq;
152 1.3.4.2 perseant char buf[32];
153 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
154 1.3.4.2 perseant
155 1.3.4.2 perseant RL(mq = mq_open("mq", O_RDWR|O_CREAT, 0666, NULL));
156 1.3.4.2 perseant cancelpointready();
157 1.3.4.2 perseant RL(mq_timedreceive(mq, buf, sizeof(buf), NULL, &t));
158 1.3.4.2 perseant }
159 1.3.4.2 perseant
160 1.3.4.2 perseant static void
161 1.3.4.2 perseant cancelpoint_compat50_mq_timedsend(void)
162 1.3.4.2 perseant {
163 1.3.4.2 perseant mqd_t mq;
164 1.3.4.2 perseant char buf[32] = {0};
165 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
166 1.3.4.2 perseant
167 1.3.4.2 perseant RL(mq = mq_open("mq", O_RDWR|O_CREAT, 0666, NULL));
168 1.3.4.2 perseant cancelpointready();
169 1.3.4.2 perseant RL(mq_timedsend(mq, buf, sizeof(buf), 0, &t));
170 1.3.4.2 perseant }
171 1.3.4.2 perseant
172 1.3.4.2 perseant static void
173 1.3.4.2 perseant cancelpoint_compat50_nanosleep(void)
174 1.3.4.2 perseant {
175 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
176 1.3.4.2 perseant
177 1.3.4.2 perseant cancelpointready();
178 1.3.4.2 perseant RL(nanosleep(&t, NULL));
179 1.3.4.2 perseant }
180 1.3.4.2 perseant
181 1.3.4.2 perseant static void
182 1.3.4.2 perseant cancelpoint_compat50_pollts(void)
183 1.3.4.2 perseant {
184 1.3.4.2 perseant int fd[2];
185 1.3.4.2 perseant struct pollfd pfd;
186 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
187 1.3.4.2 perseant
188 1.3.4.2 perseant RL(pipe(fd));
189 1.3.4.2 perseant pfd.fd = fd[0];
190 1.3.4.2 perseant pfd.events = POLLIN;
191 1.3.4.2 perseant cancelpointready();
192 1.3.4.2 perseant RL(pollts(&pfd, 1, &t, NULL));
193 1.3.4.2 perseant }
194 1.3.4.2 perseant
195 1.3.4.2 perseant static void
196 1.3.4.2 perseant cancelpoint_compat50_pselect(void)
197 1.3.4.2 perseant {
198 1.3.4.2 perseant int fd[2];
199 1.3.4.2 perseant fd_set readfd;
200 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
201 1.3.4.2 perseant
202 1.3.4.2 perseant FD_ZERO(&readfd);
203 1.3.4.2 perseant
204 1.3.4.2 perseant RL(pipe(fd));
205 1.3.4.2 perseant FD_SET(fd[0], &readfd);
206 1.3.4.2 perseant cancelpointready();
207 1.3.4.2 perseant RL(pselect(fd[0] + 1, &readfd, NULL, NULL, &t, NULL));
208 1.3.4.2 perseant }
209 1.3.4.2 perseant
210 1.3.4.2 perseant static void
211 1.3.4.2 perseant cancelpoint_compat50_select(void)
212 1.3.4.2 perseant {
213 1.3.4.2 perseant int fd[2];
214 1.3.4.2 perseant fd_set readfd;
215 1.3.4.2 perseant struct timeval50 t = {.tv_sec = 1, .tv_usec = 0};
216 1.3.4.2 perseant
217 1.3.4.2 perseant FD_ZERO(&readfd);
218 1.3.4.2 perseant
219 1.3.4.2 perseant RL(pipe(fd));
220 1.3.4.2 perseant FD_SET(fd[0], &readfd);
221 1.3.4.2 perseant cancelpointready();
222 1.3.4.2 perseant RL(select(fd[0] + 1, &readfd, NULL, NULL, &t));
223 1.3.4.2 perseant }
224 1.3.4.2 perseant
225 1.3.4.2 perseant static void
226 1.3.4.2 perseant cancelpoint_compat13_sigsuspend(void)
227 1.3.4.2 perseant {
228 1.3.4.2 perseant sigset13_t mask, omask;
229 1.3.4.2 perseant
230 1.3.4.2 perseant RL(sigfillset(&mask));
231 1.3.4.2 perseant RL(sigprocmask(SIG_BLOCK, &mask, &omask));
232 1.3.4.2 perseant cancelpointready();
233 1.3.4.2 perseant RL(sigsuspend(&omask));
234 1.3.4.2 perseant }
235 1.3.4.2 perseant
236 1.3.4.2 perseant static void
237 1.3.4.2 perseant cancelpoint_compat50_sigtimedwait(void)
238 1.3.4.2 perseant {
239 1.3.4.2 perseant sigset_t mask, omask;
240 1.3.4.2 perseant siginfo_t info;
241 1.3.4.2 perseant struct timespec50 t = {.tv_sec = 2, .tv_nsec = 0};
242 1.3.4.2 perseant
243 1.3.4.2 perseant RL(__sigfillset14(&mask));
244 1.3.4.2 perseant RL(__sigprocmask14(SIG_BLOCK, &mask, &omask));
245 1.3.4.2 perseant cancelpointready();
246 1.3.4.2 perseant RL(sigtimedwait(&omask, &info, &t));
247 1.3.4.2 perseant }
248 1.3.4.2 perseant
249 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat100_kevent, __nothing)
250 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat12_msync, __nothing)
251 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat13_sigsuspend,
252 1.3.4.2 perseant atf_tc_expect_signal(-1, "PR lib/59240: POSIX.1-2024:"
253 1.3.4.2 perseant " cancellation point audit"))
254 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50___sigtimedwait,
255 1.3.4.2 perseant atf_tc_expect_signal(-1, "PR lib/59240: POSIX.1-2024:"
256 1.3.4.2 perseant " cancellation point audit"))
257 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_aio_suspend, __nothing)
258 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_kevent, __nothing)
259 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_mq_timedreceive, __nothing)
260 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_mq_timedsend, __nothing)
261 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_nanosleep, __nothing)
262 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_pollts, __nothing)
263 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_pselect, __nothing)
264 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_select, __nothing)
265 1.3.4.2 perseant TEST_CANCELPOINT(cancelpoint_compat50_sigtimedwait,
266 1.3.4.2 perseant atf_tc_expect_signal(-1, "PR lib/59240: POSIX.1-2024:"
267 1.3.4.2 perseant " cancellation point audit"))
268 1.3.4.2 perseant
269 1.3.4.2 perseant ATF_TP_ADD_TCS(tp)
270 1.3.4.2 perseant {
271 1.3.4.2 perseant
272 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat100_kevent);
273 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat12_msync);
274 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat13_sigsuspend);
275 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50___sigtimedwait);
276 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_aio_suspend);
277 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_kevent);
278 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_mq_timedreceive);
279 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_mq_timedsend);
280 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_nanosleep);
281 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_pollts);
282 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_pselect);
283 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_select);
284 1.3.4.2 perseant ADD_TEST_CANCELPOINT(cancelpoint_compat50_sigtimedwait);
285 1.3.4.2 perseant
286 1.3.4.2 perseant return atf_no_error();
287 1.3.4.2 perseant }
288