.
[glibc/history.git] / nptl / tst-cancel4.c
blob45df6ce07686b4d3431a3e8321790d732230feba
1 /* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 /* NOTE: this tests functionality beyond POSIX. POSIX does not allow
21 exit to be called more than once. */
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <limits.h>
26 #include <pthread.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <termios.h>
32 #include <unistd.h>
33 #include <sys/mman.h>
34 #include <sys/msg.h>
35 #include <sys/poll.h>
36 #include <sys/select.h>
37 #include <sys/socket.h>
38 #include <sys/uio.h>
39 #include <sys/un.h>
40 #include <sys/wait.h>
42 #include "pthreadP.h"
45 /* Since STREAMS are not supported in the standard Linux kernel and
46 there we don't advertise STREAMS as supported is no need to test
47 the STREAMS related functions. This affects
48 getmsg() getpmsg() putmsg()
49 putpmsg()
51 lockf() and fcntl() are tested in tst-cancel16.
53 pthread_join() is tested in tst-join5.
55 pthread_testcancel()'s only purpose is to allow cancellation. This
56 is tested in several places.
58 sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
60 mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
61 in tst-mqueue8{,x} tests.
63 aio_suspend() is tested in tst-cancel17.
65 clock_nanosleep() is tested in tst-cancel18.
68 /* Pipe descriptors. */
69 static int fds[2];
71 /* Temporary file descriptor, to be closed after each round. */
72 static int tempfd = -1;
73 static int tempfd2 = -1;
74 /* Name of temporary file to be removed after each round. */
75 static char *tempfname;
76 /* Temporary message queue. */
77 static int tempmsg = -1;
79 /* Often used barrier for two threads. */
80 static pthread_barrier_t b2;
83 #ifndef IPC_ADDVAL
84 # define IPC_ADDVAL 0
85 #endif
87 #define WRITE_BUFFER_SIZE 4096
89 /* Cleanup handling test. */
90 static int cl_called;
92 static void
93 cl (void *arg)
95 ++cl_called;
100 static void *
101 tf_read (void *arg)
103 int fd;
104 int r;
106 if (arg == NULL)
107 fd = fds[0];
108 else
110 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
111 tempfd = fd = mkstemp (fname);
112 if (fd == -1)
113 printf ("%s: mkstemp failed\n", __FUNCTION__);
114 unlink (fname);
116 r = pthread_barrier_wait (&b2);
117 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
119 printf ("%s: barrier_wait failed\n", __FUNCTION__);
120 exit (1);
124 r = pthread_barrier_wait (&b2);
125 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
127 printf ("%s: barrier_wait failed\n", __FUNCTION__);
128 exit (1);
131 ssize_t s;
132 pthread_cleanup_push (cl, NULL);
134 char buf[100];
135 s = read (fd, buf, sizeof (buf));
137 pthread_cleanup_pop (0);
139 printf ("%s: read returns with %zd\n", __FUNCTION__, s);
141 exit (1);
145 static void *
146 tf_readv (void *arg)
148 int fd;
149 int r;
151 if (arg == NULL)
152 fd = fds[0];
153 else
155 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
156 tempfd = fd = mkstemp (fname);
157 if (fd == -1)
158 printf ("%s: mkstemp failed\n", __FUNCTION__);
159 unlink (fname);
161 r = pthread_barrier_wait (&b2);
162 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
164 printf ("%s: barrier_wait failed\n", __FUNCTION__);
165 exit (1);
169 r = pthread_barrier_wait (&b2);
170 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
172 printf ("%s: barrier_wait failed\n", __FUNCTION__);
173 exit (1);
176 ssize_t s;
177 pthread_cleanup_push (cl, NULL);
179 char buf[100];
180 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
181 s = readv (fd, iov, 1);
183 pthread_cleanup_pop (0);
185 printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
187 exit (1);
191 static void *
192 tf_write (void *arg)
194 int fd;
195 int r;
197 if (arg == NULL)
198 fd = fds[1];
199 else
201 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
202 tempfd = fd = mkstemp (fname);
203 if (fd == -1)
204 printf ("%s: mkstemp failed\n", __FUNCTION__);
205 unlink (fname);
207 r = pthread_barrier_wait (&b2);
208 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
210 printf ("%s: barrier_wait failed\n", __FUNCTION__);
211 exit (1);
215 r = pthread_barrier_wait (&b2);
216 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
218 printf ("%s: barrier_wait failed\n", __FUNCTION__);
219 exit (1);
222 ssize_t s;
223 pthread_cleanup_push (cl, NULL);
225 char buf[WRITE_BUFFER_SIZE];
226 memset (buf, '\0', sizeof (buf));
227 s = write (fd, buf, sizeof (buf));
229 pthread_cleanup_pop (0);
231 printf ("%s: write returns with %zd\n", __FUNCTION__, s);
233 exit (1);
237 static void *
238 tf_writev (void *arg)
240 int fd;
241 int r;
243 if (arg == NULL)
244 fd = fds[1];
245 else
247 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
248 tempfd = fd = mkstemp (fname);
249 if (fd == -1)
250 printf ("%s: mkstemp failed\n", __FUNCTION__);
251 unlink (fname);
253 r = pthread_barrier_wait (&b2);
254 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
256 printf ("%s: barrier_wait failed\n", __FUNCTION__);
257 exit (1);
261 r = pthread_barrier_wait (&b2);
262 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
264 printf ("%s: barrier_wait failed\n", __FUNCTION__);
265 exit (1);
268 ssize_t s;
269 pthread_cleanup_push (cl, NULL);
271 char buf[WRITE_BUFFER_SIZE];
272 memset (buf, '\0', sizeof (buf));
273 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
274 s = writev (fd, iov, 1);
276 pthread_cleanup_pop (0);
278 printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
280 exit (1);
284 static void *
285 tf_sleep (void *arg)
287 int r = pthread_barrier_wait (&b2);
288 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
290 printf ("%s: barrier_wait failed\n", __FUNCTION__);
291 exit (1);
294 if (arg != NULL)
296 r = pthread_barrier_wait (&b2);
297 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
299 printf ("%s: barrier_wait failed\n", __FUNCTION__);
300 exit (1);
304 pthread_cleanup_push (cl, NULL);
306 sleep (arg == NULL ? 1000000 : 0);
308 pthread_cleanup_pop (0);
310 printf ("%s: sleep returns\n", __FUNCTION__);
312 exit (1);
316 static void *
317 tf_usleep (void *arg)
319 int r = pthread_barrier_wait (&b2);
320 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
322 printf ("%s: barrier_wait failed\n", __FUNCTION__);
323 exit (1);
326 if (arg != NULL)
328 r = pthread_barrier_wait (&b2);
329 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
331 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
332 exit (1);
336 pthread_cleanup_push (cl, NULL);
338 usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
340 pthread_cleanup_pop (0);
342 printf ("%s: usleep returns\n", __FUNCTION__);
344 exit (1);
348 static void *
349 tf_nanosleep (void *arg)
351 int r = pthread_barrier_wait (&b2);
352 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
354 printf ("%s: barrier_wait failed\n", __FUNCTION__);
355 exit (1);
358 if (arg != NULL)
360 r = pthread_barrier_wait (&b2);
361 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
363 printf ("%s: barrier_wait failed\n", __FUNCTION__);
364 exit (1);
368 pthread_cleanup_push (cl, NULL);
370 struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
371 TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
373 pthread_cleanup_pop (0);
375 printf ("%s: nanosleep returns\n", __FUNCTION__);
377 exit (1);
381 static void *
382 tf_select (void *arg)
384 int fd;
385 int r;
387 if (arg == NULL)
388 fd = fds[0];
389 else
391 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
392 tempfd = fd = mkstemp (fname);
393 if (fd == -1)
394 printf ("%s: mkstemp failed\n", __FUNCTION__);
395 unlink (fname);
397 r = pthread_barrier_wait (&b2);
398 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
400 printf ("%s: barrier_wait failed\n", __FUNCTION__);
401 exit (1);
405 r = pthread_barrier_wait (&b2);
406 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
408 printf ("%s: barrier_wait failed\n", __FUNCTION__);
409 exit (1);
412 fd_set rfs;
413 FD_ZERO (&rfs);
414 FD_SET (fd, &rfs);
416 int s;
417 pthread_cleanup_push (cl, NULL);
419 s = select (fd + 1, &rfs, NULL, NULL, NULL);
421 pthread_cleanup_pop (0);
423 printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
424 strerror (errno));
426 exit (1);
430 static void *
431 tf_pselect (void *arg)
433 int fd;
434 int r;
436 if (arg == NULL)
437 fd = fds[0];
438 else
440 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
441 tempfd = fd = mkstemp (fname);
442 if (fd == -1)
443 printf ("%s: mkstemp failed\n", __FUNCTION__);
444 unlink (fname);
446 r = pthread_barrier_wait (&b2);
447 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
449 printf ("%s: barrier_wait failed\n", __FUNCTION__);
450 exit (1);
454 r = pthread_barrier_wait (&b2);
455 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
457 printf ("%s: barrier_wait failed\n", __FUNCTION__);
458 exit (1);
461 fd_set rfs;
462 FD_ZERO (&rfs);
463 FD_SET (fd, &rfs);
465 int s;
466 pthread_cleanup_push (cl, NULL);
468 s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
470 pthread_cleanup_pop (0);
472 printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
473 strerror (errno));
475 exit (1);
479 static void *
480 tf_poll (void *arg)
482 int fd;
483 int r;
485 if (arg == NULL)
486 fd = fds[0];
487 else
489 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
490 tempfd = fd = mkstemp (fname);
491 if (fd == -1)
492 printf ("%s: mkstemp failed\n", __FUNCTION__);
493 unlink (fname);
495 r = pthread_barrier_wait (&b2);
496 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
498 printf ("%s: barrier_wait failed\n", __FUNCTION__);
499 exit (1);
503 r = pthread_barrier_wait (&b2);
504 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
506 printf ("%s: barrier_wait failed\n", __FUNCTION__);
507 exit (1);
510 struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
512 int s;
513 pthread_cleanup_push (cl, NULL);
515 s = poll (rfs, 1, -1);
517 pthread_cleanup_pop (0);
519 printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
520 strerror (errno));
522 exit (1);
526 static void *
527 tf_ppoll (void *arg)
529 int fd;
530 int r;
532 if (arg == NULL)
533 fd = fds[0];
534 else
536 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
537 tempfd = fd = mkstemp (fname);
538 if (fd == -1)
539 printf ("%s: mkstemp failed\n", __FUNCTION__);
540 unlink (fname);
542 r = pthread_barrier_wait (&b2);
543 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
545 printf ("%s: barrier_wait failed\n", __FUNCTION__);
546 exit (1);
550 r = pthread_barrier_wait (&b2);
551 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
553 printf ("%s: barrier_wait failed\n", __FUNCTION__);
554 exit (1);
557 struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
559 int s;
560 pthread_cleanup_push (cl, NULL);
562 s = ppoll (rfs, 1, NULL, NULL);
564 pthread_cleanup_pop (0);
566 printf ("%s: ppoll returns with %d (%s)\n", __FUNCTION__, s,
567 strerror (errno));
569 exit (1);
573 static void *
574 tf_wait (void *arg)
576 pid_t pid = fork ();
577 if (pid == -1)
579 puts ("fork failed");
580 exit (1);
583 if (pid == 0)
585 /* Make the program disappear after a while. */
586 if (arg == NULL)
587 sleep (10);
588 exit (0);
591 int r;
592 if (arg != NULL)
594 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
595 while (nanosleep (&ts, &ts) != 0)
596 continue;
598 r = pthread_barrier_wait (&b2);
599 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
601 printf ("%s: barrier_wait failed\n", __FUNCTION__);
602 exit (1);
606 r = pthread_barrier_wait (&b2);
607 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
609 printf ("%s: barrier_wait failed\n", __FUNCTION__);
610 exit (1);
613 int s;
614 pthread_cleanup_push (cl, NULL);
616 s = wait (NULL);
618 pthread_cleanup_pop (0);
620 printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
621 strerror (errno));
623 exit (1);
627 static void *
628 tf_waitpid (void *arg)
631 pid_t pid = fork ();
632 if (pid == -1)
634 puts ("fork failed");
635 exit (1);
638 if (pid == 0)
640 /* Make the program disappear after a while. */
641 if (arg == NULL)
642 sleep (10);
643 exit (0);
646 int r;
647 if (arg != NULL)
649 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
650 while (nanosleep (&ts, &ts) != 0)
651 continue;
653 r = pthread_barrier_wait (&b2);
654 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
656 printf ("%s: barrier_wait failed\n", __FUNCTION__);
657 exit (1);
661 r = pthread_barrier_wait (&b2);
662 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
664 printf ("%s: barrier_wait failed\n", __FUNCTION__);
665 exit (1);
668 int s;
669 pthread_cleanup_push (cl, NULL);
671 s = waitpid (-1, NULL, 0);
673 pthread_cleanup_pop (0);
675 printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
676 strerror (errno));
678 exit (1);
682 static void *
683 tf_waitid (void *arg)
685 pid_t pid = fork ();
686 if (pid == -1)
688 puts ("fork failed");
689 exit (1);
692 if (pid == 0)
694 /* Make the program disappear after a while. */
695 if (arg == NULL)
696 sleep (10);
697 exit (0);
700 int r;
701 if (arg != NULL)
703 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
704 while (nanosleep (&ts, &ts) != 0)
705 continue;
707 r = pthread_barrier_wait (&b2);
708 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
710 printf ("%s: barrier_wait failed\n", __FUNCTION__);
711 exit (1);
715 r = pthread_barrier_wait (&b2);
716 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
718 printf ("%s: barrier_wait failed\n", __FUNCTION__);
719 exit (1);
722 int s;
723 pthread_cleanup_push (cl, NULL);
725 #ifndef WEXITED
726 # define WEXITED 0
727 #endif
728 siginfo_t si;
729 s = waitid (P_PID, pid, &si, WEXITED);
731 pthread_cleanup_pop (0);
733 printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
734 strerror (errno));
736 exit (1);
740 static void *
741 tf_sigpause (void *arg)
743 int r = pthread_barrier_wait (&b2);
744 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
746 printf ("%s: barrier_wait failed\n", __FUNCTION__);
747 exit (1);
750 if (arg != NULL)
752 r = pthread_barrier_wait (&b2);
753 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
755 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
756 exit (1);
760 pthread_cleanup_push (cl, NULL);
762 /* Just for fun block the cancellation signal. We need to use
763 __xpg_sigpause since otherwise we will get the BSD version. */
764 __xpg_sigpause (SIGCANCEL);
766 pthread_cleanup_pop (0);
768 printf ("%s: sigpause returned\n", __FUNCTION__);
770 exit (1);
774 static void *
775 tf_sigsuspend (void *arg)
777 int r = pthread_barrier_wait (&b2);
778 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
780 printf ("%s: barrier_wait failed\n", __FUNCTION__);
781 exit (1);
784 if (arg != NULL)
786 r = pthread_barrier_wait (&b2);
787 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
789 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
790 exit (1);
794 pthread_cleanup_push (cl, NULL);
796 /* Just for fun block all signals. */
797 sigset_t mask;
798 sigfillset (&mask);
799 sigsuspend (&mask);
801 pthread_cleanup_pop (0);
803 printf ("%s: sigsuspend returned\n", __FUNCTION__);
805 exit (1);
809 static void *
810 tf_sigwait (void *arg)
812 int r = pthread_barrier_wait (&b2);
813 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
815 printf ("%s: barrier_wait failed\n", __FUNCTION__);
816 exit (1);
819 if (arg != NULL)
821 r = pthread_barrier_wait (&b2);
822 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
824 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
825 exit (1);
829 /* Block SIGUSR1. */
830 sigset_t mask;
831 sigemptyset (&mask);
832 sigaddset (&mask, SIGUSR1);
833 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
835 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
836 exit (1);
839 int sig;
840 pthread_cleanup_push (cl, NULL);
842 /* Wait for SIGUSR1. */
843 sigwait (&mask, &sig);
845 pthread_cleanup_pop (0);
847 printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
849 exit (1);
853 static void *
854 tf_sigwaitinfo (void *arg)
856 int r = pthread_barrier_wait (&b2);
857 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
859 printf ("%s: barrier_wait failed\n", __FUNCTION__);
860 exit (1);
863 if (arg != NULL)
865 r = pthread_barrier_wait (&b2);
866 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
868 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
869 exit (1);
873 /* Block SIGUSR1. */
874 sigset_t mask;
875 sigemptyset (&mask);
876 sigaddset (&mask, SIGUSR1);
877 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
879 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
880 exit (1);
883 siginfo_t info;
884 pthread_cleanup_push (cl, NULL);
886 /* Wait for SIGUSR1. */
887 sigwaitinfo (&mask, &info);
889 pthread_cleanup_pop (0);
891 printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
892 info.si_signo);
894 exit (1);
898 static void *
899 tf_sigtimedwait (void *arg)
901 int r = pthread_barrier_wait (&b2);
902 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
904 printf ("%s: barrier_wait failed\n", __FUNCTION__);
905 exit (1);
908 if (arg != NULL)
910 r = pthread_barrier_wait (&b2);
911 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
913 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
914 exit (1);
918 /* Block SIGUSR1. */
919 sigset_t mask;
920 sigemptyset (&mask);
921 sigaddset (&mask, SIGUSR1);
922 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
924 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
925 exit (1);
928 /* Wait for SIGUSR1. */
929 siginfo_t info;
930 struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
931 pthread_cleanup_push (cl, NULL);
933 sigtimedwait (&mask, &info, &ts);
935 pthread_cleanup_pop (0);
937 printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
938 info.si_signo);
940 exit (1);
944 static void *
945 tf_pause (void *arg)
947 int r = pthread_barrier_wait (&b2);
948 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
950 printf ("%s: barrier_wait failed\n", __FUNCTION__);
951 exit (1);
954 if (arg != NULL)
956 r = pthread_barrier_wait (&b2);
957 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
959 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
960 exit (1);
964 pthread_cleanup_push (cl, NULL);
966 pause ();
968 pthread_cleanup_pop (0);
970 printf ("%s: pause returned\n", __FUNCTION__);
972 exit (1);
976 static void *
977 tf_accept (void *arg)
979 struct sockaddr_un sun;
980 /* To test a non-blocking accept call we make the call file by using
981 a datagrame socket. */
982 int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
984 tempfd = socket (AF_UNIX, pf, 0);
985 if (tempfd == -1)
987 printf ("%s: socket call failed\n", __FUNCTION__);
988 exit (1);
991 int tries = 0;
994 if (++tries > 10)
996 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
999 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
1000 if (mktemp (sun.sun_path) == NULL)
1002 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1003 exit (1);
1006 sun.sun_family = AF_UNIX;
1008 while (bind (tempfd, (struct sockaddr *) &sun,
1009 offsetof (struct sockaddr_un, sun_path)
1010 + strlen (sun.sun_path) + 1) != 0);
1012 unlink (sun.sun_path);
1014 listen (tempfd, 5);
1016 socklen_t len = sizeof (sun);
1018 int r = pthread_barrier_wait (&b2);
1019 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1021 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1022 exit (1);
1025 if (arg != NULL)
1027 r = pthread_barrier_wait (&b2);
1028 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1030 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1031 exit (1);
1035 pthread_cleanup_push (cl, NULL);
1037 accept (tempfd, (struct sockaddr *) &sun, &len);
1039 pthread_cleanup_pop (0);
1041 printf ("%s: accept returned\n", __FUNCTION__);
1043 exit (1);
1047 static void *
1048 tf_send (void *arg)
1050 struct sockaddr_un sun;
1052 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1053 if (tempfd == -1)
1055 printf ("%s: first socket call failed\n", __FUNCTION__);
1056 exit (1);
1059 int tries = 0;
1062 if (++tries > 10)
1064 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1067 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1068 if (mktemp (sun.sun_path) == NULL)
1070 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1071 exit (1);
1074 sun.sun_family = AF_UNIX;
1076 while (bind (tempfd, (struct sockaddr *) &sun,
1077 offsetof (struct sockaddr_un, sun_path)
1078 + strlen (sun.sun_path) + 1) != 0);
1080 listen (tempfd, 5);
1082 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1083 if (tempfd2 == -1)
1085 printf ("%s: second socket call failed\n", __FUNCTION__);
1086 exit (1);
1089 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1091 printf ("%s: connect failed\n", __FUNCTION__);
1092 exit(1);
1095 unlink (sun.sun_path);
1097 int r = pthread_barrier_wait (&b2);
1098 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1100 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1101 exit (1);
1104 if (arg != NULL)
1106 r = pthread_barrier_wait (&b2);
1107 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1109 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1110 exit (1);
1114 pthread_cleanup_push (cl, NULL);
1116 /* Very large block, so that the send call blocks. */
1117 char mem[700000];
1119 send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
1121 pthread_cleanup_pop (0);
1123 printf ("%s: send returned\n", __FUNCTION__);
1125 exit (1);
1129 static void *
1130 tf_recv (void *arg)
1132 struct sockaddr_un sun;
1134 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1135 if (tempfd == -1)
1137 printf ("%s: first socket call failed\n", __FUNCTION__);
1138 exit (1);
1141 int tries = 0;
1144 if (++tries > 10)
1146 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1149 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
1150 if (mktemp (sun.sun_path) == NULL)
1152 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1153 exit (1);
1156 sun.sun_family = AF_UNIX;
1158 while (bind (tempfd, (struct sockaddr *) &sun,
1159 offsetof (struct sockaddr_un, sun_path)
1160 + strlen (sun.sun_path) + 1) != 0);
1162 listen (tempfd, 5);
1164 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1165 if (tempfd2 == -1)
1167 printf ("%s: second socket call failed\n", __FUNCTION__);
1168 exit (1);
1171 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1173 printf ("%s: connect failed\n", __FUNCTION__);
1174 exit(1);
1177 unlink (sun.sun_path);
1179 int r = pthread_barrier_wait (&b2);
1180 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1182 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1183 exit (1);
1186 if (arg != NULL)
1188 r = pthread_barrier_wait (&b2);
1189 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1191 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1192 exit (1);
1196 pthread_cleanup_push (cl, NULL);
1198 char mem[70];
1200 recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
1202 pthread_cleanup_pop (0);
1204 printf ("%s: recv returned\n", __FUNCTION__);
1206 exit (1);
1210 static void *
1211 tf_recvfrom (void *arg)
1213 struct sockaddr_un sun;
1215 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1216 if (tempfd == -1)
1218 printf ("%s: first socket call failed\n", __FUNCTION__);
1219 exit (1);
1222 int tries = 0;
1225 if (++tries > 10)
1227 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1230 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
1231 if (mktemp (sun.sun_path) == NULL)
1233 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1234 exit (1);
1237 sun.sun_family = AF_UNIX;
1239 while (bind (tempfd, (struct sockaddr *) &sun,
1240 offsetof (struct sockaddr_un, sun_path)
1241 + strlen (sun.sun_path) + 1) != 0);
1243 tempfname = strdup (sun.sun_path);
1245 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1246 if (tempfd2 == -1)
1248 printf ("%s: second socket call failed\n", __FUNCTION__);
1249 exit (1);
1252 int r = pthread_barrier_wait (&b2);
1253 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1255 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1256 exit (1);
1259 if (arg != NULL)
1261 r = pthread_barrier_wait (&b2);
1262 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1264 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1265 exit (1);
1269 pthread_cleanup_push (cl, NULL);
1271 char mem[70];
1272 socklen_t len = sizeof (sun);
1274 recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
1275 (struct sockaddr *) &sun, &len);
1277 pthread_cleanup_pop (0);
1279 printf ("%s: recvfrom returned\n", __FUNCTION__);
1281 exit (1);
1285 static void *
1286 tf_recvmsg (void *arg)
1288 struct sockaddr_un sun;
1290 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1291 if (tempfd == -1)
1293 printf ("%s: first socket call failed\n", __FUNCTION__);
1294 exit (1);
1297 int tries = 0;
1300 if (++tries > 10)
1302 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1305 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
1306 if (mktemp (sun.sun_path) == NULL)
1308 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1309 exit (1);
1312 sun.sun_family = AF_UNIX;
1314 while (bind (tempfd, (struct sockaddr *) &sun,
1315 offsetof (struct sockaddr_un, sun_path)
1316 + strlen (sun.sun_path) + 1) != 0);
1318 tempfname = strdup (sun.sun_path);
1320 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1321 if (tempfd2 == -1)
1323 printf ("%s: second socket call failed\n", __FUNCTION__);
1324 exit (1);
1327 int r = pthread_barrier_wait (&b2);
1328 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1330 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1331 exit (1);
1334 if (arg != NULL)
1336 r = pthread_barrier_wait (&b2);
1337 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1339 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1340 exit (1);
1344 pthread_cleanup_push (cl, NULL);
1346 char mem[70];
1347 struct iovec iov[1];
1348 iov[0].iov_base = mem;
1349 iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
1351 struct msghdr m;
1352 m.msg_name = &sun;
1353 m.msg_namelen = sizeof (sun);
1354 m.msg_iov = iov;
1355 m.msg_iovlen = 1;
1356 m.msg_control = NULL;
1357 m.msg_controllen = 0;
1359 recvmsg (tempfd2, &m, 0);
1361 pthread_cleanup_pop (0);
1363 printf ("%s: recvmsg returned\n", __FUNCTION__);
1365 exit (1);
1369 static void *
1370 tf_open (void *arg)
1372 if (arg == NULL)
1373 // XXX If somebody can provide a portable test case in which open()
1374 // blocks we can enable this test to run in both rounds.
1375 abort ();
1377 int r = pthread_barrier_wait (&b2);
1378 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1380 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1381 exit (1);
1384 r = pthread_barrier_wait (&b2);
1385 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1387 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1388 exit (1);
1391 pthread_cleanup_push (cl, NULL);
1393 open ("Makefile", O_RDONLY);
1395 pthread_cleanup_pop (0);
1397 printf ("%s: open returned\n", __FUNCTION__);
1399 exit (1);
1403 static void *
1404 tf_close (void *arg)
1406 if (arg == NULL)
1407 // XXX If somebody can provide a portable test case in which close()
1408 // blocks we can enable this test to run in both rounds.
1409 abort ();
1411 char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
1412 tempfd = mkstemp (fname);
1413 if (tempfd == -1)
1415 printf ("%s: mkstemp failed\n", __FUNCTION__);
1416 exit (1);
1418 unlink (fname);
1420 int r = pthread_barrier_wait (&b2);
1421 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1423 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1424 exit (1);
1427 r = pthread_barrier_wait (&b2);
1428 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1430 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1431 exit (1);
1434 pthread_cleanup_push (cl, NULL);
1436 close (tempfd);
1438 pthread_cleanup_pop (0);
1440 printf ("%s: close returned\n", __FUNCTION__);
1442 exit (1);
1446 static void *
1447 tf_pread (void *arg)
1449 if (arg == NULL)
1450 // XXX If somebody can provide a portable test case in which pread()
1451 // blocks we can enable this test to run in both rounds.
1452 abort ();
1454 tempfd = open ("Makefile", O_RDONLY);
1455 if (tempfd == -1)
1457 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1458 exit (1);
1461 int r = pthread_barrier_wait (&b2);
1462 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1464 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1465 exit (1);
1468 r = pthread_barrier_wait (&b2);
1469 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1471 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1472 exit (1);
1475 pthread_cleanup_push (cl, NULL);
1477 char mem[10];
1478 pread (tempfd, mem, sizeof (mem), 0);
1480 pthread_cleanup_pop (0);
1482 printf ("%s: pread returned\n", __FUNCTION__);
1484 exit (1);
1488 static void *
1489 tf_pwrite (void *arg)
1491 if (arg == NULL)
1492 // XXX If somebody can provide a portable test case in which pwrite()
1493 // blocks we can enable this test to run in both rounds.
1494 abort ();
1496 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1497 tempfd = mkstemp (fname);
1498 if (tempfd == -1)
1500 printf ("%s: mkstemp failed\n", __FUNCTION__);
1501 exit (1);
1503 unlink (fname);
1505 int r = pthread_barrier_wait (&b2);
1506 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1508 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1509 exit (1);
1512 r = pthread_barrier_wait (&b2);
1513 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1515 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1516 exit (1);
1519 pthread_cleanup_push (cl, NULL);
1521 char mem[10];
1522 pwrite (tempfd, mem, sizeof (mem), 0);
1524 pthread_cleanup_pop (0);
1526 printf ("%s: pwrite returned\n", __FUNCTION__);
1528 exit (1);
1532 static void *
1533 tf_fsync (void *arg)
1535 if (arg == NULL)
1536 // XXX If somebody can provide a portable test case in which fsync()
1537 // blocks we can enable this test to run in both rounds.
1538 abort ();
1540 tempfd = open ("Makefile", O_RDONLY);
1541 if (tempfd == -1)
1543 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1544 exit (1);
1547 int r = pthread_barrier_wait (&b2);
1548 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1550 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1551 exit (1);
1554 r = pthread_barrier_wait (&b2);
1555 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1557 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1558 exit (1);
1561 pthread_cleanup_push (cl, NULL);
1563 fsync (tempfd);
1565 pthread_cleanup_pop (0);
1567 printf ("%s: fsync returned\n", __FUNCTION__);
1569 exit (1);
1573 static void *
1574 tf_fdatasync (void *arg)
1576 if (arg == NULL)
1577 // XXX If somebody can provide a portable test case in which fdatasync()
1578 // blocks we can enable this test to run in both rounds.
1579 abort ();
1581 tempfd = open ("Makefile", O_RDONLY);
1582 if (tempfd == -1)
1584 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1585 exit (1);
1588 int r = pthread_barrier_wait (&b2);
1589 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1591 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1592 exit (1);
1595 r = pthread_barrier_wait (&b2);
1596 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1598 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1599 exit (1);
1602 pthread_cleanup_push (cl, NULL);
1604 fdatasync (tempfd);
1606 pthread_cleanup_pop (0);
1608 printf ("%s: fdatasync returned\n", __FUNCTION__);
1610 exit (1);
1614 static void *
1615 tf_msync (void *arg)
1617 if (arg == NULL)
1618 // XXX If somebody can provide a portable test case in which msync()
1619 // blocks we can enable this test to run in both rounds.
1620 abort ();
1622 tempfd = open ("Makefile", O_RDONLY);
1623 if (tempfd == -1)
1625 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1626 exit (1);
1628 void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
1629 if (p == MAP_FAILED)
1631 printf ("%s: mmap failed\n", __FUNCTION__);
1632 exit (1);
1635 int r = pthread_barrier_wait (&b2);
1636 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1638 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1639 exit (1);
1642 r = pthread_barrier_wait (&b2);
1643 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1645 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1646 exit (1);
1649 pthread_cleanup_push (cl, NULL);
1651 msync (p, 10, 0);
1653 pthread_cleanup_pop (0);
1655 printf ("%s: msync returned\n", __FUNCTION__);
1657 exit (1);
1661 static void *
1662 tf_sendto (void *arg)
1664 if (arg == NULL)
1665 // XXX If somebody can provide a portable test case in which sendto()
1666 // blocks we can enable this test to run in both rounds.
1667 abort ();
1669 struct sockaddr_un sun;
1671 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1672 if (tempfd == -1)
1674 printf ("%s: first socket call failed\n", __FUNCTION__);
1675 exit (1);
1678 int tries = 0;
1681 if (++tries > 10)
1683 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1686 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1687 if (mktemp (sun.sun_path) == NULL)
1689 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1690 exit (1);
1693 sun.sun_family = AF_UNIX;
1695 while (bind (tempfd, (struct sockaddr *) &sun,
1696 offsetof (struct sockaddr_un, sun_path)
1697 + strlen (sun.sun_path) + 1) != 0);
1698 tempfname = strdup (sun.sun_path);
1700 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1701 if (tempfd2 == -1)
1703 printf ("%s: second socket call failed\n", __FUNCTION__);
1704 exit (1);
1707 int r = pthread_barrier_wait (&b2);
1708 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1710 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1711 exit (1);
1714 r = pthread_barrier_wait (&b2);
1715 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1717 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1718 exit (1);
1721 pthread_cleanup_push (cl, NULL);
1723 char mem[1];
1725 sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
1726 (struct sockaddr *) &sun,
1727 offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
1729 pthread_cleanup_pop (0);
1731 printf ("%s: sendto returned\n", __FUNCTION__);
1733 exit (1);
1737 static void *
1738 tf_sendmsg (void *arg)
1740 if (arg == NULL)
1741 // XXX If somebody can provide a portable test case in which sendmsg()
1742 // blocks we can enable this test to run in both rounds.
1743 abort ();
1745 struct sockaddr_un sun;
1747 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1748 if (tempfd == -1)
1750 printf ("%s: first socket call failed\n", __FUNCTION__);
1751 exit (1);
1754 int tries = 0;
1757 if (++tries > 10)
1759 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1762 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1763 if (mktemp (sun.sun_path) == NULL)
1765 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1766 exit (1);
1769 sun.sun_family = AF_UNIX;
1771 while (bind (tempfd, (struct sockaddr *) &sun,
1772 offsetof (struct sockaddr_un, sun_path)
1773 + strlen (sun.sun_path) + 1) != 0);
1774 tempfname = strdup (sun.sun_path);
1776 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1777 if (tempfd2 == -1)
1779 printf ("%s: second socket call failed\n", __FUNCTION__);
1780 exit (1);
1783 int r = pthread_barrier_wait (&b2);
1784 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1786 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1787 exit (1);
1790 r = pthread_barrier_wait (&b2);
1791 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1793 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1794 exit (1);
1797 pthread_cleanup_push (cl, NULL);
1799 char mem[1];
1800 struct iovec iov[1];
1801 iov[0].iov_base = mem;
1802 iov[0].iov_len = 1;
1804 struct msghdr m;
1805 m.msg_name = &sun;
1806 m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1807 + strlen (sun.sun_path) + 1);
1808 m.msg_iov = iov;
1809 m.msg_iovlen = 1;
1810 m.msg_control = NULL;
1811 m.msg_controllen = 0;
1813 sendmsg (tempfd2, &m, 0);
1815 pthread_cleanup_pop (0);
1817 printf ("%s: sendmsg returned\n", __FUNCTION__);
1819 exit (1);
1823 static void *
1824 tf_creat (void *arg)
1826 if (arg == NULL)
1827 // XXX If somebody can provide a portable test case in which sendmsg()
1828 // blocks we can enable this test to run in both rounds.
1829 abort ();
1831 int r = pthread_barrier_wait (&b2);
1832 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1834 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1835 exit (1);
1838 r = pthread_barrier_wait (&b2);
1839 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1841 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1842 exit (1);
1845 pthread_cleanup_push (cl, NULL);
1847 creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1849 pthread_cleanup_pop (0);
1851 printf ("%s: creat returned\n", __FUNCTION__);
1853 exit (1);
1857 static void *
1858 tf_connect (void *arg)
1860 if (arg == NULL)
1861 // XXX If somebody can provide a portable test case in which connect()
1862 // blocks we can enable this test to run in both rounds.
1863 abort ();
1865 struct sockaddr_un sun;
1867 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1868 if (tempfd == -1)
1870 printf ("%s: first socket call failed\n", __FUNCTION__);
1871 exit (1);
1874 int tries = 0;
1877 if (++tries > 10)
1879 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1882 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1883 if (mktemp (sun.sun_path) == NULL)
1885 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1886 exit (1);
1889 sun.sun_family = AF_UNIX;
1891 while (bind (tempfd, (struct sockaddr *) &sun,
1892 offsetof (struct sockaddr_un, sun_path)
1893 + strlen (sun.sun_path) + 1) != 0);
1894 tempfname = strdup (sun.sun_path);
1896 listen (tempfd, 5);
1898 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1899 if (tempfd2 == -1)
1901 printf ("%s: second socket call failed\n", __FUNCTION__);
1902 exit (1);
1905 int r = pthread_barrier_wait (&b2);
1906 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1908 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1909 exit (1);
1912 if (arg != NULL)
1914 r = pthread_barrier_wait (&b2);
1915 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1917 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1918 exit (1);
1922 pthread_cleanup_push (cl, NULL);
1924 connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1926 pthread_cleanup_pop (0);
1928 printf ("%s: connect returned\n", __FUNCTION__);
1930 exit (1);
1934 static void *
1935 tf_tcdrain (void *arg)
1937 if (arg == NULL)
1938 // XXX If somebody can provide a portable test case in which tcdrain()
1939 // blocks we can enable this test to run in both rounds.
1940 abort ();
1942 int r = pthread_barrier_wait (&b2);
1943 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1945 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1946 exit (1);
1949 if (arg != NULL)
1951 r = pthread_barrier_wait (&b2);
1952 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1954 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1955 exit (1);
1959 pthread_cleanup_push (cl, NULL);
1961 /* Regardless of stderr being a terminal, the tcdrain call should be
1962 canceled. */
1963 tcdrain (STDERR_FILENO);
1965 pthread_cleanup_pop (0);
1967 printf ("%s: tcdrain returned\n", __FUNCTION__);
1969 exit (1);
1973 static void *
1974 tf_msgrcv (void *arg)
1976 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1977 if (tempmsg == -1)
1979 printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
1980 exit (1);
1983 int r = pthread_barrier_wait (&b2);
1984 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1986 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1987 exit (1);
1990 if (arg != NULL)
1992 r = pthread_barrier_wait (&b2);
1993 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1995 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1996 exit (1);
2000 ssize_t s;
2002 pthread_cleanup_push (cl, NULL);
2004 struct
2006 long int type;
2007 char mem[10];
2008 } m;
2009 int randnr;
2010 /* We need a positive random number. */
2012 randnr = random () % 64000;
2013 while (randnr <= 0);
2016 errno = 0;
2017 s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
2019 while (errno == EIDRM || errno == EINTR);
2021 pthread_cleanup_pop (0);
2023 printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
2025 msgctl (tempmsg, IPC_RMID, NULL);
2027 exit (1);
2031 static void *
2032 tf_msgsnd (void *arg)
2034 if (arg == NULL)
2035 // XXX If somebody can provide a portable test case in which msgsnd()
2036 // blocks we can enable this test to run in both rounds.
2037 abort ();
2039 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
2040 if (tempmsg == -1)
2042 printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
2043 exit (1);
2046 int r = pthread_barrier_wait (&b2);
2047 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2049 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2050 exit (1);
2053 r = pthread_barrier_wait (&b2);
2054 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2056 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
2057 exit (1);
2060 pthread_cleanup_push (cl, NULL);
2062 struct
2064 long int type;
2065 char mem[1];
2066 } m;
2067 /* We need a positive random number. */
2069 m.type = random () % 64000;
2070 while (m.type <= 0);
2071 msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
2073 pthread_cleanup_pop (0);
2075 printf ("%s: msgsnd returned\n", __FUNCTION__);
2077 msgctl (tempmsg, IPC_RMID, NULL);
2079 exit (1);
2083 static struct
2085 const char *name;
2086 void *(*tf) (void *);
2087 int nb;
2088 int only_early;
2089 } tests[] =
2091 #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
2092 ADD_TEST (read, 2, 0),
2093 ADD_TEST (readv, 2, 0),
2094 ADD_TEST (select, 2, 0),
2095 ADD_TEST (pselect, 2, 0),
2096 ADD_TEST (poll, 2, 0),
2097 ADD_TEST (ppoll, 2, 0),
2098 ADD_TEST (write, 2, 0),
2099 ADD_TEST (writev, 2, 0),
2100 ADD_TEST (sleep, 2, 0),
2101 ADD_TEST (usleep, 2, 0),
2102 ADD_TEST (nanosleep, 2, 0),
2103 ADD_TEST (wait, 2, 0),
2104 ADD_TEST (waitid, 2, 0),
2105 ADD_TEST (waitpid, 2, 0),
2106 ADD_TEST (sigpause, 2, 0),
2107 ADD_TEST (sigsuspend, 2, 0),
2108 ADD_TEST (sigwait, 2, 0),
2109 ADD_TEST (sigwaitinfo, 2, 0),
2110 ADD_TEST (sigtimedwait, 2, 0),
2111 ADD_TEST (pause, 2, 0),
2112 ADD_TEST (accept, 2, 0),
2113 ADD_TEST (send, 2, 0),
2114 ADD_TEST (recv, 2, 0),
2115 ADD_TEST (recvfrom, 2, 0),
2116 ADD_TEST (recvmsg, 2, 0),
2117 ADD_TEST (open, 2, 1),
2118 ADD_TEST (close, 2, 1),
2119 ADD_TEST (pread, 2, 1),
2120 ADD_TEST (pwrite, 2, 1),
2121 ADD_TEST (fsync, 2, 1),
2122 ADD_TEST (fdatasync, 2, 1),
2123 ADD_TEST (msync, 2, 1),
2124 ADD_TEST (sendto, 2, 1),
2125 ADD_TEST (sendmsg, 2, 1),
2126 ADD_TEST (creat, 2, 1),
2127 ADD_TEST (connect, 2, 1),
2128 ADD_TEST (tcdrain, 2, 1),
2129 ADD_TEST (msgrcv, 2, 0),
2130 ADD_TEST (msgsnd, 2, 1),
2132 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
2135 static int
2136 do_test (void)
2138 int val;
2139 socklen_t len;
2141 if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
2143 perror ("socketpair");
2144 exit (1);
2147 val = 1;
2148 len = sizeof(val);
2149 setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2150 if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
2152 perror ("getsockopt");
2153 exit (1);
2155 if (val >= WRITE_BUFFER_SIZE)
2157 puts ("minimum write buffer size too large");
2158 exit (1);
2160 setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2162 int result = 0;
2163 size_t cnt;
2164 for (cnt = 0; cnt < ntest_tf; ++cnt)
2166 if (tests[cnt].only_early)
2167 continue;
2169 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2171 puts ("b2 init failed");
2172 exit (1);
2175 /* Reset the counter for the cleanup handler. */
2176 cl_called = 0;
2178 pthread_t th;
2179 if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
2181 printf ("create for '%s' test failed\n", tests[cnt].name);
2182 result = 1;
2183 continue;
2186 int r = pthread_barrier_wait (&b2);
2187 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2189 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2190 result = 1;
2191 continue;
2194 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
2195 while (nanosleep (&ts, &ts) != 0)
2196 continue;
2198 if (pthread_cancel (th) != 0)
2200 printf ("cancel for '%s' failed\n", tests[cnt].name);
2201 result = 1;
2202 continue;
2205 void *status;
2206 if (pthread_join (th, &status) != 0)
2208 printf ("join for '%s' failed\n", tests[cnt].name);
2209 result = 1;
2210 continue;
2212 if (status != PTHREAD_CANCELED)
2214 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2215 result = 1;
2216 continue;
2219 if (pthread_barrier_destroy (&b2) != 0)
2221 puts ("barrier_destroy failed");
2222 result = 1;
2223 continue;
2226 if (cl_called == 0)
2228 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2229 result = 1;
2230 continue;
2232 if (cl_called > 1)
2234 printf ("cleanup handler called more than once for '%s'\n",
2235 tests[cnt].name);
2236 result = 1;
2237 continue;
2240 printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
2242 if (tempfd != -1)
2244 close (tempfd);
2245 tempfd = -1;
2247 if (tempfd2 != -1)
2249 close (tempfd2);
2250 tempfd2 = -1;
2252 if (tempfname != NULL)
2254 unlink (tempfname);
2255 free (tempfname);
2256 tempfname = NULL;
2258 if (tempmsg != -1)
2260 msgctl (tempmsg, IPC_RMID, NULL);
2261 tempmsg = -1;
2265 for (cnt = 0; cnt < ntest_tf; ++cnt)
2267 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2269 puts ("b2 init failed");
2270 exit (1);
2273 /* Reset the counter for the cleanup handler. */
2274 cl_called = 0;
2276 pthread_t th;
2277 if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
2279 printf ("create for '%s' test failed\n", tests[cnt].name);
2280 result = 1;
2281 continue;
2284 int r = pthread_barrier_wait (&b2);
2285 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2287 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2288 result = 1;
2289 continue;
2292 if (pthread_cancel (th) != 0)
2294 printf ("cancel for '%s' failed\n", tests[cnt].name);
2295 result = 1;
2296 continue;
2299 r = pthread_barrier_wait (&b2);
2300 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2302 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2303 result = 1;
2304 continue;
2307 void *status;
2308 if (pthread_join (th, &status) != 0)
2310 printf ("join for '%s' failed\n", tests[cnt].name);
2311 result = 1;
2312 continue;
2314 if (status != PTHREAD_CANCELED)
2316 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2317 result = 1;
2318 continue;
2321 if (pthread_barrier_destroy (&b2) != 0)
2323 puts ("barrier_destroy failed");
2324 result = 1;
2325 continue;
2328 if (cl_called == 0)
2330 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2331 result = 1;
2332 continue;
2334 if (cl_called > 1)
2336 printf ("cleanup handler called more than once for '%s'\n",
2337 tests[cnt].name);
2338 result = 1;
2339 continue;
2342 printf ("early cancel test of '%s' successful\n", tests[cnt].name);
2344 if (tempfd != -1)
2346 close (tempfd);
2347 tempfd = -1;
2349 if (tempfd2 != -1)
2351 close (tempfd2);
2352 tempfd2 = -1;
2354 if (tempfname != NULL)
2356 unlink (tempfname);
2357 free (tempfname);
2358 tempfname = NULL;
2360 if (tempmsg != -1)
2362 msgctl (tempmsg, IPC_RMID, NULL);
2363 tempmsg = -1;
2367 return result;
2370 #define TIMEOUT 60
2371 #define TEST_FUNCTION do_test ()
2372 #include "../test-skeleton.c"