nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029)
[glibc.git] / sysdeps / pthread / tst-cancel4.c
blob7067f17c23f054cc1e25623cfe45404e82e7960b
1 /* Copyright (C) 2002-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 /* NOTE: this tests functionality beyond POSIX. POSIX does not allow
19 exit to be called more than once. */
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sys/ipc.h>
29 #include <sys/msg.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <pthread.h>
34 #include <fcntl.h>
35 #include <termios.h>
36 #include <sys/mman.h>
37 #include <sys/poll.h>
38 #include <sys/wait.h>
39 #include <sys/stat.h>
40 #include <sys/uio.h>
41 #include <libc-diag.h>
44 /* Since STREAMS are not supported in the standard Linux kernel and
45 there we don't advertise STREAMS as supported is no need to test
46 the STREAMS related functions. This affects
47 getmsg() getpmsg() putmsg()
48 putpmsg()
50 lockf() and fcntl() are tested in tst-cancel16.
52 pthread_join() is tested in tst-join5.
54 pthread_testcancel()'s only purpose is to allow cancellation. This
55 is tested in several places.
57 sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
59 mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
60 in tst-mqueue8{,x} tests.
62 aio_suspend() is tested in tst-cancel17.
64 clock_nanosleep() is tested in tst-cancel18.
66 Linux sendmmsg and recvmmsg are checked in tst-cancel4_1.c and
67 tst-cancel4_2.c respectively.
70 #include "tst-cancel4-common.h"
73 #ifndef IPC_ADDVAL
74 # define IPC_ADDVAL 0
75 #endif
78 static void *
79 tf_read (void *arg)
81 int fd;
83 if (arg == NULL)
84 fd = fds[0];
85 else
87 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
88 tempfd = fd = mkstemp (fname);
89 if (fd == -1)
90 FAIL_EXIT1 ("mkstemp failed: %m");
91 unlink (fname);
93 xpthread_barrier_wait (&b2);
96 xpthread_barrier_wait (&b2);
98 ssize_t s;
99 pthread_cleanup_push (cl, NULL);
101 char buf[100];
102 s = read (fd, buf, sizeof (buf));
104 pthread_cleanup_pop (0);
106 FAIL_EXIT1 ("read returns with %zd", s);
110 static void *
111 tf_readv (void *arg)
113 int fd;
115 if (arg == NULL)
116 fd = fds[0];
117 else
119 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
120 tempfd = fd = mkstemp (fname);
121 if (fd == -1)
122 FAIL_EXIT1 ("mkstemp failed: %m");
123 unlink (fname);
125 xpthread_barrier_wait (&b2);
128 xpthread_barrier_wait (&b2);
130 ssize_t s;
131 pthread_cleanup_push (cl, NULL);
133 char buf[100];
134 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
135 s = readv (fd, iov, 1);
137 pthread_cleanup_pop (0);
139 FAIL_EXIT1 ("readv returns with %zd", s);
143 static void *
144 tf_write (void *arg)
146 int fd;
148 if (arg == NULL)
149 fd = fds[1];
150 else
152 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
153 tempfd = fd = mkstemp (fname);
154 if (fd == -1)
155 FAIL_EXIT1 ("mkstemp failed: %m");
156 unlink (fname);
158 xpthread_barrier_wait (&b2);
161 xpthread_barrier_wait (&b2);
163 ssize_t s;
164 pthread_cleanup_push (cl, NULL);
166 char buf[WRITE_BUFFER_SIZE];
167 memset (buf, '\0', sizeof (buf));
168 s = write (fd, buf, sizeof (buf));
169 /* The write can return a value higher than 0 (meaning partial write)
170 due to the SIGCANCEL, but the thread may still be pending
171 cancellation. */
172 pthread_testcancel ();
174 pthread_cleanup_pop (0);
176 FAIL_EXIT1 ("write returns with %zd", s);
180 static void *
181 tf_writev (void *arg)
183 int fd;
185 if (arg == NULL)
186 fd = fds[1];
187 else
189 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
190 tempfd = fd = mkstemp (fname);
191 if (fd == -1)
192 FAIL_EXIT1 ("mkstemp failed: %m");
193 unlink (fname);
195 xpthread_barrier_wait (&b2);
198 xpthread_barrier_wait (&b2);
200 ssize_t s;
201 pthread_cleanup_push (cl, NULL);
203 char buf[WRITE_BUFFER_SIZE];
204 memset (buf, '\0', sizeof (buf));
205 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
206 s = writev (fd, iov, 1);
208 pthread_cleanup_pop (0);
210 FAIL_EXIT1 ("writev returns with %zd", s);
214 static void *
215 tf_sleep (void *arg)
217 xpthread_barrier_wait (&b2);
219 if (arg != NULL)
220 xpthread_barrier_wait (&b2);
222 pthread_cleanup_push (cl, NULL);
224 sleep (arg == NULL ? 1000000 : 0);
226 pthread_cleanup_pop (0);
228 FAIL_EXIT1 ("sleep returns");
232 static void *
233 tf_usleep (void *arg)
235 xpthread_barrier_wait (&b2);
237 if (arg != NULL)
238 xpthread_barrier_wait (&b2);
240 pthread_cleanup_push (cl, NULL);
242 usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
244 pthread_cleanup_pop (0);
246 FAIL_EXIT1 ("usleep returns");
250 static void *
251 tf_nanosleep (void *arg)
253 xpthread_barrier_wait (&b2);
255 if (arg != NULL)
256 xpthread_barrier_wait (&b2);
258 pthread_cleanup_push (cl, NULL);
260 struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
261 TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
263 pthread_cleanup_pop (0);
265 FAIL_EXIT1 ("nanosleep returns");
269 static void *
270 tf_select (void *arg)
272 int fd;
274 if (arg == NULL)
275 fd = fds[0];
276 else
278 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
279 tempfd = fd = mkstemp (fname);
280 if (fd == -1)
281 FAIL_EXIT1 ("mkstemp failed: %m");
282 unlink (fname);
284 xpthread_barrier_wait (&b2);
287 xpthread_barrier_wait (&b2);
289 fd_set rfs;
290 FD_ZERO (&rfs);
291 FD_SET (fd, &rfs);
293 int s;
294 pthread_cleanup_push (cl, NULL);
296 s = select (fd + 1, &rfs, NULL, NULL, NULL);
298 pthread_cleanup_pop (0);
300 FAIL_EXIT1 ("select returns with %d: %m", s);
304 static void *
305 tf_pselect (void *arg)
307 int fd;
309 if (arg == NULL)
310 fd = fds[0];
311 else
313 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
314 tempfd = fd = mkstemp (fname);
315 if (fd == -1)
316 FAIL_EXIT1 ("mkstemp failed: %m");
317 unlink (fname);
319 xpthread_barrier_wait (&b2);
322 xpthread_barrier_wait (&b2);
324 fd_set rfs;
325 FD_ZERO (&rfs);
326 FD_SET (fd, &rfs);
328 int s;
329 pthread_cleanup_push (cl, NULL);
331 s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
333 pthread_cleanup_pop (0);
335 FAIL_EXIT1 ("pselect returns with %d: %m", s);
339 static void *
340 tf_poll (void *arg)
342 int fd;
344 if (arg == NULL)
345 fd = fds[0];
346 else
348 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
349 tempfd = fd = mkstemp (fname);
350 if (fd == -1)
351 FAIL_EXIT1 ("mkstemp failed: %m");
352 unlink (fname);
354 xpthread_barrier_wait (&b2);
357 xpthread_barrier_wait (&b2);
359 struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
361 int s;
362 pthread_cleanup_push (cl, NULL);
364 s = poll (rfs, 1, -1);
366 pthread_cleanup_pop (0);
368 FAIL_EXIT1 ("poll returns with %d: %m", s);
372 static void *
373 tf_ppoll (void *arg)
375 int fd;
377 if (arg == NULL)
378 fd = fds[0];
379 else
381 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
382 tempfd = fd = mkstemp (fname);
383 if (fd == -1)
384 FAIL_EXIT1 ("mkstemp failed: %m");
385 unlink (fname);
387 xpthread_barrier_wait (&b2);
390 xpthread_barrier_wait (&b2);
392 struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
394 int s;
395 pthread_cleanup_push (cl, NULL);
397 s = ppoll (rfs, 1, NULL, NULL);
399 pthread_cleanup_pop (0);
401 FAIL_EXIT1 ("ppoll returns with %d: %m", s);
405 static void *
406 tf_wait (void *arg)
408 pid_t pid = fork ();
409 if (pid == -1)
410 FAIL_EXIT1 ("fork: %m");
412 if (pid == 0)
414 /* Make the program disappear after a while. */
415 if (arg == NULL)
416 sleep (10);
417 exit (0);
420 if (arg != NULL)
422 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
423 while (nanosleep (&ts, &ts) != 0)
424 continue;
426 xpthread_barrier_wait (&b2);
429 xpthread_barrier_wait (&b2);
431 int s;
432 pthread_cleanup_push (cl, NULL);
434 s = wait (NULL);
436 pthread_cleanup_pop (0);
438 FAIL_EXIT1 ("wait returns with %d: %m", s);
442 static void *
443 tf_waitpid (void *arg)
445 pid_t pid = fork ();
446 if (pid == -1)
447 FAIL_EXIT1 ("fork: %m");
449 if (pid == 0)
451 /* Make the program disappear after a while. */
452 if (arg == NULL)
453 sleep (10);
454 exit (0);
457 if (arg != NULL)
459 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
460 while (nanosleep (&ts, &ts) != 0)
461 continue;
463 xpthread_barrier_wait (&b2);
466 xpthread_barrier_wait (&b2);
468 int s;
469 pthread_cleanup_push (cl, NULL);
471 s = waitpid (-1, NULL, 0);
473 pthread_cleanup_pop (0);
475 FAIL_EXIT1 ("waitpid returns with %d: %m", s);
479 static void *
480 tf_waitid (void *arg)
482 pid_t pid = fork ();
483 if (pid == -1)
484 FAIL_EXIT1 ("fork: %m");
486 if (pid == 0)
488 /* Make the program disappear after a while. */
489 if (arg == NULL)
490 sleep (10);
491 exit (0);
494 if (arg != NULL)
496 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
497 while (nanosleep (&ts, &ts) != 0)
498 continue;
500 xpthread_barrier_wait (&b2);
503 xpthread_barrier_wait (&b2);
505 int s;
506 pthread_cleanup_push (cl, NULL);
508 #ifndef WEXITED
509 # define WEXITED 0
510 #endif
511 siginfo_t si;
512 s = waitid (P_PID, pid, &si, WEXITED);
514 pthread_cleanup_pop (0);
516 FAIL_EXIT1 ("waitid returns with %d: %m", s);
520 static void *
521 tf_sigpause (void *arg)
523 xpthread_barrier_wait (&b2);
525 if (arg != NULL)
526 xpthread_barrier_wait (&b2);
528 pthread_cleanup_push (cl, NULL);
530 /* This tests the deprecated sigpause and sigmask functions. The
531 file is compiled with -Wno-errno so that the sigmask deprecation
532 warning is not fatal. */
533 DIAG_PUSH_NEEDS_COMMENT;
534 DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
535 sigpause (sigmask (SIGINT));
536 DIAG_POP_NEEDS_COMMENT;
538 pthread_cleanup_pop (0);
540 FAIL_EXIT1 ("sigpause returned");
544 static void *
545 tf_sigsuspend (void *arg)
547 xpthread_barrier_wait (&b2);
549 if (arg != NULL)
550 xpthread_barrier_wait (&b2);
552 pthread_cleanup_push (cl, NULL);
554 /* Just for fun block all signals. */
555 sigset_t mask;
556 sigfillset (&mask);
557 sigsuspend (&mask);
559 pthread_cleanup_pop (0);
561 FAIL_EXIT1 ("sigsuspend returned");
565 static void *
566 tf_sigwait (void *arg)
568 xpthread_barrier_wait (&b2);
570 if (arg != NULL)
571 xpthread_barrier_wait (&b2);
573 /* Block SIGUSR1. */
574 sigset_t mask;
575 sigemptyset (&mask);
576 sigaddset (&mask, SIGUSR1);
577 TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0);
579 int sig;
580 pthread_cleanup_push (cl, NULL);
582 /* Wait for SIGUSR1. */
583 sigwait (&mask, &sig);
585 pthread_cleanup_pop (0);
587 FAIL_EXIT1 ("sigwait returned with signal %d", sig);
591 static void *
592 tf_sigwaitinfo (void *arg)
594 xpthread_barrier_wait (&b2);
596 if (arg != NULL)
597 xpthread_barrier_wait (&b2);
599 /* Block SIGUSR1. */
600 sigset_t mask;
601 sigemptyset (&mask);
602 sigaddset (&mask, SIGUSR1);
603 TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0);
605 siginfo_t info;
606 pthread_cleanup_push (cl, NULL);
608 /* Wait for SIGUSR1. */
609 int ret;
610 ret = sigwaitinfo (&mask, &info);
611 if (ret == -1 && errno == ENOSYS)
613 int sig;
615 printf ("sigwaitinfo not supported\n");
616 sigwait (&mask, &sig);
619 pthread_cleanup_pop (0);
621 FAIL_EXIT1 ("sigwaitinfo returned with signal %d", info.si_signo);
625 static void *
626 tf_sigtimedwait (void *arg)
628 xpthread_barrier_wait (&b2);
630 if (arg != NULL)
631 xpthread_barrier_wait (&b2);
633 /* Block SIGUSR1. */
634 sigset_t mask;
635 sigemptyset (&mask);
636 sigaddset (&mask, SIGUSR1);
637 TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0);
639 /* Wait for SIGUSR1. */
640 siginfo_t info;
641 struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
642 pthread_cleanup_push (cl, NULL);
644 int ret;
645 ret = sigtimedwait (&mask, &info, &ts);
646 if (ret == -1 && errno == ENOSYS)
648 int sig;
649 printf ("sigtimedwait not supported\n");
651 sigwait (&mask, &sig);
654 pthread_cleanup_pop (0);
656 FAIL_EXIT1 ("sigtimedwait returned with signal %d", info.si_signo);
660 static void *
661 tf_pause (void *arg)
663 xpthread_barrier_wait (&b2);
665 if (arg != NULL)
666 xpthread_barrier_wait (&b2);
668 pthread_cleanup_push (cl, NULL);
670 pause ();
672 pthread_cleanup_pop (0);
674 FAIL_EXIT1 ("pause returned");
678 static void *
679 tf_accept (void *arg)
681 struct sockaddr_un sun;
682 /* To test a non-blocking accept call we make the call file by using
683 a datagrame socket. */
684 int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
686 tempfd = socket (AF_UNIX, pf, 0);
687 if (tempfd == -1)
688 FAIL_EXIT1 ("socket (AF_UNIX, %s, 0): %m", arg == NULL ? "SOCK_STREAM"
689 : "SOCK_DGRAM");
691 int tries = 0;
694 TEST_VERIFY_EXIT (tries++ < 10);
696 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
697 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
699 sun.sun_family = AF_UNIX;
701 while (bind (tempfd, (struct sockaddr *) &sun,
702 offsetof (struct sockaddr_un, sun_path)
703 + strlen (sun.sun_path) + 1) != 0);
705 unlink (sun.sun_path);
707 listen (tempfd, 5);
709 socklen_t len = sizeof (sun);
711 xpthread_barrier_wait (&b2);
713 if (arg != NULL)
714 xpthread_barrier_wait (&b2);
716 pthread_cleanup_push (cl, NULL);
718 accept (tempfd, (struct sockaddr *) &sun, &len);
720 pthread_cleanup_pop (0);
722 FAIL_EXIT1 ("accept returned");
726 static void *
727 tf_send (void *arg)
729 struct sockaddr_un sun;
731 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
732 if (tempfd == -1)
733 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
735 int tries = 0;
738 TEST_VERIFY_EXIT (tries++ < 10);
740 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
741 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
743 sun.sun_family = AF_UNIX;
745 while (bind (tempfd, (struct sockaddr *) &sun,
746 offsetof (struct sockaddr_un, sun_path)
747 + strlen (sun.sun_path) + 1) != 0);
749 listen (tempfd, 5);
751 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
752 if (tempfd2 == -1)
753 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
755 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
756 FAIL_EXIT1 ("connect: %m");
758 unlink (sun.sun_path);
760 set_socket_buffer (tempfd2);
762 xpthread_barrier_wait (&b2);
764 if (arg != NULL)
765 xpthread_barrier_wait (&b2);
767 pthread_cleanup_push (cl, NULL);
769 char mem[WRITE_BUFFER_SIZE];
771 size_t s = send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
772 /* The send can return a value higher than 0 (meaning partial send)
773 due to the SIGCANCEL, but the thread may still be pending
774 cancellation. */
775 pthread_testcancel ();
776 printf("send returned %zd\n", s);
778 pthread_cleanup_pop (0);
780 FAIL_EXIT1 ("send returned");
784 static void *
785 tf_recv (void *arg)
787 struct sockaddr_un sun;
789 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
790 if (tempfd == -1)
791 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
793 int tries = 0;
796 TEST_VERIFY_EXIT (tries++ < 10);
798 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
799 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
801 sun.sun_family = AF_UNIX;
803 while (bind (tempfd, (struct sockaddr *) &sun,
804 offsetof (struct sockaddr_un, sun_path)
805 + strlen (sun.sun_path) + 1) != 0);
807 listen (tempfd, 5);
809 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
810 if (tempfd2 == -1)
811 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
813 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
814 FAIL_EXIT1 ("connect: %m");
816 unlink (sun.sun_path);
818 xpthread_barrier_wait (&b2);
820 if (arg != NULL)
821 xpthread_barrier_wait (&b2);
823 pthread_cleanup_push (cl, NULL);
825 char mem[70];
827 recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
829 pthread_cleanup_pop (0);
831 FAIL_EXIT1 ("recv returned");
835 static void *
836 tf_recvfrom (void *arg)
838 struct sockaddr_un sun;
840 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
841 if (tempfd == -1)
842 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
844 int tries = 0;
847 TEST_VERIFY_EXIT (tries++ < 10);
849 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
850 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
852 sun.sun_family = AF_UNIX;
854 while (bind (tempfd, (struct sockaddr *) &sun,
855 offsetof (struct sockaddr_un, sun_path)
856 + strlen (sun.sun_path) + 1) != 0);
858 tempfname = strdup (sun.sun_path);
860 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
861 if (tempfd2 == -1)
862 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
864 xpthread_barrier_wait (&b2);
866 if (arg != NULL)
867 xpthread_barrier_wait (&b2);
869 pthread_cleanup_push (cl, NULL);
871 char mem[70];
872 socklen_t len = sizeof (sun);
874 recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
875 (struct sockaddr *) &sun, &len);
877 pthread_cleanup_pop (0);
879 FAIL_EXIT1 ("recvfrom returned");
883 static void *
884 tf_recvmsg (void *arg)
886 struct sockaddr_un sun;
888 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
889 if (tempfd == -1)
890 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
892 int tries = 0;
895 TEST_VERIFY_EXIT (tries++ < 10);
897 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
898 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
900 sun.sun_family = AF_UNIX;
902 while (bind (tempfd, (struct sockaddr *) &sun,
903 offsetof (struct sockaddr_un, sun_path)
904 + strlen (sun.sun_path) + 1) != 0);
906 tempfname = strdup (sun.sun_path);
908 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
909 if (tempfd2 == -1)
910 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
912 xpthread_barrier_wait (&b2);
914 if (arg != NULL)
915 xpthread_barrier_wait (&b2);
917 pthread_cleanup_push (cl, NULL);
919 char mem[70];
920 struct iovec iov[1];
921 iov[0].iov_base = mem;
922 iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
924 struct msghdr m;
925 m.msg_name = &sun;
926 m.msg_namelen = sizeof (sun);
927 m.msg_iov = iov;
928 m.msg_iovlen = 1;
929 m.msg_control = NULL;
930 m.msg_controllen = 0;
932 recvmsg (tempfd2, &m, 0);
934 pthread_cleanup_pop (0);
936 FAIL_EXIT1 ("recvmsg returned");
939 static void *
940 tf_open (void *arg)
942 if (arg == NULL)
944 fifofd = mkfifo (fifoname, S_IWUSR | S_IRUSR);
945 if (fifofd == -1)
946 FAIL_EXIT1 ("mkfifo: %m");
948 else
950 xpthread_barrier_wait (&b2);
953 xpthread_barrier_wait (&b2);
955 pthread_cleanup_push (cl_fifo, NULL);
957 open (arg ? "Makefile" : fifoname, O_RDONLY);
959 pthread_cleanup_pop (0);
961 FAIL_EXIT1 ("open returned");
965 static void *
966 tf_close (void *arg)
968 if (arg == NULL)
969 // XXX If somebody can provide a portable test case in which close()
970 // blocks we can enable this test to run in both rounds.
971 abort ();
973 char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
974 tempfd = mkstemp (fname);
975 if (tempfd == -1)
976 FAIL_EXIT1 ("mkstemp failed: %m");
977 unlink (fname);
979 xpthread_barrier_wait (&b2);
981 xpthread_barrier_wait (&b2);
983 pthread_cleanup_push (cl, NULL);
985 close (tempfd);
987 pthread_cleanup_pop (0);
989 FAIL_EXIT1 ("close returned");
993 static void *
994 tf_pread (void *arg)
996 if (arg == NULL)
997 // XXX If somebody can provide a portable test case in which pread()
998 // blocks we can enable this test to run in both rounds.
999 abort ();
1001 tempfd = open ("Makefile", O_RDONLY);
1002 if (tempfd == -1)
1003 FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1005 xpthread_barrier_wait (&b2);
1007 xpthread_barrier_wait (&b2);
1009 pthread_cleanup_push (cl, NULL);
1011 char mem[10];
1012 pread (tempfd, mem, sizeof (mem), 0);
1014 pthread_cleanup_pop (0);
1016 FAIL_EXIT1 ("pread returned");
1020 static void *
1021 tf_pwrite (void *arg)
1023 if (arg == NULL)
1024 // XXX If somebody can provide a portable test case in which pwrite()
1025 // blocks we can enable this test to run in both rounds.
1026 abort ();
1028 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1029 tempfd = mkstemp (fname);
1030 if (tempfd == -1)
1031 FAIL_EXIT1 ("mkstemp failed: %m");
1032 unlink (fname);
1034 xpthread_barrier_wait (&b2);
1036 xpthread_barrier_wait (&b2);
1038 pthread_cleanup_push (cl, NULL);
1040 char mem[10];
1041 pwrite (tempfd, mem, sizeof (mem), 0);
1043 pthread_cleanup_pop (0);
1045 FAIL_EXIT1 ("pwrite returned");
1048 static void *
1049 tf_preadv (void *arg)
1051 int fd;
1053 if (arg == NULL)
1054 /* XXX If somebody can provide a portable test case in which preadv
1055 blocks we can enable this test to run in both rounds. */
1056 abort ();
1058 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1059 tempfd = fd = mkstemp (fname);
1060 if (fd == -1)
1061 FAIL_EXIT1 ("mkstemp failed: %m");
1062 unlink (fname);
1064 xpthread_barrier_wait (&b2);
1066 xpthread_barrier_wait (&b2);
1068 ssize_t s;
1069 pthread_cleanup_push (cl, NULL);
1071 char buf[100];
1072 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1073 s = preadv (fd, iov, 1, 0);
1075 pthread_cleanup_pop (0);
1077 FAIL_EXIT1 ("preadv returns with %zd", s);
1080 static void *
1081 tf_pwritev (void *arg)
1083 int fd;
1085 if (arg == NULL)
1086 /* XXX If somebody can provide a portable test case in which pwritev
1087 blocks we can enable this test to run in both rounds. */
1088 abort ();
1090 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1091 tempfd = fd = mkstemp (fname);
1092 if (fd == -1)
1093 FAIL_EXIT1 ("mkstemp failed: %m");
1094 unlink (fname);
1096 xpthread_barrier_wait (&b2);
1098 xpthread_barrier_wait (&b2);
1100 ssize_t s;
1101 pthread_cleanup_push (cl, NULL);
1103 char buf[WRITE_BUFFER_SIZE];
1104 memset (buf, '\0', sizeof (buf));
1105 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1106 s = pwritev (fd, iov, 1, 0);
1108 pthread_cleanup_pop (0);
1110 FAIL_EXIT1 ("pwritev returns with %zd", s);
1113 static void *
1114 tf_pwritev2 (void *arg)
1116 int fd;
1118 if (arg == NULL)
1119 /* XXX If somebody can provide a portable test case in which pwritev2
1120 blocks we can enable this test to run in both rounds. */
1121 abort ();
1123 errno = 0;
1125 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1126 tempfd = fd = mkstemp (fname);
1127 if (fd == -1)
1128 FAIL_EXIT1 ("mkstemp: %m");
1129 unlink (fname);
1131 xpthread_barrier_wait (&b2);
1133 xpthread_barrier_wait (&b2);
1135 ssize_t s;
1136 pthread_cleanup_push (cl, NULL);
1138 char buf[WRITE_BUFFER_SIZE];
1139 memset (buf, '\0', sizeof (buf));
1140 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1141 s = pwritev2 (fd, iov, 1, 0, 0);
1143 pthread_cleanup_pop (0);
1145 FAIL_EXIT1 ("pwritev2 returns with %zd", s);
1148 static void *
1149 tf_preadv2 (void *arg)
1151 int fd;
1153 if (arg == NULL)
1154 /* XXX If somebody can provide a portable test case in which preadv2
1155 blocks we can enable this test to run in both rounds. */
1156 abort ();
1158 errno = 0;
1160 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1161 tempfd = fd = mkstemp (fname);
1162 if (fd == -1)
1163 FAIL_EXIT1 ("mkstemp failed: %m");
1164 unlink (fname);
1166 xpthread_barrier_wait (&b2);
1168 xpthread_barrier_wait (&b2);
1170 ssize_t s;
1171 pthread_cleanup_push (cl, NULL);
1173 char buf[100];
1174 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1175 s = preadv2 (fd, iov, 1, 0, 0);
1177 pthread_cleanup_pop (0);
1179 FAIL_EXIT1 ("preadv2 returns with %zd", s);
1182 static void *
1183 tf_fsync (void *arg)
1185 if (arg == NULL)
1186 // XXX If somebody can provide a portable test case in which fsync()
1187 // blocks we can enable this test to run in both rounds.
1188 abort ();
1190 tempfd = open ("Makefile", O_RDONLY);
1191 if (tempfd == -1)
1192 FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1194 xpthread_barrier_wait (&b2);
1196 xpthread_barrier_wait (&b2);
1198 pthread_cleanup_push (cl, NULL);
1200 fsync (tempfd);
1202 pthread_cleanup_pop (0);
1204 FAIL_EXIT1 ("fsync returned");
1208 static void *
1209 tf_fdatasync (void *arg)
1211 if (arg == NULL)
1212 // XXX If somebody can provide a portable test case in which fdatasync()
1213 // blocks we can enable this test to run in both rounds.
1214 abort ();
1216 tempfd = open ("Makefile", O_RDONLY);
1217 if (tempfd == -1)
1218 FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1220 xpthread_barrier_wait (&b2);
1222 xpthread_barrier_wait (&b2);
1224 pthread_cleanup_push (cl, NULL);
1226 fdatasync (tempfd);
1228 pthread_cleanup_pop (0);
1230 FAIL_EXIT1 ("fdatasync returned");
1234 static void *
1235 tf_msync (void *arg)
1237 if (arg == NULL)
1238 // XXX If somebody can provide a portable test case in which msync()
1239 // blocks we can enable this test to run in both rounds.
1240 abort ();
1242 tempfd = open ("Makefile", O_RDONLY);
1243 if (tempfd == -1)
1244 FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1246 void *p = xmmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd);
1248 xpthread_barrier_wait (&b2);
1250 xpthread_barrier_wait (&b2);
1252 pthread_cleanup_push (cl, NULL);
1254 msync (p, 10, 0);
1256 pthread_cleanup_pop (0);
1258 FAIL_EXIT1 ("msync returned");
1262 static void *
1263 tf_sendto (void *arg)
1265 struct sockaddr_un sun;
1267 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1268 if (tempfd == -1)
1269 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1271 int tries = 0;
1274 TEST_VERIFY_EXIT (tries++ < 10);
1276 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1277 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
1279 sun.sun_family = AF_UNIX;
1281 while (bind (tempfd, (struct sockaddr *) &sun,
1282 offsetof (struct sockaddr_un, sun_path)
1283 + strlen (sun.sun_path) + 1) != 0);
1285 listen (tempfd, 5);
1287 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1288 if (tempfd2 == -1)
1289 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1291 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1292 FAIL_EXIT1 ("connect: %m");
1294 unlink (sun.sun_path);
1296 set_socket_buffer (tempfd2);
1298 xpthread_barrier_wait (&b2);
1300 if (arg != NULL)
1301 xpthread_barrier_wait (&b2);
1303 pthread_cleanup_push (cl, NULL);
1305 char mem[WRITE_BUFFER_SIZE];
1307 sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0, NULL, 0);
1309 pthread_cleanup_pop (0);
1311 FAIL_EXIT1 ("sendto returned");
1315 static void *
1316 tf_sendmsg (void *arg)
1318 if (arg == NULL)
1319 // XXX If somebody can provide a portable test case in which sendmsg()
1320 // blocks we can enable this test to run in both rounds.
1321 abort ();
1323 struct sockaddr_un sun;
1325 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1326 if (tempfd == -1)
1327 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
1329 int tries = 0;
1332 TEST_VERIFY_EXIT (tries++ < 10);
1334 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1335 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
1337 sun.sun_family = AF_UNIX;
1339 while (bind (tempfd, (struct sockaddr *) &sun,
1340 offsetof (struct sockaddr_un, sun_path)
1341 + strlen (sun.sun_path) + 1) != 0);
1342 tempfname = strdup (sun.sun_path);
1344 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1345 if (tempfd2 == -1)
1346 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
1348 xpthread_barrier_wait (&b2);
1350 xpthread_barrier_wait (&b2);
1352 pthread_cleanup_push (cl, NULL);
1354 char mem[1];
1355 struct iovec iov[1];
1356 iov[0].iov_base = mem;
1357 iov[0].iov_len = 1;
1359 struct msghdr m;
1360 m.msg_name = &sun;
1361 m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1362 + strlen (sun.sun_path) + 1);
1363 m.msg_iov = iov;
1364 m.msg_iovlen = 1;
1365 m.msg_control = NULL;
1366 m.msg_controllen = 0;
1368 sendmsg (tempfd2, &m, 0);
1370 pthread_cleanup_pop (0);
1372 FAIL_EXIT1 ("sendmsg returned");
1376 static void *
1377 tf_creat (void *arg)
1379 if (arg == NULL)
1380 // XXX If somebody can provide a portable test case in which sendmsg()
1381 // blocks we can enable this test to run in both rounds.
1382 abort ();
1384 xpthread_barrier_wait (&b2);
1386 xpthread_barrier_wait (&b2);
1388 pthread_cleanup_push (cl, NULL);
1390 creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1392 pthread_cleanup_pop (0);
1394 FAIL_EXIT1 ("creat returned");
1398 static void *
1399 tf_connect (void *arg)
1401 if (arg == NULL)
1402 // XXX If somebody can provide a portable test case in which connect()
1403 // blocks we can enable this test to run in both rounds.
1404 abort ();
1406 struct sockaddr_un sun;
1408 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1409 if (tempfd == -1)
1410 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1412 int tries = 0;
1415 TEST_VERIFY_EXIT (tries++ < 10);
1417 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1418 TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
1420 sun.sun_family = AF_UNIX;
1422 while (bind (tempfd, (struct sockaddr *) &sun,
1423 offsetof (struct sockaddr_un, sun_path)
1424 + strlen (sun.sun_path) + 1) != 0);
1425 tempfname = strdup (sun.sun_path);
1427 listen (tempfd, 5);
1429 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1430 if (tempfd2 == -1)
1431 FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1433 xpthread_barrier_wait (&b2);
1435 if (arg != NULL)
1436 xpthread_barrier_wait (&b2);
1438 pthread_cleanup_push (cl, NULL);
1440 connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1442 pthread_cleanup_pop (0);
1444 FAIL_EXIT1 ("connect returned");
1448 static void *
1449 tf_tcdrain (void *arg)
1451 if (arg == NULL)
1452 // XXX If somebody can provide a portable test case in which tcdrain()
1453 // blocks we can enable this test to run in both rounds.
1454 abort ();
1456 xpthread_barrier_wait (&b2);
1458 if (arg != NULL)
1459 xpthread_barrier_wait (&b2);
1461 pthread_cleanup_push (cl, NULL);
1463 /* Regardless of stderr being a terminal, the tcdrain call should be
1464 canceled. */
1465 tcdrain (STDERR_FILENO);
1467 pthread_cleanup_pop (0);
1469 FAIL_EXIT1 ("tcdrain returned");
1473 static void *
1474 tf_msgrcv (void *arg)
1476 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1477 if (tempmsg == -1)
1479 if (errno == ENOSYS)
1481 printf ("msgget not supported\n");
1482 tf_usleep (arg);
1483 pthread_exit (NULL);
1485 else
1486 FAIL_EXIT1 ("msgget (IPC_PRIVATE, 0666 | IPC_CREAT): %m");
1489 xpthread_barrier_wait (&b2);
1491 if (arg != NULL)
1492 xpthread_barrier_wait (&b2);
1494 ssize_t s;
1496 pthread_cleanup_push (cl, NULL);
1498 struct
1500 long int type;
1501 char mem[10];
1502 } m;
1503 int randnr;
1504 /* We need a positive random number. */
1506 randnr = random () % 64000;
1507 while (randnr <= 0);
1510 errno = 0;
1511 s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
1513 while (errno == EIDRM || errno == EINTR);
1515 pthread_cleanup_pop (0);
1517 msgctl (tempmsg, IPC_RMID, NULL);
1519 FAIL_EXIT1 ("msgrcv returned %zd", s);
1523 static void *
1524 tf_msgsnd (void *arg)
1526 if (arg == NULL)
1527 // XXX If somebody can provide a portable test case in which msgsnd()
1528 // blocks we can enable this test to run in both rounds.
1529 abort ();
1531 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1532 if (tempmsg == -1)
1534 if (errno == ENOSYS)
1536 printf ("msgget not supported\n");
1537 tf_usleep (arg);
1538 pthread_exit (NULL);
1540 else
1541 FAIL_EXIT1 ("msgget (IPC_PRIVATE, 0666 | IPC_CREAT): %m");
1544 xpthread_barrier_wait (&b2);
1546 xpthread_barrier_wait (&b2);
1548 pthread_cleanup_push (cl, NULL);
1550 struct
1552 long int type;
1553 char mem[1];
1554 } m;
1555 /* We need a positive random number. */
1557 m.type = random () % 64000;
1558 while (m.type <= 0);
1559 msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
1561 pthread_cleanup_pop (0);
1563 msgctl (tempmsg, IPC_RMID, NULL);
1565 FAIL_EXIT1 ("msgsnd returned");
1569 struct cancel_tests tests[] =
1571 ADD_TEST (read, 2, 0),
1572 ADD_TEST (readv, 2, 0),
1573 ADD_TEST (select, 2, 0),
1574 ADD_TEST (pselect, 2, 0),
1575 ADD_TEST (poll, 2, 0),
1576 ADD_TEST (ppoll, 2, 0),
1577 ADD_TEST (write, 2, 0),
1578 ADD_TEST (writev, 2, 0),
1579 ADD_TEST (sleep, 2, 0),
1580 ADD_TEST (usleep, 2, 0),
1581 ADD_TEST (nanosleep, 2, 0),
1582 ADD_TEST (wait, 2, 0),
1583 ADD_TEST (waitid, 2, 0),
1584 ADD_TEST (waitpid, 2, 0),
1585 ADD_TEST (sigpause, 2, 0),
1586 ADD_TEST (sigsuspend, 2, 0),
1587 ADD_TEST (sigwait, 2, 0),
1588 ADD_TEST (sigwaitinfo, 2, 0),
1589 ADD_TEST (sigtimedwait, 2, 0),
1590 ADD_TEST (pause, 2, 0),
1591 ADD_TEST (accept, 2, 0),
1592 ADD_TEST (send, 2, 0),
1593 ADD_TEST (recv, 2, 0),
1594 ADD_TEST (recvfrom, 2, 0),
1595 ADD_TEST (recvmsg, 2, 0),
1596 ADD_TEST (preadv, 2, 1),
1597 ADD_TEST (preadv2, 2, 1),
1598 ADD_TEST (pwritev, 2, 1),
1599 ADD_TEST (pwritev2, 2, 1),
1600 ADD_TEST (open, 2, 1),
1601 ADD_TEST (close, 2, 1),
1602 ADD_TEST (pread, 2, 1),
1603 ADD_TEST (pwrite, 2, 1),
1604 ADD_TEST (fsync, 2, 1),
1605 ADD_TEST (fdatasync, 2, 1),
1606 ADD_TEST (msync, 2, 1),
1607 ADD_TEST (sendto, 2, 1),
1608 ADD_TEST (sendmsg, 2, 1),
1609 ADD_TEST (creat, 2, 1),
1610 ADD_TEST (connect, 2, 1),
1611 ADD_TEST (tcdrain, 2, 1),
1612 ADD_TEST (msgrcv, 2, 0),
1613 ADD_TEST (msgsnd, 2, 1),
1615 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
1617 #include "tst-cancel4-common.c"