2.4.90-20
[glibc.git] / nptl / tst-cancel4.c
blob73cfa44614f9d942976d5ad9ce52b53df17dc081
1 /* Copyright (C) 2002, 2003, 2004, 2006 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_msync (void *arg)
1576 if (arg == NULL)
1577 // XXX If somebody can provide a portable test case in which msync()
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);
1587 void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
1588 if (p == MAP_FAILED)
1590 printf ("%s: mmap failed\n", __FUNCTION__);
1591 exit (1);
1594 int r = pthread_barrier_wait (&b2);
1595 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1597 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1598 exit (1);
1601 r = pthread_barrier_wait (&b2);
1602 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1604 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1605 exit (1);
1608 pthread_cleanup_push (cl, NULL);
1610 msync (p, 10, 0);
1612 pthread_cleanup_pop (0);
1614 printf ("%s: msync returned\n", __FUNCTION__);
1616 exit (1);
1620 static void *
1621 tf_sendto (void *arg)
1623 if (arg == NULL)
1624 // XXX If somebody can provide a portable test case in which sendto()
1625 // blocks we can enable this test to run in both rounds.
1626 abort ();
1628 struct sockaddr_un sun;
1630 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1631 if (tempfd == -1)
1633 printf ("%s: first socket call failed\n", __FUNCTION__);
1634 exit (1);
1637 int tries = 0;
1640 if (++tries > 10)
1642 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1645 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1646 if (mktemp (sun.sun_path) == NULL)
1648 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1649 exit (1);
1652 sun.sun_family = AF_UNIX;
1654 while (bind (tempfd, (struct sockaddr *) &sun,
1655 offsetof (struct sockaddr_un, sun_path)
1656 + strlen (sun.sun_path) + 1) != 0);
1657 tempfname = strdup (sun.sun_path);
1659 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1660 if (tempfd2 == -1)
1662 printf ("%s: second socket call failed\n", __FUNCTION__);
1663 exit (1);
1666 int r = pthread_barrier_wait (&b2);
1667 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1669 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1670 exit (1);
1673 r = pthread_barrier_wait (&b2);
1674 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1676 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1677 exit (1);
1680 pthread_cleanup_push (cl, NULL);
1682 char mem[1];
1684 sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
1685 (struct sockaddr *) &sun,
1686 offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
1688 pthread_cleanup_pop (0);
1690 printf ("%s: sendto returned\n", __FUNCTION__);
1692 exit (1);
1696 static void *
1697 tf_sendmsg (void *arg)
1699 if (arg == NULL)
1700 // XXX If somebody can provide a portable test case in which sendmsg()
1701 // blocks we can enable this test to run in both rounds.
1702 abort ();
1704 struct sockaddr_un sun;
1706 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1707 if (tempfd == -1)
1709 printf ("%s: first socket call failed\n", __FUNCTION__);
1710 exit (1);
1713 int tries = 0;
1716 if (++tries > 10)
1718 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1721 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1722 if (mktemp (sun.sun_path) == NULL)
1724 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1725 exit (1);
1728 sun.sun_family = AF_UNIX;
1730 while (bind (tempfd, (struct sockaddr *) &sun,
1731 offsetof (struct sockaddr_un, sun_path)
1732 + strlen (sun.sun_path) + 1) != 0);
1733 tempfname = strdup (sun.sun_path);
1735 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1736 if (tempfd2 == -1)
1738 printf ("%s: second socket call failed\n", __FUNCTION__);
1739 exit (1);
1742 int r = pthread_barrier_wait (&b2);
1743 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1745 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1746 exit (1);
1749 r = pthread_barrier_wait (&b2);
1750 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1752 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1753 exit (1);
1756 pthread_cleanup_push (cl, NULL);
1758 char mem[1];
1759 struct iovec iov[1];
1760 iov[0].iov_base = mem;
1761 iov[0].iov_len = 1;
1763 struct msghdr m;
1764 m.msg_name = &sun;
1765 m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1766 + strlen (sun.sun_path) + 1);
1767 m.msg_iov = iov;
1768 m.msg_iovlen = 1;
1769 m.msg_control = NULL;
1770 m.msg_controllen = 0;
1772 sendmsg (tempfd2, &m, 0);
1774 pthread_cleanup_pop (0);
1776 printf ("%s: sendmsg returned\n", __FUNCTION__);
1778 exit (1);
1782 static void *
1783 tf_creat (void *arg)
1785 if (arg == NULL)
1786 // XXX If somebody can provide a portable test case in which sendmsg()
1787 // blocks we can enable this test to run in both rounds.
1788 abort ();
1790 int r = pthread_barrier_wait (&b2);
1791 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1793 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1794 exit (1);
1797 r = pthread_barrier_wait (&b2);
1798 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1800 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1801 exit (1);
1804 pthread_cleanup_push (cl, NULL);
1806 creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1808 pthread_cleanup_pop (0);
1810 printf ("%s: creat returned\n", __FUNCTION__);
1812 exit (1);
1816 static void *
1817 tf_connect (void *arg)
1819 if (arg == NULL)
1820 // XXX If somebody can provide a portable test case in which connect()
1821 // blocks we can enable this test to run in both rounds.
1822 abort ();
1824 struct sockaddr_un sun;
1826 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1827 if (tempfd == -1)
1829 printf ("%s: first socket call failed\n", __FUNCTION__);
1830 exit (1);
1833 int tries = 0;
1836 if (++tries > 10)
1838 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1841 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1842 if (mktemp (sun.sun_path) == NULL)
1844 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1845 exit (1);
1848 sun.sun_family = AF_UNIX;
1850 while (bind (tempfd, (struct sockaddr *) &sun,
1851 offsetof (struct sockaddr_un, sun_path)
1852 + strlen (sun.sun_path) + 1) != 0);
1853 tempfname = strdup (sun.sun_path);
1855 listen (tempfd, 5);
1857 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1858 if (tempfd2 == -1)
1860 printf ("%s: second socket call failed\n", __FUNCTION__);
1861 exit (1);
1864 int r = pthread_barrier_wait (&b2);
1865 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1867 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1868 exit (1);
1871 if (arg != NULL)
1873 r = pthread_barrier_wait (&b2);
1874 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1876 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1877 exit (1);
1881 pthread_cleanup_push (cl, NULL);
1883 connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1885 pthread_cleanup_pop (0);
1887 printf ("%s: connect returned\n", __FUNCTION__);
1889 exit (1);
1893 static void *
1894 tf_tcdrain (void *arg)
1896 if (arg == NULL)
1897 // XXX If somebody can provide a portable test case in which tcdrain()
1898 // blocks we can enable this test to run in both rounds.
1899 abort ();
1901 int r = pthread_barrier_wait (&b2);
1902 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1904 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1905 exit (1);
1908 if (arg != NULL)
1910 r = pthread_barrier_wait (&b2);
1911 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1913 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1914 exit (1);
1918 pthread_cleanup_push (cl, NULL);
1920 /* Regardless of stderr being a terminal, the tcdrain call should be
1921 canceled. */
1922 tcdrain (STDERR_FILENO);
1924 pthread_cleanup_pop (0);
1926 printf ("%s: tcdrain returned\n", __FUNCTION__);
1928 exit (1);
1932 static void *
1933 tf_msgrcv (void *arg)
1935 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1936 if (tempmsg == -1)
1938 printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
1939 exit (1);
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 ssize_t s;
1961 pthread_cleanup_push (cl, NULL);
1963 struct
1965 long int type;
1966 char mem[10];
1967 } m;
1968 int randnr;
1969 /* We need a positive random number. */
1971 randnr = random () % 64000;
1972 while (randnr <= 0);
1975 errno = 0;
1976 s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
1978 while (errno == EIDRM || errno == EINTR);
1980 pthread_cleanup_pop (0);
1982 printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
1984 msgctl (tempmsg, IPC_RMID, NULL);
1986 exit (1);
1990 static void *
1991 tf_msgsnd (void *arg)
1993 if (arg == NULL)
1994 // XXX If somebody can provide a portable test case in which msgsnd()
1995 // blocks we can enable this test to run in both rounds.
1996 abort ();
1998 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1999 if (tempmsg == -1)
2001 printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
2002 exit (1);
2005 int r = pthread_barrier_wait (&b2);
2006 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2008 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2009 exit (1);
2012 r = pthread_barrier_wait (&b2);
2013 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2015 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
2016 exit (1);
2019 pthread_cleanup_push (cl, NULL);
2021 struct
2023 long int type;
2024 char mem[1];
2025 } m;
2026 /* We need a positive random number. */
2028 m.type = random () % 64000;
2029 while (m.type <= 0);
2030 msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
2032 pthread_cleanup_pop (0);
2034 printf ("%s: msgsnd returned\n", __FUNCTION__);
2036 msgctl (tempmsg, IPC_RMID, NULL);
2038 exit (1);
2042 static struct
2044 const char *name;
2045 void *(*tf) (void *);
2046 int nb;
2047 int only_early;
2048 } tests[] =
2050 #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
2051 ADD_TEST (read, 2, 0),
2052 ADD_TEST (readv, 2, 0),
2053 ADD_TEST (select, 2, 0),
2054 ADD_TEST (pselect, 2, 0),
2055 ADD_TEST (poll, 2, 0),
2056 ADD_TEST (ppoll, 2, 0),
2057 ADD_TEST (write, 2, 0),
2058 ADD_TEST (writev, 2, 0),
2059 ADD_TEST (sleep, 2, 0),
2060 ADD_TEST (usleep, 2, 0),
2061 ADD_TEST (nanosleep, 2, 0),
2062 ADD_TEST (wait, 2, 0),
2063 ADD_TEST (waitid, 2, 0),
2064 ADD_TEST (waitpid, 2, 0),
2065 ADD_TEST (sigpause, 2, 0),
2066 ADD_TEST (sigsuspend, 2, 0),
2067 ADD_TEST (sigwait, 2, 0),
2068 ADD_TEST (sigwaitinfo, 2, 0),
2069 ADD_TEST (sigtimedwait, 2, 0),
2070 ADD_TEST (pause, 2, 0),
2071 ADD_TEST (accept, 2, 0),
2072 ADD_TEST (send, 2, 0),
2073 ADD_TEST (recv, 2, 0),
2074 ADD_TEST (recvfrom, 2, 0),
2075 ADD_TEST (recvmsg, 2, 0),
2076 ADD_TEST (open, 2, 1),
2077 ADD_TEST (close, 2, 1),
2078 ADD_TEST (pread, 2, 1),
2079 ADD_TEST (pwrite, 2, 1),
2080 ADD_TEST (fsync, 2, 1),
2081 ADD_TEST (msync, 2, 1),
2082 ADD_TEST (sendto, 2, 1),
2083 ADD_TEST (sendmsg, 2, 1),
2084 ADD_TEST (creat, 2, 1),
2085 ADD_TEST (connect, 2, 1),
2086 ADD_TEST (tcdrain, 2, 1),
2087 ADD_TEST (msgrcv, 2, 0),
2088 ADD_TEST (msgsnd, 2, 1),
2090 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
2093 static int
2094 do_test (void)
2096 int val;
2097 socklen_t len;
2099 if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
2101 perror ("socketpair");
2102 exit (1);
2105 val = 1;
2106 len = sizeof(val);
2107 setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2108 if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
2110 perror ("getsockopt");
2111 exit (1);
2113 if (val >= WRITE_BUFFER_SIZE)
2115 puts ("minimum write buffer size too large");
2116 exit (1);
2118 setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2120 int result = 0;
2121 size_t cnt;
2122 for (cnt = 0; cnt < ntest_tf; ++cnt)
2124 if (tests[cnt].only_early)
2125 continue;
2127 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2129 puts ("b2 init failed");
2130 exit (1);
2133 /* Reset the counter for the cleanup handler. */
2134 cl_called = 0;
2136 pthread_t th;
2137 if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
2139 printf ("create for '%s' test failed\n", tests[cnt].name);
2140 result = 1;
2141 continue;
2144 int r = pthread_barrier_wait (&b2);
2145 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2147 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2148 result = 1;
2149 continue;
2152 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
2153 while (nanosleep (&ts, &ts) != 0)
2154 continue;
2156 if (pthread_cancel (th) != 0)
2158 printf ("cancel for '%s' failed\n", tests[cnt].name);
2159 result = 1;
2160 continue;
2163 void *status;
2164 if (pthread_join (th, &status) != 0)
2166 printf ("join for '%s' failed\n", tests[cnt].name);
2167 result = 1;
2168 continue;
2170 if (status != PTHREAD_CANCELED)
2172 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2173 result = 1;
2174 continue;
2177 if (pthread_barrier_destroy (&b2) != 0)
2179 puts ("barrier_destroy failed");
2180 result = 1;
2181 continue;
2184 if (cl_called == 0)
2186 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2187 result = 1;
2188 continue;
2190 if (cl_called > 1)
2192 printf ("cleanup handler called more than once for '%s'\n",
2193 tests[cnt].name);
2194 result = 1;
2195 continue;
2198 printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
2200 if (tempfd != -1)
2202 close (tempfd);
2203 tempfd = -1;
2205 if (tempfd2 != -1)
2207 close (tempfd2);
2208 tempfd2 = -1;
2210 if (tempfname != NULL)
2212 unlink (tempfname);
2213 free (tempfname);
2214 tempfname = NULL;
2216 if (tempmsg != -1)
2218 msgctl (tempmsg, IPC_RMID, NULL);
2219 tempmsg = -1;
2223 for (cnt = 0; cnt < ntest_tf; ++cnt)
2225 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2227 puts ("b2 init failed");
2228 exit (1);
2231 /* Reset the counter for the cleanup handler. */
2232 cl_called = 0;
2234 pthread_t th;
2235 if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
2237 printf ("create for '%s' test failed\n", tests[cnt].name);
2238 result = 1;
2239 continue;
2242 int r = pthread_barrier_wait (&b2);
2243 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2245 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2246 result = 1;
2247 continue;
2250 if (pthread_cancel (th) != 0)
2252 printf ("cancel for '%s' failed\n", tests[cnt].name);
2253 result = 1;
2254 continue;
2257 r = pthread_barrier_wait (&b2);
2258 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2260 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2261 result = 1;
2262 continue;
2265 void *status;
2266 if (pthread_join (th, &status) != 0)
2268 printf ("join for '%s' failed\n", tests[cnt].name);
2269 result = 1;
2270 continue;
2272 if (status != PTHREAD_CANCELED)
2274 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2275 result = 1;
2276 continue;
2279 if (pthread_barrier_destroy (&b2) != 0)
2281 puts ("barrier_destroy failed");
2282 result = 1;
2283 continue;
2286 if (cl_called == 0)
2288 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2289 result = 1;
2290 continue;
2292 if (cl_called > 1)
2294 printf ("cleanup handler called more than once for '%s'\n",
2295 tests[cnt].name);
2296 result = 1;
2297 continue;
2300 printf ("early cancel test of '%s' successful\n", tests[cnt].name);
2302 if (tempfd != -1)
2304 close (tempfd);
2305 tempfd = -1;
2307 if (tempfd2 != -1)
2309 close (tempfd2);
2310 tempfd2 = -1;
2312 if (tempfname != NULL)
2314 unlink (tempfname);
2315 free (tempfname);
2316 tempfname = NULL;
2318 if (tempmsg != -1)
2320 msgctl (tempmsg, IPC_RMID, NULL);
2321 tempmsg = -1;
2325 return result;
2328 #define TIMEOUT 60
2329 #define TEST_FUNCTION do_test ()
2330 #include "../test-skeleton.c"