]>
Commit | Line | Data |
---|---|---|
d614a753 | 1 | /* Copyright (C) 2002-2020 Free Software Foundation, Inc. |
76a50749 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
76a50749 UD |
18 | |
19 | /* NOTE: this tests functionality beyond POSIX. POSIX does not allow | |
20 | exit to be called more than once. */ | |
21 | ||
39906a3e ZW |
22 | #include <errno.h> |
23 | #include <fcntl.h> | |
24 | #include <limits.h> | |
25 | #include <pthread.h> | |
26 | #include <signal.h> | |
ceaa9889 | 27 | #include <stddef.h> |
76a50749 UD |
28 | #include <stdio.h> |
29 | #include <stdlib.h> | |
30 | #include <string.h> | |
b39b6e0c | 31 | #include <termios.h> |
39906a3e ZW |
32 | #include <unistd.h> |
33 | #include <sys/ipc.h> | |
047aec8f | 34 | #include <sys/mman.h> |
39906a3e | 35 | #include <sys/msg.h> |
76a50749 | 36 | #include <sys/poll.h> |
39906a3e ZW |
37 | #include <sys/select.h> |
38 | #include <sys/socket.h> | |
ceaa9889 | 39 | #include <sys/stat.h> |
39906a3e | 40 | #include <sys/types.h> |
9fe3c80c | 41 | #include <sys/uio.h> |
39906a3e ZW |
42 | #include <sys/un.h> |
43 | #include <sys/wait.h> | |
76a50749 | 44 | |
26676450 | 45 | |
f23b30e2 UD |
46 | /* Since STREAMS are not supported in the standard Linux kernel and |
47 | there we don't advertise STREAMS as supported is no need to test | |
48 | the STREAMS related functions. This affects | |
26676450 UD |
49 | getmsg() getpmsg() putmsg() |
50 | putpmsg() | |
51 | ||
52 | lockf() and fcntl() are tested in tst-cancel16. | |
53 | ||
54 | pthread_join() is tested in tst-join5. | |
55 | ||
56 | pthread_testcancel()'s only purpose is to allow cancellation. This | |
57 | is tested in several places. | |
58 | ||
59 | sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests. | |
60 | ||
1683daeb UD |
61 | mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked |
62 | in tst-mqueue8{,x} tests. | |
f23b30e2 UD |
63 | |
64 | aio_suspend() is tested in tst-cancel17. | |
65 | ||
66 | clock_nanosleep() is tested in tst-cancel18. | |
76a50749 | 67 | |
b39b6e0c AZ |
68 | Linux sendmmsg and recvmmsg are checked in tst-cancel4_1.c and |
69 | tst-cancel4_2.c respectively. | |
70 | */ | |
76a50749 | 71 | |
b39b6e0c | 72 | #include "tst-cancel4-common.h" |
76a50749 | 73 | |
2918b0d0 | 74 | |
483e95d0 UD |
75 | #ifndef IPC_ADDVAL |
76 | # define IPC_ADDVAL 0 | |
77 | #endif | |
78 | ||
483e95d0 | 79 | |
76a50749 UD |
80 | static void * |
81 | tf_read (void *arg) | |
82 | { | |
26676450 | 83 | int fd; |
26676450 UD |
84 | |
85 | if (arg == NULL) | |
86 | fd = fds[0]; | |
87 | else | |
88 | { | |
89 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
90 | tempfd = fd = mkstemp (fname); | |
91 | if (fd == -1) | |
fa66f341 | 92 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
93 | unlink (fname); |
94 | ||
fa66f341 | 95 | xpthread_barrier_wait (&b2); |
26676450 UD |
96 | } |
97 | ||
fa66f341 | 98 | xpthread_barrier_wait (&b2); |
76a50749 | 99 | |
f23b30e2 | 100 | ssize_t s; |
0e0deb03 UD |
101 | pthread_cleanup_push (cl, NULL); |
102 | ||
76a50749 | 103 | char buf[100]; |
f23b30e2 | 104 | s = read (fd, buf, sizeof (buf)); |
76a50749 | 105 | |
0e0deb03 UD |
106 | pthread_cleanup_pop (0); |
107 | ||
fa66f341 | 108 | FAIL_EXIT1 ("read returns with %zd", s); |
76a50749 UD |
109 | } |
110 | ||
111 | ||
112 | static void * | |
113 | tf_readv (void *arg) | |
114 | { | |
26676450 | 115 | int fd; |
26676450 UD |
116 | |
117 | if (arg == NULL) | |
118 | fd = fds[0]; | |
119 | else | |
120 | { | |
121 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
122 | tempfd = fd = mkstemp (fname); | |
123 | if (fd == -1) | |
fa66f341 | 124 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
125 | unlink (fname); |
126 | ||
fa66f341 | 127 | xpthread_barrier_wait (&b2); |
26676450 UD |
128 | } |
129 | ||
fa66f341 | 130 | xpthread_barrier_wait (&b2); |
76a50749 | 131 | |
f23b30e2 | 132 | ssize_t s; |
0e0deb03 UD |
133 | pthread_cleanup_push (cl, NULL); |
134 | ||
76a50749 UD |
135 | char buf[100]; |
136 | struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; | |
f23b30e2 | 137 | s = readv (fd, iov, 1); |
76a50749 | 138 | |
0e0deb03 UD |
139 | pthread_cleanup_pop (0); |
140 | ||
fa66f341 | 141 | FAIL_EXIT1 ("readv returns with %zd", s); |
76a50749 UD |
142 | } |
143 | ||
144 | ||
145 | static void * | |
146 | tf_write (void *arg) | |
147 | { | |
26676450 | 148 | int fd; |
26676450 UD |
149 | |
150 | if (arg == NULL) | |
151 | fd = fds[1]; | |
152 | else | |
153 | { | |
154 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
155 | tempfd = fd = mkstemp (fname); | |
156 | if (fd == -1) | |
fa66f341 | 157 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
158 | unlink (fname); |
159 | ||
fa66f341 | 160 | xpthread_barrier_wait (&b2); |
26676450 UD |
161 | } |
162 | ||
fa66f341 | 163 | xpthread_barrier_wait (&b2); |
76a50749 | 164 | |
f23b30e2 | 165 | ssize_t s; |
0e0deb03 UD |
166 | pthread_cleanup_push (cl, NULL); |
167 | ||
8074c5c5 | 168 | char buf[WRITE_BUFFER_SIZE]; |
76a50749 | 169 | memset (buf, '\0', sizeof (buf)); |
f23b30e2 | 170 | s = write (fd, buf, sizeof (buf)); |
d0d7f85f AZ |
171 | /* The write can return a value higher than 0 (meaning partial write) |
172 | due to the SIGCANCEL, but the thread may still be pending | |
173 | cancellation. */ | |
174 | pthread_testcancel (); | |
76a50749 | 175 | |
0e0deb03 UD |
176 | pthread_cleanup_pop (0); |
177 | ||
fa66f341 | 178 | FAIL_EXIT1 ("write returns with %zd", s); |
76a50749 UD |
179 | } |
180 | ||
181 | ||
182 | static void * | |
183 | tf_writev (void *arg) | |
184 | { | |
26676450 | 185 | int fd; |
26676450 UD |
186 | |
187 | if (arg == NULL) | |
188 | fd = fds[1]; | |
189 | else | |
190 | { | |
191 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
192 | tempfd = fd = mkstemp (fname); | |
193 | if (fd == -1) | |
fa66f341 | 194 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
195 | unlink (fname); |
196 | ||
fa66f341 | 197 | xpthread_barrier_wait (&b2); |
26676450 UD |
198 | } |
199 | ||
fa66f341 | 200 | xpthread_barrier_wait (&b2); |
76a50749 | 201 | |
f23b30e2 | 202 | ssize_t s; |
0e0deb03 UD |
203 | pthread_cleanup_push (cl, NULL); |
204 | ||
8074c5c5 | 205 | char buf[WRITE_BUFFER_SIZE]; |
76a50749 UD |
206 | memset (buf, '\0', sizeof (buf)); |
207 | struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; | |
f23b30e2 | 208 | s = writev (fd, iov, 1); |
76a50749 | 209 | |
0e0deb03 UD |
210 | pthread_cleanup_pop (0); |
211 | ||
fa66f341 | 212 | FAIL_EXIT1 ("writev returns with %zd", s); |
76a50749 UD |
213 | } |
214 | ||
215 | ||
216 | static void * | |
217 | tf_sleep (void *arg) | |
218 | { | |
fa66f341 | 219 | xpthread_barrier_wait (&b2); |
76a50749 | 220 | |
26676450 | 221 | if (arg != NULL) |
fa66f341 | 222 | xpthread_barrier_wait (&b2); |
26676450 | 223 | |
0e0deb03 UD |
224 | pthread_cleanup_push (cl, NULL); |
225 | ||
26676450 | 226 | sleep (arg == NULL ? 1000000 : 0); |
76a50749 | 227 | |
0e0deb03 UD |
228 | pthread_cleanup_pop (0); |
229 | ||
fa66f341 | 230 | FAIL_EXIT1 ("sleep returns"); |
76a50749 UD |
231 | } |
232 | ||
233 | ||
234 | static void * | |
235 | tf_usleep (void *arg) | |
236 | { | |
fa66f341 | 237 | xpthread_barrier_wait (&b2); |
76a50749 | 238 | |
26676450 | 239 | if (arg != NULL) |
fa66f341 | 240 | xpthread_barrier_wait (&b2); |
26676450 | 241 | |
0e0deb03 UD |
242 | pthread_cleanup_push (cl, NULL); |
243 | ||
26676450 | 244 | usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0); |
76a50749 | 245 | |
0e0deb03 UD |
246 | pthread_cleanup_pop (0); |
247 | ||
fa66f341 | 248 | FAIL_EXIT1 ("usleep returns"); |
76a50749 UD |
249 | } |
250 | ||
251 | ||
252 | static void * | |
253 | tf_nanosleep (void *arg) | |
254 | { | |
fa66f341 | 255 | xpthread_barrier_wait (&b2); |
76a50749 | 256 | |
26676450 | 257 | if (arg != NULL) |
fa66f341 | 258 | xpthread_barrier_wait (&b2); |
26676450 | 259 | |
0e0deb03 UD |
260 | pthread_cleanup_push (cl, NULL); |
261 | ||
26676450 | 262 | struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 }; |
f23b30e2 | 263 | TEMP_FAILURE_RETRY (nanosleep (&ts, &ts)); |
76a50749 | 264 | |
0e0deb03 UD |
265 | pthread_cleanup_pop (0); |
266 | ||
fa66f341 | 267 | FAIL_EXIT1 ("nanosleep returns"); |
76a50749 UD |
268 | } |
269 | ||
270 | ||
271 | static void * | |
272 | tf_select (void *arg) | |
273 | { | |
26676450 | 274 | int fd; |
26676450 UD |
275 | |
276 | if (arg == NULL) | |
277 | fd = fds[0]; | |
278 | else | |
279 | { | |
280 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
281 | tempfd = fd = mkstemp (fname); | |
282 | if (fd == -1) | |
fa66f341 | 283 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
284 | unlink (fname); |
285 | ||
fa66f341 | 286 | xpthread_barrier_wait (&b2); |
26676450 UD |
287 | } |
288 | ||
fa66f341 | 289 | xpthread_barrier_wait (&b2); |
76a50749 UD |
290 | |
291 | fd_set rfs; | |
292 | FD_ZERO (&rfs); | |
26676450 | 293 | FD_SET (fd, &rfs); |
76a50749 | 294 | |
f23b30e2 | 295 | int s; |
0e0deb03 UD |
296 | pthread_cleanup_push (cl, NULL); |
297 | ||
f23b30e2 UD |
298 | s = select (fd + 1, &rfs, NULL, NULL, NULL); |
299 | ||
300 | pthread_cleanup_pop (0); | |
76a50749 | 301 | |
fa66f341 | 302 | FAIL_EXIT1 ("select returns with %d: %m", s); |
76a50749 UD |
303 | } |
304 | ||
305 | ||
306 | static void * | |
307 | tf_pselect (void *arg) | |
308 | { | |
26676450 | 309 | int fd; |
26676450 UD |
310 | |
311 | if (arg == NULL) | |
312 | fd = fds[0]; | |
313 | else | |
314 | { | |
315 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
316 | tempfd = fd = mkstemp (fname); | |
317 | if (fd == -1) | |
fa66f341 | 318 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
319 | unlink (fname); |
320 | ||
fa66f341 | 321 | xpthread_barrier_wait (&b2); |
26676450 UD |
322 | } |
323 | ||
fa66f341 | 324 | xpthread_barrier_wait (&b2); |
76a50749 UD |
325 | |
326 | fd_set rfs; | |
327 | FD_ZERO (&rfs); | |
26676450 | 328 | FD_SET (fd, &rfs); |
76a50749 | 329 | |
f23b30e2 | 330 | int s; |
0e0deb03 UD |
331 | pthread_cleanup_push (cl, NULL); |
332 | ||
f23b30e2 UD |
333 | s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL); |
334 | ||
335 | pthread_cleanup_pop (0); | |
76a50749 | 336 | |
fa66f341 | 337 | FAIL_EXIT1 ("pselect returns with %d: %m", s); |
76a50749 UD |
338 | } |
339 | ||
340 | ||
341 | static void * | |
342 | tf_poll (void *arg) | |
343 | { | |
26676450 | 344 | int fd; |
26676450 UD |
345 | |
346 | if (arg == NULL) | |
347 | fd = fds[0]; | |
348 | else | |
349 | { | |
350 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
351 | tempfd = fd = mkstemp (fname); | |
352 | if (fd == -1) | |
fa66f341 | 353 | FAIL_EXIT1 ("mkstemp failed: %m"); |
26676450 UD |
354 | unlink (fname); |
355 | ||
fa66f341 | 356 | xpthread_barrier_wait (&b2); |
26676450 UD |
357 | } |
358 | ||
fa66f341 | 359 | xpthread_barrier_wait (&b2); |
76a50749 | 360 | |
26676450 | 361 | struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } }; |
76a50749 | 362 | |
f23b30e2 | 363 | int s; |
0e0deb03 UD |
364 | pthread_cleanup_push (cl, NULL); |
365 | ||
f23b30e2 UD |
366 | s = poll (rfs, 1, -1); |
367 | ||
368 | pthread_cleanup_pop (0); | |
76a50749 | 369 | |
fa66f341 | 370 | FAIL_EXIT1 ("poll returns with %d: %m", s); |
76a50749 UD |
371 | } |
372 | ||
373 | ||
7c65e900 UD |
374 | static void * |
375 | tf_ppoll (void *arg) | |
376 | { | |
377 | int fd; | |
7c65e900 UD |
378 | |
379 | if (arg == NULL) | |
380 | fd = fds[0]; | |
381 | else | |
382 | { | |
383 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
384 | tempfd = fd = mkstemp (fname); | |
385 | if (fd == -1) | |
fa66f341 | 386 | FAIL_EXIT1 ("mkstemp failed: %m"); |
7c65e900 UD |
387 | unlink (fname); |
388 | ||
fa66f341 | 389 | xpthread_barrier_wait (&b2); |
7c65e900 UD |
390 | } |
391 | ||
fa66f341 | 392 | xpthread_barrier_wait (&b2); |
7c65e900 UD |
393 | |
394 | struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } }; | |
395 | ||
396 | int s; | |
397 | pthread_cleanup_push (cl, NULL); | |
398 | ||
399 | s = ppoll (rfs, 1, NULL, NULL); | |
400 | ||
401 | pthread_cleanup_pop (0); | |
402 | ||
fa66f341 | 403 | FAIL_EXIT1 ("ppoll returns with %d: %m", s); |
7c65e900 UD |
404 | } |
405 | ||
406 | ||
76a50749 UD |
407 | static void * |
408 | tf_wait (void *arg) | |
409 | { | |
76a50749 UD |
410 | pid_t pid = fork (); |
411 | if (pid == -1) | |
fa66f341 | 412 | FAIL_EXIT1 ("fork: %m"); |
76a50749 UD |
413 | |
414 | if (pid == 0) | |
415 | { | |
416 | /* Make the program disappear after a while. */ | |
26676450 UD |
417 | if (arg == NULL) |
418 | sleep (10); | |
76a50749 UD |
419 | exit (0); |
420 | } | |
421 | ||
26676450 UD |
422 | if (arg != NULL) |
423 | { | |
424 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 }; | |
425 | while (nanosleep (&ts, &ts) != 0) | |
426 | continue; | |
427 | ||
fa66f341 | 428 | xpthread_barrier_wait (&b2); |
26676450 UD |
429 | } |
430 | ||
fa66f341 | 431 | xpthread_barrier_wait (&b2); |
26676450 | 432 | |
f23b30e2 | 433 | int s; |
0e0deb03 UD |
434 | pthread_cleanup_push (cl, NULL); |
435 | ||
f23b30e2 UD |
436 | s = wait (NULL); |
437 | ||
438 | pthread_cleanup_pop (0); | |
76a50749 | 439 | |
fa66f341 | 440 | FAIL_EXIT1 ("wait returns with %d: %m", s); |
76a50749 UD |
441 | } |
442 | ||
443 | ||
444 | static void * | |
445 | tf_waitpid (void *arg) | |
446 | { | |
76a50749 UD |
447 | pid_t pid = fork (); |
448 | if (pid == -1) | |
fa66f341 | 449 | FAIL_EXIT1 ("fork: %m"); |
76a50749 UD |
450 | |
451 | if (pid == 0) | |
452 | { | |
453 | /* Make the program disappear after a while. */ | |
26676450 UD |
454 | if (arg == NULL) |
455 | sleep (10); | |
76a50749 UD |
456 | exit (0); |
457 | } | |
458 | ||
26676450 UD |
459 | if (arg != NULL) |
460 | { | |
461 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 }; | |
462 | while (nanosleep (&ts, &ts) != 0) | |
463 | continue; | |
464 | ||
fa66f341 | 465 | xpthread_barrier_wait (&b2); |
26676450 UD |
466 | } |
467 | ||
fa66f341 | 468 | xpthread_barrier_wait (&b2); |
26676450 | 469 | |
f23b30e2 | 470 | int s; |
fa66f341 | 471 | pthread_cleanup_push (cl, NULL); |
0e0deb03 | 472 | |
f23b30e2 UD |
473 | s = waitpid (-1, NULL, 0); |
474 | ||
475 | pthread_cleanup_pop (0); | |
76a50749 | 476 | |
fa66f341 | 477 | FAIL_EXIT1 ("waitpid returns with %d: %m", s); |
76a50749 UD |
478 | } |
479 | ||
480 | ||
481 | static void * | |
482 | tf_waitid (void *arg) | |
483 | { | |
76a50749 UD |
484 | pid_t pid = fork (); |
485 | if (pid == -1) | |
fa66f341 | 486 | FAIL_EXIT1 ("fork: %m"); |
76a50749 UD |
487 | |
488 | if (pid == 0) | |
489 | { | |
490 | /* Make the program disappear after a while. */ | |
26676450 UD |
491 | if (arg == NULL) |
492 | sleep (10); | |
76a50749 UD |
493 | exit (0); |
494 | } | |
495 | ||
26676450 UD |
496 | if (arg != NULL) |
497 | { | |
498 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 }; | |
499 | while (nanosleep (&ts, &ts) != 0) | |
500 | continue; | |
501 | ||
fa66f341 | 502 | xpthread_barrier_wait (&b2); |
26676450 UD |
503 | } |
504 | ||
fa66f341 | 505 | xpthread_barrier_wait (&b2); |
26676450 | 506 | |
f23b30e2 | 507 | int s; |
0e0deb03 UD |
508 | pthread_cleanup_push (cl, NULL); |
509 | ||
4fb907b7 RM |
510 | #ifndef WEXITED |
511 | # define WEXITED 0 | |
512 | #endif | |
76a50749 | 513 | siginfo_t si; |
4fb907b7 | 514 | s = waitid (P_PID, pid, &si, WEXITED); |
f23b30e2 UD |
515 | |
516 | pthread_cleanup_pop (0); | |
76a50749 | 517 | |
fa66f341 | 518 | FAIL_EXIT1 ("waitid returns with %d: %m", s); |
76a50749 UD |
519 | } |
520 | ||
521 | ||
26676450 UD |
522 | static void * |
523 | tf_sigpause (void *arg) | |
76a50749 | 524 | { |
fa66f341 | 525 | xpthread_barrier_wait (&b2); |
76a50749 | 526 | |
26676450 | 527 | if (arg != NULL) |
fa66f341 | 528 | xpthread_barrier_wait (&b2); |
76a50749 | 529 | |
26676450 | 530 | pthread_cleanup_push (cl, NULL); |
0e0deb03 | 531 | |
2918b0d0 | 532 | sigpause (sigmask (SIGINT)); |
76a50749 | 533 | |
26676450 UD |
534 | pthread_cleanup_pop (0); |
535 | ||
fa66f341 | 536 | FAIL_EXIT1 ("sigpause returned"); |
26676450 UD |
537 | } |
538 | ||
539 | ||
540 | static void * | |
541 | tf_sigsuspend (void *arg) | |
542 | { | |
fa66f341 | 543 | xpthread_barrier_wait (&b2); |
26676450 UD |
544 | |
545 | if (arg != NULL) | |
fa66f341 | 546 | xpthread_barrier_wait (&b2); |
76a50749 | 547 | |
26676450 | 548 | pthread_cleanup_push (cl, NULL); |
76a50749 | 549 | |
26676450 UD |
550 | /* Just for fun block all signals. */ |
551 | sigset_t mask; | |
552 | sigfillset (&mask); | |
553 | sigsuspend (&mask); | |
76a50749 | 554 | |
26676450 UD |
555 | pthread_cleanup_pop (0); |
556 | ||
fa66f341 | 557 | FAIL_EXIT1 ("sigsuspend returned"); |
26676450 UD |
558 | } |
559 | ||
560 | ||
561 | static void * | |
562 | tf_sigwait (void *arg) | |
563 | { | |
fa66f341 | 564 | xpthread_barrier_wait (&b2); |
26676450 UD |
565 | |
566 | if (arg != NULL) | |
fa66f341 | 567 | xpthread_barrier_wait (&b2); |
26676450 | 568 | |
26676450 UD |
569 | /* Block SIGUSR1. */ |
570 | sigset_t mask; | |
97b6614c | 571 | sigemptyset (&mask); |
26676450 | 572 | sigaddset (&mask, SIGUSR1); |
fa66f341 | 573 | TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0); |
26676450 | 574 | |
26676450 | 575 | int sig; |
f23b30e2 | 576 | pthread_cleanup_push (cl, NULL); |
26676450 | 577 | |
f23b30e2 UD |
578 | /* Wait for SIGUSR1. */ |
579 | sigwait (&mask, &sig); | |
26676450 UD |
580 | |
581 | pthread_cleanup_pop (0); | |
582 | ||
fa66f341 | 583 | FAIL_EXIT1 ("sigwait returned with signal %d", sig); |
26676450 UD |
584 | } |
585 | ||
586 | ||
587 | static void * | |
588 | tf_sigwaitinfo (void *arg) | |
589 | { | |
fa66f341 | 590 | xpthread_barrier_wait (&b2); |
26676450 UD |
591 | |
592 | if (arg != NULL) | |
fa66f341 | 593 | xpthread_barrier_wait (&b2); |
26676450 | 594 | |
26676450 UD |
595 | /* Block SIGUSR1. */ |
596 | sigset_t mask; | |
97b6614c | 597 | sigemptyset (&mask); |
26676450 | 598 | sigaddset (&mask, SIGUSR1); |
fa66f341 | 599 | TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0); |
26676450 | 600 | |
26676450 | 601 | siginfo_t info; |
f23b30e2 UD |
602 | pthread_cleanup_push (cl, NULL); |
603 | ||
604 | /* Wait for SIGUSR1. */ | |
26676450 UD |
605 | sigwaitinfo (&mask, &info); |
606 | ||
f23b30e2 UD |
607 | pthread_cleanup_pop (0); |
608 | ||
fa66f341 | 609 | FAIL_EXIT1 ("sigwaitinfo returned with signal %d", info.si_signo); |
26676450 UD |
610 | } |
611 | ||
612 | ||
613 | static void * | |
614 | tf_sigtimedwait (void *arg) | |
615 | { | |
fa66f341 | 616 | xpthread_barrier_wait (&b2); |
26676450 UD |
617 | |
618 | if (arg != NULL) | |
fa66f341 | 619 | xpthread_barrier_wait (&b2); |
26676450 | 620 | |
26676450 UD |
621 | /* Block SIGUSR1. */ |
622 | sigset_t mask; | |
97b6614c | 623 | sigemptyset (&mask); |
26676450 | 624 | sigaddset (&mask, SIGUSR1); |
fa66f341 | 625 | TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0); |
26676450 UD |
626 | |
627 | /* Wait for SIGUSR1. */ | |
628 | siginfo_t info; | |
629 | struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 }; | |
f23b30e2 UD |
630 | pthread_cleanup_push (cl, NULL); |
631 | ||
26676450 UD |
632 | sigtimedwait (&mask, &info, &ts); |
633 | ||
f23b30e2 UD |
634 | pthread_cleanup_pop (0); |
635 | ||
fa66f341 | 636 | FAIL_EXIT1 ("sigtimedwait returned with signal %d", info.si_signo); |
26676450 UD |
637 | } |
638 | ||
639 | ||
640 | static void * | |
641 | tf_pause (void *arg) | |
642 | { | |
fa66f341 | 643 | xpthread_barrier_wait (&b2); |
26676450 UD |
644 | |
645 | if (arg != NULL) | |
fa66f341 | 646 | xpthread_barrier_wait (&b2); |
26676450 UD |
647 | |
648 | pthread_cleanup_push (cl, NULL); | |
649 | ||
650 | pause (); | |
651 | ||
652 | pthread_cleanup_pop (0); | |
653 | ||
fa66f341 | 654 | FAIL_EXIT1 ("pause returned"); |
26676450 UD |
655 | } |
656 | ||
657 | ||
658 | static void * | |
659 | tf_accept (void *arg) | |
660 | { | |
661 | struct sockaddr_un sun; | |
662 | /* To test a non-blocking accept call we make the call file by using | |
663 | a datagrame socket. */ | |
664 | int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM; | |
665 | ||
666 | tempfd = socket (AF_UNIX, pf, 0); | |
667 | if (tempfd == -1) | |
fa66f341 AZ |
668 | FAIL_EXIT1 ("socket (AF_UNIX, %s, 0): %m", arg == NULL ? "SOCK_STREAM" |
669 | : "SOCK_DGRAM"); | |
26676450 UD |
670 | |
671 | int tries = 0; | |
672 | do | |
673 | { | |
fa66f341 | 674 | TEST_VERIFY_EXIT (tries++ < 10); |
26676450 | 675 | |
f23b30e2 | 676 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX"); |
fa66f341 | 677 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
26676450 UD |
678 | |
679 | sun.sun_family = AF_UNIX; | |
680 | } | |
681 | while (bind (tempfd, (struct sockaddr *) &sun, | |
682 | offsetof (struct sockaddr_un, sun_path) | |
683 | + strlen (sun.sun_path) + 1) != 0); | |
684 | ||
685 | unlink (sun.sun_path); | |
686 | ||
687 | listen (tempfd, 5); | |
688 | ||
689 | socklen_t len = sizeof (sun); | |
690 | ||
fa66f341 | 691 | xpthread_barrier_wait (&b2); |
26676450 UD |
692 | |
693 | if (arg != NULL) | |
fa66f341 | 694 | xpthread_barrier_wait (&b2); |
26676450 UD |
695 | |
696 | pthread_cleanup_push (cl, NULL); | |
697 | ||
698 | accept (tempfd, (struct sockaddr *) &sun, &len); | |
699 | ||
700 | pthread_cleanup_pop (0); | |
701 | ||
fa66f341 | 702 | FAIL_EXIT1 ("accept returned"); |
26676450 UD |
703 | } |
704 | ||
705 | ||
706 | static void * | |
707 | tf_send (void *arg) | |
708 | { | |
709 | struct sockaddr_un sun; | |
710 | ||
711 | tempfd = socket (AF_UNIX, SOCK_STREAM, 0); | |
712 | if (tempfd == -1) | |
fa66f341 | 713 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
26676450 UD |
714 | |
715 | int tries = 0; | |
716 | do | |
717 | { | |
fa66f341 | 718 | TEST_VERIFY_EXIT (tries++ < 10); |
26676450 | 719 | |
f23b30e2 | 720 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX"); |
fa66f341 | 721 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
26676450 UD |
722 | |
723 | sun.sun_family = AF_UNIX; | |
724 | } | |
725 | while (bind (tempfd, (struct sockaddr *) &sun, | |
726 | offsetof (struct sockaddr_un, sun_path) | |
727 | + strlen (sun.sun_path) + 1) != 0); | |
728 | ||
729 | listen (tempfd, 5); | |
730 | ||
731 | tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0); | |
732 | if (tempfd2 == -1) | |
fa66f341 | 733 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
26676450 | 734 | |
fbd01e6c AZ |
735 | set_socket_buffer (tempfd2); |
736 | ||
26676450 | 737 | if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0) |
fa66f341 | 738 | FAIL_EXIT1 ("connect: %m"); |
26676450 UD |
739 | |
740 | unlink (sun.sun_path); | |
741 | ||
fa66f341 | 742 | xpthread_barrier_wait (&b2); |
26676450 UD |
743 | |
744 | if (arg != NULL) | |
fa66f341 | 745 | xpthread_barrier_wait (&b2); |
26676450 UD |
746 | |
747 | pthread_cleanup_push (cl, NULL); | |
748 | ||
fbd01e6c | 749 | char mem[WRITE_BUFFER_SIZE]; |
26676450 UD |
750 | |
751 | send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0); | |
d0d7f85f AZ |
752 | /* The send can return a value higher than 0 (meaning partial send) |
753 | due to the SIGCANCEL, but the thread may still be pending | |
754 | cancellation. */ | |
755 | pthread_testcancel (); | |
26676450 UD |
756 | |
757 | pthread_cleanup_pop (0); | |
758 | ||
fa66f341 | 759 | FAIL_EXIT1 ("send returned"); |
26676450 UD |
760 | } |
761 | ||
762 | ||
763 | static void * | |
764 | tf_recv (void *arg) | |
765 | { | |
766 | struct sockaddr_un sun; | |
767 | ||
768 | tempfd = socket (AF_UNIX, SOCK_STREAM, 0); | |
769 | if (tempfd == -1) | |
fa66f341 | 770 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
26676450 UD |
771 | |
772 | int tries = 0; | |
773 | do | |
774 | { | |
fa66f341 | 775 | TEST_VERIFY_EXIT (tries++ < 10); |
26676450 | 776 | |
f23b30e2 | 777 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX"); |
fa66f341 | 778 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
26676450 UD |
779 | |
780 | sun.sun_family = AF_UNIX; | |
781 | } | |
782 | while (bind (tempfd, (struct sockaddr *) &sun, | |
783 | offsetof (struct sockaddr_un, sun_path) | |
784 | + strlen (sun.sun_path) + 1) != 0); | |
785 | ||
786 | listen (tempfd, 5); | |
787 | ||
788 | tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0); | |
789 | if (tempfd2 == -1) | |
fa66f341 | 790 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
26676450 UD |
791 | |
792 | if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0) | |
fa66f341 | 793 | FAIL_EXIT1 ("connect: %m"); |
26676450 UD |
794 | |
795 | unlink (sun.sun_path); | |
796 | ||
fa66f341 | 797 | xpthread_barrier_wait (&b2); |
26676450 UD |
798 | |
799 | if (arg != NULL) | |
fa66f341 | 800 | xpthread_barrier_wait (&b2); |
26676450 UD |
801 | |
802 | pthread_cleanup_push (cl, NULL); | |
803 | ||
804 | char mem[70]; | |
805 | ||
806 | recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0); | |
807 | ||
808 | pthread_cleanup_pop (0); | |
809 | ||
fa66f341 | 810 | FAIL_EXIT1 ("recv returned"); |
26676450 UD |
811 | } |
812 | ||
813 | ||
814 | static void * | |
815 | tf_recvfrom (void *arg) | |
816 | { | |
817 | struct sockaddr_un sun; | |
818 | ||
819 | tempfd = socket (AF_UNIX, SOCK_DGRAM, 0); | |
820 | if (tempfd == -1) | |
fa66f341 | 821 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m"); |
26676450 UD |
822 | |
823 | int tries = 0; | |
824 | do | |
825 | { | |
fa66f341 | 826 | TEST_VERIFY_EXIT (tries++ < 10); |
26676450 | 827 | |
f23b30e2 | 828 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX"); |
fa66f341 | 829 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
26676450 UD |
830 | |
831 | sun.sun_family = AF_UNIX; | |
832 | } | |
833 | while (bind (tempfd, (struct sockaddr *) &sun, | |
834 | offsetof (struct sockaddr_un, sun_path) | |
835 | + strlen (sun.sun_path) + 1) != 0); | |
836 | ||
837 | tempfname = strdup (sun.sun_path); | |
838 | ||
839 | tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0); | |
840 | if (tempfd2 == -1) | |
fa66f341 | 841 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m"); |
26676450 | 842 | |
fa66f341 | 843 | xpthread_barrier_wait (&b2); |
26676450 UD |
844 | |
845 | if (arg != NULL) | |
fa66f341 | 846 | xpthread_barrier_wait (&b2); |
26676450 UD |
847 | |
848 | pthread_cleanup_push (cl, NULL); | |
849 | ||
850 | char mem[70]; | |
851 | socklen_t len = sizeof (sun); | |
852 | ||
853 | recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0, | |
854 | (struct sockaddr *) &sun, &len); | |
855 | ||
856 | pthread_cleanup_pop (0); | |
857 | ||
fa66f341 | 858 | FAIL_EXIT1 ("recvfrom returned"); |
26676450 UD |
859 | } |
860 | ||
861 | ||
862 | static void * | |
863 | tf_recvmsg (void *arg) | |
864 | { | |
865 | struct sockaddr_un sun; | |
866 | ||
867 | tempfd = socket (AF_UNIX, SOCK_DGRAM, 0); | |
868 | if (tempfd == -1) | |
fa66f341 | 869 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m"); |
26676450 UD |
870 | |
871 | int tries = 0; | |
872 | do | |
873 | { | |
fa66f341 | 874 | TEST_VERIFY_EXIT (tries++ < 10); |
26676450 | 875 | |
f23b30e2 | 876 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX"); |
fa66f341 | 877 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
26676450 UD |
878 | |
879 | sun.sun_family = AF_UNIX; | |
880 | } | |
881 | while (bind (tempfd, (struct sockaddr *) &sun, | |
882 | offsetof (struct sockaddr_un, sun_path) | |
883 | + strlen (sun.sun_path) + 1) != 0); | |
884 | ||
885 | tempfname = strdup (sun.sun_path); | |
886 | ||
887 | tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0); | |
888 | if (tempfd2 == -1) | |
fa66f341 | 889 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m"); |
26676450 | 890 | |
fa66f341 | 891 | xpthread_barrier_wait (&b2); |
26676450 UD |
892 | |
893 | if (arg != NULL) | |
fa66f341 | 894 | xpthread_barrier_wait (&b2); |
26676450 UD |
895 | |
896 | pthread_cleanup_push (cl, NULL); | |
897 | ||
898 | char mem[70]; | |
899 | struct iovec iov[1]; | |
900 | iov[0].iov_base = mem; | |
901 | iov[0].iov_len = arg == NULL ? sizeof (mem) : 0; | |
902 | ||
903 | struct msghdr m; | |
904 | m.msg_name = &sun; | |
905 | m.msg_namelen = sizeof (sun); | |
906 | m.msg_iov = iov; | |
907 | m.msg_iovlen = 1; | |
908 | m.msg_control = NULL; | |
909 | m.msg_controllen = 0; | |
910 | ||
911 | recvmsg (tempfd2, &m, 0); | |
912 | ||
913 | pthread_cleanup_pop (0); | |
914 | ||
fa66f341 | 915 | FAIL_EXIT1 ("recvmsg returned"); |
26676450 UD |
916 | } |
917 | ||
047aec8f UD |
918 | static void * |
919 | tf_open (void *arg) | |
920 | { | |
921 | if (arg == NULL) | |
047aec8f | 922 | { |
2918b0d0 AZ |
923 | fifofd = mkfifo (fifoname, S_IWUSR | S_IRUSR); |
924 | if (fifofd == -1) | |
fa66f341 | 925 | FAIL_EXIT1 ("mkfifo: %m"); |
2918b0d0 AZ |
926 | } |
927 | else | |
928 | { | |
fa66f341 | 929 | xpthread_barrier_wait (&b2); |
047aec8f UD |
930 | } |
931 | ||
fa66f341 | 932 | xpthread_barrier_wait (&b2); |
047aec8f | 933 | |
2918b0d0 | 934 | pthread_cleanup_push (cl_fifo, NULL); |
047aec8f | 935 | |
2918b0d0 | 936 | open (arg ? "Makefile" : fifoname, O_RDONLY); |
047aec8f UD |
937 | |
938 | pthread_cleanup_pop (0); | |
939 | ||
fa66f341 | 940 | FAIL_EXIT1 ("open returned"); |
047aec8f UD |
941 | } |
942 | ||
943 | ||
944 | static void * | |
945 | tf_close (void *arg) | |
946 | { | |
947 | if (arg == NULL) | |
948 | // XXX If somebody can provide a portable test case in which close() | |
949 | // blocks we can enable this test to run in both rounds. | |
950 | abort (); | |
951 | ||
952 | char fname[] = "/tmp/tst-cancel-fd-XXXXXX"; | |
953 | tempfd = mkstemp (fname); | |
954 | if (tempfd == -1) | |
fa66f341 | 955 | FAIL_EXIT1 ("mkstemp failed: %m"); |
047aec8f UD |
956 | unlink (fname); |
957 | ||
fa66f341 | 958 | xpthread_barrier_wait (&b2); |
047aec8f | 959 | |
fa66f341 | 960 | xpthread_barrier_wait (&b2); |
047aec8f UD |
961 | |
962 | pthread_cleanup_push (cl, NULL); | |
963 | ||
964 | close (tempfd); | |
965 | ||
966 | pthread_cleanup_pop (0); | |
967 | ||
fa66f341 | 968 | FAIL_EXIT1 ("close returned"); |
047aec8f UD |
969 | } |
970 | ||
971 | ||
972 | static void * | |
973 | tf_pread (void *arg) | |
974 | { | |
975 | if (arg == NULL) | |
976 | // XXX If somebody can provide a portable test case in which pread() | |
977 | // blocks we can enable this test to run in both rounds. | |
978 | abort (); | |
979 | ||
980 | tempfd = open ("Makefile", O_RDONLY); | |
981 | if (tempfd == -1) | |
fa66f341 | 982 | FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m"); |
047aec8f | 983 | |
fa66f341 | 984 | xpthread_barrier_wait (&b2); |
047aec8f | 985 | |
fa66f341 | 986 | xpthread_barrier_wait (&b2); |
047aec8f UD |
987 | |
988 | pthread_cleanup_push (cl, NULL); | |
989 | ||
990 | char mem[10]; | |
991 | pread (tempfd, mem, sizeof (mem), 0); | |
992 | ||
993 | pthread_cleanup_pop (0); | |
994 | ||
fa66f341 | 995 | FAIL_EXIT1 ("pread returned"); |
047aec8f UD |
996 | } |
997 | ||
998 | ||
999 | static void * | |
1000 | tf_pwrite (void *arg) | |
1001 | { | |
1002 | if (arg == NULL) | |
1003 | // XXX If somebody can provide a portable test case in which pwrite() | |
1004 | // blocks we can enable this test to run in both rounds. | |
1005 | abort (); | |
1006 | ||
1007 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
1008 | tempfd = mkstemp (fname); | |
1009 | if (tempfd == -1) | |
fa66f341 | 1010 | FAIL_EXIT1 ("mkstemp failed: %m"); |
047aec8f UD |
1011 | unlink (fname); |
1012 | ||
fa66f341 | 1013 | xpthread_barrier_wait (&b2); |
047aec8f | 1014 | |
fa66f341 | 1015 | xpthread_barrier_wait (&b2); |
047aec8f UD |
1016 | |
1017 | pthread_cleanup_push (cl, NULL); | |
1018 | ||
1019 | char mem[10]; | |
1020 | pwrite (tempfd, mem, sizeof (mem), 0); | |
1021 | ||
1022 | pthread_cleanup_pop (0); | |
1023 | ||
fa66f341 | 1024 | FAIL_EXIT1 ("pwrite returned"); |
047aec8f UD |
1025 | } |
1026 | ||
4e778151 AZ |
1027 | static void * |
1028 | tf_preadv (void *arg) | |
1029 | { | |
1030 | int fd; | |
4e778151 AZ |
1031 | |
1032 | if (arg == NULL) | |
1033 | /* XXX If somebody can provide a portable test case in which preadv | |
1034 | blocks we can enable this test to run in both rounds. */ | |
1035 | abort (); | |
1036 | ||
1037 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
1038 | tempfd = fd = mkstemp (fname); | |
1039 | if (fd == -1) | |
fa66f341 | 1040 | FAIL_EXIT1 ("mkstemp failed: %m"); |
4e778151 AZ |
1041 | unlink (fname); |
1042 | ||
fa66f341 | 1043 | xpthread_barrier_wait (&b2); |
4e778151 | 1044 | |
fa66f341 | 1045 | xpthread_barrier_wait (&b2); |
4e778151 AZ |
1046 | |
1047 | ssize_t s; | |
1048 | pthread_cleanup_push (cl, NULL); | |
1049 | ||
1050 | char buf[100]; | |
1051 | struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; | |
1052 | s = preadv (fd, iov, 1, 0); | |
1053 | ||
1054 | pthread_cleanup_pop (0); | |
1055 | ||
fa66f341 | 1056 | FAIL_EXIT1 ("preadv returns with %zd", s); |
4e778151 | 1057 | } |
047aec8f | 1058 | |
af5fdf5a AZ |
1059 | static void * |
1060 | tf_pwritev (void *arg) | |
1061 | { | |
1062 | int fd; | |
af5fdf5a AZ |
1063 | |
1064 | if (arg == NULL) | |
1065 | /* XXX If somebody can provide a portable test case in which pwritev | |
1066 | blocks we can enable this test to run in both rounds. */ | |
1067 | abort (); | |
1068 | ||
1069 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
1070 | tempfd = fd = mkstemp (fname); | |
1071 | if (fd == -1) | |
fa66f341 | 1072 | FAIL_EXIT1 ("mkstemp failed: %m"); |
af5fdf5a AZ |
1073 | unlink (fname); |
1074 | ||
fa66f341 | 1075 | xpthread_barrier_wait (&b2); |
af5fdf5a | 1076 | |
fa66f341 | 1077 | xpthread_barrier_wait (&b2); |
af5fdf5a AZ |
1078 | |
1079 | ssize_t s; | |
1080 | pthread_cleanup_push (cl, NULL); | |
1081 | ||
1082 | char buf[WRITE_BUFFER_SIZE]; | |
1083 | memset (buf, '\0', sizeof (buf)); | |
1084 | struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; | |
1085 | s = pwritev (fd, iov, 1, 0); | |
1086 | ||
1087 | pthread_cleanup_pop (0); | |
1088 | ||
fa66f341 | 1089 | FAIL_EXIT1 ("pwritev returns with %zd", s); |
af5fdf5a AZ |
1090 | } |
1091 | ||
52bd9381 AZ |
1092 | static void * |
1093 | tf_pwritev2 (void *arg) | |
1094 | { | |
1095 | int fd; | |
1096 | ||
1097 | if (arg == NULL) | |
1098 | /* XXX If somebody can provide a portable test case in which pwritev2 | |
1099 | blocks we can enable this test to run in both rounds. */ | |
1100 | abort (); | |
1101 | ||
1102 | errno = 0; | |
1103 | ||
1104 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
1105 | tempfd = fd = mkstemp (fname); | |
1106 | if (fd == -1) | |
1107 | FAIL_EXIT1 ("mkstemp: %m"); | |
1108 | unlink (fname); | |
1109 | ||
1110 | xpthread_barrier_wait (&b2); | |
1111 | ||
1112 | xpthread_barrier_wait (&b2); | |
1113 | ||
1114 | ssize_t s; | |
1115 | pthread_cleanup_push (cl, NULL); | |
1116 | ||
1117 | char buf[WRITE_BUFFER_SIZE]; | |
1118 | memset (buf, '\0', sizeof (buf)); | |
1119 | struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; | |
1120 | s = pwritev2 (fd, iov, 1, 0, 0); | |
1121 | ||
1122 | pthread_cleanup_pop (0); | |
1123 | ||
1124 | FAIL_EXIT1 ("pwritev2 returns with %zd", s); | |
1125 | } | |
1126 | ||
1127 | static void * | |
1128 | tf_preadv2 (void *arg) | |
1129 | { | |
1130 | int fd; | |
1131 | ||
1132 | if (arg == NULL) | |
1133 | /* XXX If somebody can provide a portable test case in which preadv2 | |
1134 | blocks we can enable this test to run in both rounds. */ | |
1135 | abort (); | |
1136 | ||
1137 | errno = 0; | |
1138 | ||
1139 | char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; | |
1140 | tempfd = fd = mkstemp (fname); | |
1141 | if (fd == -1) | |
1142 | FAIL_EXIT1 ("mkstemp failed: %m"); | |
1143 | unlink (fname); | |
1144 | ||
1145 | xpthread_barrier_wait (&b2); | |
1146 | ||
1147 | xpthread_barrier_wait (&b2); | |
1148 | ||
1149 | ssize_t s; | |
1150 | pthread_cleanup_push (cl, NULL); | |
1151 | ||
1152 | char buf[100]; | |
1153 | struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; | |
1154 | s = preadv2 (fd, iov, 1, 0, 0); | |
1155 | ||
1156 | pthread_cleanup_pop (0); | |
1157 | ||
1158 | FAIL_EXIT1 ("preadv2 returns with %zd", s); | |
1159 | } | |
1160 | ||
047aec8f UD |
1161 | static void * |
1162 | tf_fsync (void *arg) | |
1163 | { | |
1164 | if (arg == NULL) | |
1165 | // XXX If somebody can provide a portable test case in which fsync() | |
1166 | // blocks we can enable this test to run in both rounds. | |
1167 | abort (); | |
1168 | ||
1169 | tempfd = open ("Makefile", O_RDONLY); | |
1170 | if (tempfd == -1) | |
fa66f341 | 1171 | FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m"); |
047aec8f | 1172 | |
fa66f341 | 1173 | xpthread_barrier_wait (&b2); |
047aec8f | 1174 | |
fa66f341 | 1175 | xpthread_barrier_wait (&b2); |
047aec8f UD |
1176 | |
1177 | pthread_cleanup_push (cl, NULL); | |
1178 | ||
1179 | fsync (tempfd); | |
1180 | ||
1181 | pthread_cleanup_pop (0); | |
1182 | ||
fa66f341 | 1183 | FAIL_EXIT1 ("fsync returned"); |
047aec8f UD |
1184 | } |
1185 | ||
1186 | ||
aa75f64c UD |
1187 | static void * |
1188 | tf_fdatasync (void *arg) | |
1189 | { | |
1190 | if (arg == NULL) | |
1191 | // XXX If somebody can provide a portable test case in which fdatasync() | |
1192 | // blocks we can enable this test to run in both rounds. | |
1193 | abort (); | |
1194 | ||
1195 | tempfd = open ("Makefile", O_RDONLY); | |
1196 | if (tempfd == -1) | |
fa66f341 | 1197 | FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m"); |
aa75f64c | 1198 | |
fa66f341 | 1199 | xpthread_barrier_wait (&b2); |
aa75f64c | 1200 | |
fa66f341 | 1201 | xpthread_barrier_wait (&b2); |
aa75f64c UD |
1202 | |
1203 | pthread_cleanup_push (cl, NULL); | |
1204 | ||
1205 | fdatasync (tempfd); | |
1206 | ||
1207 | pthread_cleanup_pop (0); | |
1208 | ||
fa66f341 | 1209 | FAIL_EXIT1 ("fdatasync returned"); |
aa75f64c UD |
1210 | } |
1211 | ||
1212 | ||
047aec8f UD |
1213 | static void * |
1214 | tf_msync (void *arg) | |
1215 | { | |
1216 | if (arg == NULL) | |
1217 | // XXX If somebody can provide a portable test case in which msync() | |
1218 | // blocks we can enable this test to run in both rounds. | |
1219 | abort (); | |
1220 | ||
1221 | tempfd = open ("Makefile", O_RDONLY); | |
1222 | if (tempfd == -1) | |
fa66f341 | 1223 | FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m"); |
047aec8f | 1224 | |
fa66f341 | 1225 | void *p = xmmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd); |
047aec8f | 1226 | |
fa66f341 AZ |
1227 | xpthread_barrier_wait (&b2); |
1228 | ||
1229 | xpthread_barrier_wait (&b2); | |
047aec8f UD |
1230 | |
1231 | pthread_cleanup_push (cl, NULL); | |
1232 | ||
1233 | msync (p, 10, 0); | |
1234 | ||
1235 | pthread_cleanup_pop (0); | |
1236 | ||
fa66f341 | 1237 | FAIL_EXIT1 ("msync returned"); |
047aec8f UD |
1238 | } |
1239 | ||
1240 | ||
f23b30e2 UD |
1241 | static void * |
1242 | tf_sendto (void *arg) | |
1243 | { | |
f23b30e2 UD |
1244 | struct sockaddr_un sun; |
1245 | ||
fbd01e6c | 1246 | tempfd = socket (AF_UNIX, SOCK_STREAM, 0); |
f23b30e2 | 1247 | if (tempfd == -1) |
fbd01e6c | 1248 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
f23b30e2 UD |
1249 | |
1250 | int tries = 0; | |
1251 | do | |
1252 | { | |
fa66f341 | 1253 | TEST_VERIFY_EXIT (tries++ < 10); |
f23b30e2 UD |
1254 | |
1255 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX"); | |
fa66f341 | 1256 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
f23b30e2 UD |
1257 | |
1258 | sun.sun_family = AF_UNIX; | |
1259 | } | |
1260 | while (bind (tempfd, (struct sockaddr *) &sun, | |
1261 | offsetof (struct sockaddr_un, sun_path) | |
1262 | + strlen (sun.sun_path) + 1) != 0); | |
f23b30e2 | 1263 | |
fbd01e6c AZ |
1264 | listen (tempfd, 5); |
1265 | ||
1266 | tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0); | |
f23b30e2 | 1267 | if (tempfd2 == -1) |
fbd01e6c | 1268 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
f23b30e2 | 1269 | |
fbd01e6c AZ |
1270 | set_socket_buffer (tempfd2); |
1271 | ||
1272 | if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0) | |
1273 | FAIL_EXIT1 ("connect: %m"); | |
1274 | ||
1275 | unlink (sun.sun_path); | |
f23b30e2 | 1276 | |
fa66f341 | 1277 | xpthread_barrier_wait (&b2); |
f23b30e2 | 1278 | |
fbd01e6c AZ |
1279 | if (arg != NULL) |
1280 | xpthread_barrier_wait (&b2); | |
1281 | ||
f23b30e2 UD |
1282 | pthread_cleanup_push (cl, NULL); |
1283 | ||
fbd01e6c | 1284 | char mem[WRITE_BUFFER_SIZE]; |
f23b30e2 | 1285 | |
fbd01e6c | 1286 | sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0, NULL, 0); |
f23b30e2 UD |
1287 | |
1288 | pthread_cleanup_pop (0); | |
1289 | ||
fa66f341 | 1290 | FAIL_EXIT1 ("sendto returned"); |
f23b30e2 UD |
1291 | } |
1292 | ||
1293 | ||
1294 | static void * | |
1295 | tf_sendmsg (void *arg) | |
1296 | { | |
1297 | if (arg == NULL) | |
1298 | // XXX If somebody can provide a portable test case in which sendmsg() | |
1299 | // blocks we can enable this test to run in both rounds. | |
1300 | abort (); | |
1301 | ||
1302 | struct sockaddr_un sun; | |
1303 | ||
1304 | tempfd = socket (AF_UNIX, SOCK_DGRAM, 0); | |
1305 | if (tempfd == -1) | |
fa66f341 | 1306 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m"); |
f23b30e2 UD |
1307 | |
1308 | int tries = 0; | |
1309 | do | |
1310 | { | |
fa66f341 | 1311 | TEST_VERIFY_EXIT (tries++ < 10); |
f23b30e2 UD |
1312 | |
1313 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX"); | |
fa66f341 | 1314 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
f23b30e2 UD |
1315 | |
1316 | sun.sun_family = AF_UNIX; | |
1317 | } | |
1318 | while (bind (tempfd, (struct sockaddr *) &sun, | |
1319 | offsetof (struct sockaddr_un, sun_path) | |
1320 | + strlen (sun.sun_path) + 1) != 0); | |
1321 | tempfname = strdup (sun.sun_path); | |
1322 | ||
1323 | tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0); | |
1324 | if (tempfd2 == -1) | |
fa66f341 | 1325 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m"); |
f23b30e2 | 1326 | |
fa66f341 | 1327 | xpthread_barrier_wait (&b2); |
f23b30e2 | 1328 | |
fa66f341 | 1329 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1330 | |
1331 | pthread_cleanup_push (cl, NULL); | |
1332 | ||
1333 | char mem[1]; | |
1334 | struct iovec iov[1]; | |
1335 | iov[0].iov_base = mem; | |
1336 | iov[0].iov_len = 1; | |
1337 | ||
1338 | struct msghdr m; | |
1339 | m.msg_name = &sun; | |
1340 | m.msg_namelen = (offsetof (struct sockaddr_un, sun_path) | |
1341 | + strlen (sun.sun_path) + 1); | |
1342 | m.msg_iov = iov; | |
1343 | m.msg_iovlen = 1; | |
1344 | m.msg_control = NULL; | |
1345 | m.msg_controllen = 0; | |
1346 | ||
1347 | sendmsg (tempfd2, &m, 0); | |
1348 | ||
1349 | pthread_cleanup_pop (0); | |
1350 | ||
fa66f341 | 1351 | FAIL_EXIT1 ("sendmsg returned"); |
f23b30e2 UD |
1352 | } |
1353 | ||
1354 | ||
1355 | static void * | |
1356 | tf_creat (void *arg) | |
1357 | { | |
1358 | if (arg == NULL) | |
1359 | // XXX If somebody can provide a portable test case in which sendmsg() | |
1360 | // blocks we can enable this test to run in both rounds. | |
1361 | abort (); | |
1362 | ||
fa66f341 | 1363 | xpthread_barrier_wait (&b2); |
f23b30e2 | 1364 | |
fa66f341 | 1365 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1366 | |
1367 | pthread_cleanup_push (cl, NULL); | |
1368 | ||
1369 | creat ("tmp/tst-cancel-4-should-not-exist", 0666); | |
1370 | ||
1371 | pthread_cleanup_pop (0); | |
1372 | ||
fa66f341 | 1373 | FAIL_EXIT1 ("creat returned"); |
f23b30e2 UD |
1374 | } |
1375 | ||
1376 | ||
1377 | static void * | |
1378 | tf_connect (void *arg) | |
1379 | { | |
1380 | if (arg == NULL) | |
1381 | // XXX If somebody can provide a portable test case in which connect() | |
1382 | // blocks we can enable this test to run in both rounds. | |
1383 | abort (); | |
1384 | ||
1385 | struct sockaddr_un sun; | |
1386 | ||
1387 | tempfd = socket (AF_UNIX, SOCK_STREAM, 0); | |
1388 | if (tempfd == -1) | |
fa66f341 | 1389 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
f23b30e2 UD |
1390 | |
1391 | int tries = 0; | |
1392 | do | |
1393 | { | |
fa66f341 | 1394 | TEST_VERIFY_EXIT (tries++ < 10); |
f23b30e2 UD |
1395 | |
1396 | strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX"); | |
fa66f341 | 1397 | TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL); |
f23b30e2 UD |
1398 | |
1399 | sun.sun_family = AF_UNIX; | |
1400 | } | |
1401 | while (bind (tempfd, (struct sockaddr *) &sun, | |
1402 | offsetof (struct sockaddr_un, sun_path) | |
1403 | + strlen (sun.sun_path) + 1) != 0); | |
1404 | tempfname = strdup (sun.sun_path); | |
1405 | ||
1406 | listen (tempfd, 5); | |
1407 | ||
1408 | tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0); | |
1409 | if (tempfd2 == -1) | |
fa66f341 | 1410 | FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); |
f23b30e2 | 1411 | |
fa66f341 | 1412 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1413 | |
1414 | if (arg != NULL) | |
fa66f341 | 1415 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1416 | |
1417 | pthread_cleanup_push (cl, NULL); | |
1418 | ||
1419 | connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)); | |
1420 | ||
1421 | pthread_cleanup_pop (0); | |
1422 | ||
fa66f341 | 1423 | FAIL_EXIT1 ("connect returned"); |
f23b30e2 UD |
1424 | } |
1425 | ||
1426 | ||
1427 | static void * | |
1428 | tf_tcdrain (void *arg) | |
1429 | { | |
1430 | if (arg == NULL) | |
1431 | // XXX If somebody can provide a portable test case in which tcdrain() | |
1432 | // blocks we can enable this test to run in both rounds. | |
1433 | abort (); | |
1434 | ||
fa66f341 | 1435 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1436 | |
1437 | if (arg != NULL) | |
fa66f341 | 1438 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1439 | |
1440 | pthread_cleanup_push (cl, NULL); | |
1441 | ||
1442 | /* Regardless of stderr being a terminal, the tcdrain call should be | |
1443 | canceled. */ | |
1444 | tcdrain (STDERR_FILENO); | |
1445 | ||
1446 | pthread_cleanup_pop (0); | |
1447 | ||
fa66f341 | 1448 | FAIL_EXIT1 ("tcdrain returned"); |
f23b30e2 UD |
1449 | } |
1450 | ||
1451 | ||
1452 | static void * | |
1453 | tf_msgrcv (void *arg) | |
1454 | { | |
483e95d0 | 1455 | tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT); |
67060ef5 | 1456 | if (tempmsg == -1) |
fa66f341 | 1457 | FAIL_EXIT1 ("msgget (IPC_PRIVATE, 0666 | IPC_CREAT): %m"); |
f23b30e2 | 1458 | |
fa66f341 | 1459 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1460 | |
1461 | if (arg != NULL) | |
fa66f341 | 1462 | xpthread_barrier_wait (&b2); |
f23b30e2 | 1463 | |
7d7ff54c UD |
1464 | ssize_t s; |
1465 | ||
f23b30e2 UD |
1466 | pthread_cleanup_push (cl, NULL); |
1467 | ||
1468 | struct | |
1469 | { | |
1470 | long int type; | |
1471 | char mem[10]; | |
1472 | } m; | |
ca343e73 UD |
1473 | int randnr; |
1474 | /* We need a positive random number. */ | |
1475 | do | |
483e95d0 | 1476 | randnr = random () % 64000; |
ca343e73 UD |
1477 | while (randnr <= 0); |
1478 | do | |
1479 | { | |
1480 | errno = 0; | |
7d7ff54c | 1481 | s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0); |
ca343e73 | 1482 | } |
7d7ff54c | 1483 | while (errno == EIDRM || errno == EINTR); |
f23b30e2 UD |
1484 | |
1485 | pthread_cleanup_pop (0); | |
1486 | ||
67060ef5 UD |
1487 | msgctl (tempmsg, IPC_RMID, NULL); |
1488 | ||
fa66f341 | 1489 | FAIL_EXIT1 ("msgrcv returned %zd", s); |
f23b30e2 UD |
1490 | } |
1491 | ||
1492 | ||
1493 | static void * | |
1494 | tf_msgsnd (void *arg) | |
1495 | { | |
1496 | if (arg == NULL) | |
1497 | // XXX If somebody can provide a portable test case in which msgsnd() | |
1498 | // blocks we can enable this test to run in both rounds. | |
1499 | abort (); | |
1500 | ||
483e95d0 | 1501 | tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT); |
67060ef5 | 1502 | if (tempmsg == -1) |
fa66f341 | 1503 | FAIL_EXIT1 ("msgget (IPC_PRIVATE, 0666 | IPC_CREAT): %m"); |
f23b30e2 | 1504 | |
fa66f341 | 1505 | xpthread_barrier_wait (&b2); |
f23b30e2 | 1506 | |
fa66f341 | 1507 | xpthread_barrier_wait (&b2); |
f23b30e2 UD |
1508 | |
1509 | pthread_cleanup_push (cl, NULL); | |
1510 | ||
1511 | struct | |
1512 | { | |
1513 | long int type; | |
1514 | char mem[1]; | |
1515 | } m; | |
ca343e73 UD |
1516 | /* We need a positive random number. */ |
1517 | do | |
483e95d0 | 1518 | m.type = random () % 64000; |
ca343e73 | 1519 | while (m.type <= 0); |
f23b30e2 UD |
1520 | msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0); |
1521 | ||
1522 | pthread_cleanup_pop (0); | |
1523 | ||
67060ef5 UD |
1524 | msgctl (tempmsg, IPC_RMID, NULL); |
1525 | ||
fa66f341 | 1526 | FAIL_EXIT1 ("msgsnd returned"); |
f23b30e2 UD |
1527 | } |
1528 | ||
1529 | ||
b39b6e0c | 1530 | struct cancel_tests tests[] = |
26676450 | 1531 | { |
26676450 UD |
1532 | ADD_TEST (read, 2, 0), |
1533 | ADD_TEST (readv, 2, 0), | |
1534 | ADD_TEST (select, 2, 0), | |
1535 | ADD_TEST (pselect, 2, 0), | |
1536 | ADD_TEST (poll, 2, 0), | |
7c65e900 | 1537 | ADD_TEST (ppoll, 2, 0), |
26676450 UD |
1538 | ADD_TEST (write, 2, 0), |
1539 | ADD_TEST (writev, 2, 0), | |
1540 | ADD_TEST (sleep, 2, 0), | |
1541 | ADD_TEST (usleep, 2, 0), | |
1542 | ADD_TEST (nanosleep, 2, 0), | |
1543 | ADD_TEST (wait, 2, 0), | |
1544 | ADD_TEST (waitid, 2, 0), | |
1545 | ADD_TEST (waitpid, 2, 0), | |
1546 | ADD_TEST (sigpause, 2, 0), | |
1547 | ADD_TEST (sigsuspend, 2, 0), | |
1548 | ADD_TEST (sigwait, 2, 0), | |
1549 | ADD_TEST (sigwaitinfo, 2, 0), | |
1550 | ADD_TEST (sigtimedwait, 2, 0), | |
1551 | ADD_TEST (pause, 2, 0), | |
1552 | ADD_TEST (accept, 2, 0), | |
1553 | ADD_TEST (send, 2, 0), | |
1554 | ADD_TEST (recv, 2, 0), | |
1555 | ADD_TEST (recvfrom, 2, 0), | |
1556 | ADD_TEST (recvmsg, 2, 0), | |
4e778151 | 1557 | ADD_TEST (preadv, 2, 1), |
52bd9381 | 1558 | ADD_TEST (preadv2, 2, 1), |
af5fdf5a | 1559 | ADD_TEST (pwritev, 2, 1), |
52bd9381 | 1560 | ADD_TEST (pwritev2, 2, 1), |
047aec8f UD |
1561 | ADD_TEST (open, 2, 1), |
1562 | ADD_TEST (close, 2, 1), | |
1563 | ADD_TEST (pread, 2, 1), | |
1564 | ADD_TEST (pwrite, 2, 1), | |
1565 | ADD_TEST (fsync, 2, 1), | |
aa75f64c | 1566 | ADD_TEST (fdatasync, 2, 1), |
047aec8f | 1567 | ADD_TEST (msync, 2, 1), |
f23b30e2 UD |
1568 | ADD_TEST (sendto, 2, 1), |
1569 | ADD_TEST (sendmsg, 2, 1), | |
1570 | ADD_TEST (creat, 2, 1), | |
1571 | ADD_TEST (connect, 2, 1), | |
1572 | ADD_TEST (tcdrain, 2, 1), | |
1573 | ADD_TEST (msgrcv, 2, 0), | |
1574 | ADD_TEST (msgsnd, 2, 1), | |
26676450 UD |
1575 | }; |
1576 | #define ntest_tf (sizeof (tests) / sizeof (tests[0])) | |
1577 | ||
b39b6e0c | 1578 | #include "tst-cancel4-common.c" |