]> git.ipfire.org Git - thirdparty/glibc.git/blob - nptl/tst-cancel4.c
(tf_sigwait, tf_sigwaitinfo, tf_sigtimedwait): Add sigemptyset before sigaddset....
[thirdparty/glibc.git] / nptl / tst-cancel4.c
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
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. */
19
20 /* NOTE: this tests functionality beyond POSIX. POSIX does not allow
21 exit to be called more than once. */
22
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>
41
42 #include "pthreadP.h"
43
44
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()
50
51 lockf() and fcntl() are tested in tst-cancel16.
52
53 pthread_join() is tested in tst-join5.
54
55 pthread_testcancel()'s only purpose is to allow cancellation. This
56 is tested in several places.
57
58 sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
59
60 POSIX message queues aren't implemented yet. This affects
61 mq_receive() mq_send() mq_timedreceive() mq_timedsend()
62
63 aio_suspend() is tested in tst-cancel17.
64
65 clock_nanosleep() is tested in tst-cancel18.
66 */
67
68 /* Pipe descriptors. */
69 static int fds[2];
70
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;
78
79 /* Often used barrier for two threads. */
80 static pthread_barrier_t b2;
81
82
83 #ifndef IPC_ADDVAL
84 # define IPC_ADDVAL 0
85 #endif
86
87 /* Cleanup handling test. */
88 static int cl_called;
89
90 static void
91 cl (void *arg)
92 {
93 ++cl_called;
94 }
95
96
97
98 static void *
99 tf_read (void *arg)
100 {
101 int fd;
102 int r;
103
104 if (arg == NULL)
105 fd = fds[0];
106 else
107 {
108 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
109 tempfd = fd = mkstemp (fname);
110 if (fd == -1)
111 printf ("%s: mkstemp failed\n", __FUNCTION__);
112 unlink (fname);
113
114 r = pthread_barrier_wait (&b2);
115 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
116 {
117 printf ("%s: barrier_wait failed\n", __FUNCTION__);
118 exit (1);
119 }
120 }
121
122 r = pthread_barrier_wait (&b2);
123 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
124 {
125 printf ("%s: barrier_wait failed\n", __FUNCTION__);
126 exit (1);
127 }
128
129 ssize_t s;
130 pthread_cleanup_push (cl, NULL);
131
132 char buf[100];
133 s = read (fd, buf, sizeof (buf));
134
135 pthread_cleanup_pop (0);
136
137 printf ("%s: read returns with %zd\n", __FUNCTION__, s);
138
139 exit (1);
140 }
141
142
143 static void *
144 tf_readv (void *arg)
145 {
146 int fd;
147 int r;
148
149 if (arg == NULL)
150 fd = fds[0];
151 else
152 {
153 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
154 tempfd = fd = mkstemp (fname);
155 if (fd == -1)
156 printf ("%s: mkstemp failed\n", __FUNCTION__);
157 unlink (fname);
158
159 r = pthread_barrier_wait (&b2);
160 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
161 {
162 printf ("%s: barrier_wait failed\n", __FUNCTION__);
163 exit (1);
164 }
165 }
166
167 r = pthread_barrier_wait (&b2);
168 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
169 {
170 printf ("%s: barrier_wait failed\n", __FUNCTION__);
171 exit (1);
172 }
173
174 ssize_t s;
175 pthread_cleanup_push (cl, NULL);
176
177 char buf[100];
178 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
179 s = readv (fd, iov, 1);
180
181 pthread_cleanup_pop (0);
182
183 printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
184
185 exit (1);
186 }
187
188
189 static void *
190 tf_write (void *arg)
191 {
192 int fd;
193 int r;
194
195 if (arg == NULL)
196 fd = fds[1];
197 else
198 {
199 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
200 tempfd = fd = mkstemp (fname);
201 if (fd == -1)
202 printf ("%s: mkstemp failed\n", __FUNCTION__);
203 unlink (fname);
204
205 r = pthread_barrier_wait (&b2);
206 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
207 {
208 printf ("%s: barrier_wait failed\n", __FUNCTION__);
209 exit (1);
210 }
211 }
212
213 r = pthread_barrier_wait (&b2);
214 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
215 {
216 printf ("%s: barrier_wait failed\n", __FUNCTION__);
217 exit (1);
218 }
219
220 ssize_t s;
221 pthread_cleanup_push (cl, NULL);
222
223 char buf[100000];
224 memset (buf, '\0', sizeof (buf));
225 s = write (fd, buf, sizeof (buf));
226
227 pthread_cleanup_pop (0);
228
229 printf ("%s: write returns with %zd\n", __FUNCTION__, s);
230
231 exit (1);
232 }
233
234
235 static void *
236 tf_writev (void *arg)
237 {
238 int fd;
239 int r;
240
241 if (arg == NULL)
242 fd = fds[1];
243 else
244 {
245 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
246 tempfd = fd = mkstemp (fname);
247 if (fd == -1)
248 printf ("%s: mkstemp failed\n", __FUNCTION__);
249 unlink (fname);
250
251 r = pthread_barrier_wait (&b2);
252 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
253 {
254 printf ("%s: barrier_wait failed\n", __FUNCTION__);
255 exit (1);
256 }
257 }
258
259 r = pthread_barrier_wait (&b2);
260 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
261 {
262 printf ("%s: barrier_wait failed\n", __FUNCTION__);
263 exit (1);
264 }
265
266 ssize_t s;
267 pthread_cleanup_push (cl, NULL);
268
269 char buf[100000];
270 memset (buf, '\0', sizeof (buf));
271 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
272 s = writev (fd, iov, 1);
273
274 pthread_cleanup_pop (0);
275
276 printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
277
278 exit (1);
279 }
280
281
282 static void *
283 tf_sleep (void *arg)
284 {
285 int r = pthread_barrier_wait (&b2);
286 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
287 {
288 printf ("%s: barrier_wait failed\n", __FUNCTION__);
289 exit (1);
290 }
291
292 if (arg != NULL)
293 {
294 r = pthread_barrier_wait (&b2);
295 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
296 {
297 printf ("%s: barrier_wait failed\n", __FUNCTION__);
298 exit (1);
299 }
300 }
301
302 pthread_cleanup_push (cl, NULL);
303
304 sleep (arg == NULL ? 1000000 : 0);
305
306 pthread_cleanup_pop (0);
307
308 printf ("%s: sleep returns\n", __FUNCTION__);
309
310 exit (1);
311 }
312
313
314 static void *
315 tf_usleep (void *arg)
316 {
317 int r = pthread_barrier_wait (&b2);
318 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
319 {
320 printf ("%s: barrier_wait failed\n", __FUNCTION__);
321 exit (1);
322 }
323
324 if (arg != NULL)
325 {
326 r = pthread_barrier_wait (&b2);
327 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
328 {
329 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
330 exit (1);
331 }
332 }
333
334 pthread_cleanup_push (cl, NULL);
335
336 usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
337
338 pthread_cleanup_pop (0);
339
340 printf ("%s: usleep returns\n", __FUNCTION__);
341
342 exit (1);
343 }
344
345
346 static void *
347 tf_nanosleep (void *arg)
348 {
349 int r = pthread_barrier_wait (&b2);
350 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
351 {
352 printf ("%s: barrier_wait failed\n", __FUNCTION__);
353 exit (1);
354 }
355
356 if (arg != NULL)
357 {
358 r = pthread_barrier_wait (&b2);
359 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
360 {
361 printf ("%s: barrier_wait failed\n", __FUNCTION__);
362 exit (1);
363 }
364 }
365
366 pthread_cleanup_push (cl, NULL);
367
368 struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
369 TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
370
371 pthread_cleanup_pop (0);
372
373 printf ("%s: nanosleep returns\n", __FUNCTION__);
374
375 exit (1);
376 }
377
378
379 static void *
380 tf_select (void *arg)
381 {
382 int fd;
383 int r;
384
385 if (arg == NULL)
386 fd = fds[0];
387 else
388 {
389 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
390 tempfd = fd = mkstemp (fname);
391 if (fd == -1)
392 printf ("%s: mkstemp failed\n", __FUNCTION__);
393 unlink (fname);
394
395 r = pthread_barrier_wait (&b2);
396 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
397 {
398 printf ("%s: barrier_wait failed\n", __FUNCTION__);
399 exit (1);
400 }
401 }
402
403 r = pthread_barrier_wait (&b2);
404 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
405 {
406 printf ("%s: barrier_wait failed\n", __FUNCTION__);
407 exit (1);
408 }
409
410 fd_set rfs;
411 FD_ZERO (&rfs);
412 FD_SET (fd, &rfs);
413
414 int s;
415 pthread_cleanup_push (cl, NULL);
416
417 s = select (fd + 1, &rfs, NULL, NULL, NULL);
418
419 pthread_cleanup_pop (0);
420
421 printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
422 strerror (errno));
423
424 exit (1);
425 }
426
427
428 static void *
429 tf_pselect (void *arg)
430 {
431 int fd;
432 int r;
433
434 if (arg == NULL)
435 fd = fds[0];
436 else
437 {
438 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
439 tempfd = fd = mkstemp (fname);
440 if (fd == -1)
441 printf ("%s: mkstemp failed\n", __FUNCTION__);
442 unlink (fname);
443
444 r = pthread_barrier_wait (&b2);
445 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
446 {
447 printf ("%s: barrier_wait failed\n", __FUNCTION__);
448 exit (1);
449 }
450 }
451
452 r = pthread_barrier_wait (&b2);
453 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
454 {
455 printf ("%s: barrier_wait failed\n", __FUNCTION__);
456 exit (1);
457 }
458
459 fd_set rfs;
460 FD_ZERO (&rfs);
461 FD_SET (fd, &rfs);
462
463 int s;
464 pthread_cleanup_push (cl, NULL);
465
466 s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
467
468 pthread_cleanup_pop (0);
469
470 printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
471 strerror (errno));
472
473 exit (1);
474 }
475
476
477 static void *
478 tf_poll (void *arg)
479 {
480 int fd;
481 int r;
482
483 if (arg == NULL)
484 fd = fds[0];
485 else
486 {
487 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
488 tempfd = fd = mkstemp (fname);
489 if (fd == -1)
490 printf ("%s: mkstemp failed\n", __FUNCTION__);
491 unlink (fname);
492
493 r = pthread_barrier_wait (&b2);
494 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
495 {
496 printf ("%s: barrier_wait failed\n", __FUNCTION__);
497 exit (1);
498 }
499 }
500
501 r = pthread_barrier_wait (&b2);
502 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
503 {
504 printf ("%s: barrier_wait failed\n", __FUNCTION__);
505 exit (1);
506 }
507
508 struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
509
510 int s;
511 pthread_cleanup_push (cl, NULL);
512
513 s = poll (rfs, 1, -1);
514
515 pthread_cleanup_pop (0);
516
517 printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
518 strerror (errno));
519
520 exit (1);
521 }
522
523
524 static void *
525 tf_wait (void *arg)
526 {
527 pid_t pid = fork ();
528 if (pid == -1)
529 {
530 puts ("fork failed");
531 exit (1);
532 }
533
534 if (pid == 0)
535 {
536 /* Make the program disappear after a while. */
537 if (arg == NULL)
538 sleep (10);
539 exit (0);
540 }
541
542 int r;
543 if (arg != NULL)
544 {
545 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
546 while (nanosleep (&ts, &ts) != 0)
547 continue;
548
549 r = pthread_barrier_wait (&b2);
550 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
551 {
552 printf ("%s: barrier_wait failed\n", __FUNCTION__);
553 exit (1);
554 }
555 }
556
557 r = pthread_barrier_wait (&b2);
558 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
559 {
560 printf ("%s: barrier_wait failed\n", __FUNCTION__);
561 exit (1);
562 }
563
564 int s;
565 pthread_cleanup_push (cl, NULL);
566
567 s = wait (NULL);
568
569 pthread_cleanup_pop (0);
570
571 printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
572 strerror (errno));
573
574 exit (1);
575 }
576
577
578 static void *
579 tf_waitpid (void *arg)
580 {
581
582 pid_t pid = fork ();
583 if (pid == -1)
584 {
585 puts ("fork failed");
586 exit (1);
587 }
588
589 if (pid == 0)
590 {
591 /* Make the program disappear after a while. */
592 if (arg == NULL)
593 sleep (10);
594 exit (0);
595 }
596
597 int r;
598 if (arg != NULL)
599 {
600 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
601 while (nanosleep (&ts, &ts) != 0)
602 continue;
603
604 r = pthread_barrier_wait (&b2);
605 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
606 {
607 printf ("%s: barrier_wait failed\n", __FUNCTION__);
608 exit (1);
609 }
610 }
611
612 r = pthread_barrier_wait (&b2);
613 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
614 {
615 printf ("%s: barrier_wait failed\n", __FUNCTION__);
616 exit (1);
617 }
618
619 int s;
620 pthread_cleanup_push (cl, NULL);
621
622 s = waitpid (-1, NULL, 0);
623
624 pthread_cleanup_pop (0);
625
626 printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
627 strerror (errno));
628
629 exit (1);
630 }
631
632
633 static void *
634 tf_waitid (void *arg)
635 {
636 pid_t pid = fork ();
637 if (pid == -1)
638 {
639 puts ("fork failed");
640 exit (1);
641 }
642
643 if (pid == 0)
644 {
645 /* Make the program disappear after a while. */
646 if (arg == NULL)
647 sleep (10);
648 exit (0);
649 }
650
651 int r;
652 if (arg != NULL)
653 {
654 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
655 while (nanosleep (&ts, &ts) != 0)
656 continue;
657
658 r = pthread_barrier_wait (&b2);
659 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
660 {
661 printf ("%s: barrier_wait failed\n", __FUNCTION__);
662 exit (1);
663 }
664 }
665
666 r = pthread_barrier_wait (&b2);
667 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
668 {
669 printf ("%s: barrier_wait failed\n", __FUNCTION__);
670 exit (1);
671 }
672
673 int s;
674 pthread_cleanup_push (cl, NULL);
675
676 siginfo_t si;
677 s = waitid (P_PID, pid, &si, 0);
678
679 pthread_cleanup_pop (0);
680
681 printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
682 strerror (errno));
683
684 exit (1);
685 }
686
687
688 static void *
689 tf_sigpause (void *arg)
690 {
691 int r = pthread_barrier_wait (&b2);
692 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
693 {
694 printf ("%s: barrier_wait failed\n", __FUNCTION__);
695 exit (1);
696 }
697
698 if (arg != NULL)
699 {
700 r = pthread_barrier_wait (&b2);
701 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
702 {
703 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
704 exit (1);
705 }
706 }
707
708 pthread_cleanup_push (cl, NULL);
709
710 /* Just for fun block the cancellation signal. We need to use
711 __xpg_sigpause since otherwise we will get the BSD version. */
712 __xpg_sigpause (SIGCANCEL);
713
714 pthread_cleanup_pop (0);
715
716 printf ("%s: sigpause returned\n", __FUNCTION__);
717
718 exit (1);
719 }
720
721
722 static void *
723 tf_sigsuspend (void *arg)
724 {
725 int r = pthread_barrier_wait (&b2);
726 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
727 {
728 printf ("%s: barrier_wait failed\n", __FUNCTION__);
729 exit (1);
730 }
731
732 if (arg != NULL)
733 {
734 r = pthread_barrier_wait (&b2);
735 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
736 {
737 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
738 exit (1);
739 }
740 }
741
742 pthread_cleanup_push (cl, NULL);
743
744 /* Just for fun block all signals. */
745 sigset_t mask;
746 sigfillset (&mask);
747 sigsuspend (&mask);
748
749 pthread_cleanup_pop (0);
750
751 printf ("%s: sigsuspend returned\n", __FUNCTION__);
752
753 exit (1);
754 }
755
756
757 static void *
758 tf_sigwait (void *arg)
759 {
760 int r = pthread_barrier_wait (&b2);
761 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
762 {
763 printf ("%s: barrier_wait failed\n", __FUNCTION__);
764 exit (1);
765 }
766
767 if (arg != NULL)
768 {
769 r = pthread_barrier_wait (&b2);
770 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
771 {
772 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
773 exit (1);
774 }
775 }
776
777 /* Block SIGUSR1. */
778 sigset_t mask;
779 sigemptyset (&mask);
780 sigaddset (&mask, SIGUSR1);
781 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
782 {
783 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
784 exit (1);
785 }
786
787 int sig;
788 pthread_cleanup_push (cl, NULL);
789
790 /* Wait for SIGUSR1. */
791 sigwait (&mask, &sig);
792
793 pthread_cleanup_pop (0);
794
795 printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
796
797 exit (1);
798 }
799
800
801 static void *
802 tf_sigwaitinfo (void *arg)
803 {
804 int r = pthread_barrier_wait (&b2);
805 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
806 {
807 printf ("%s: barrier_wait failed\n", __FUNCTION__);
808 exit (1);
809 }
810
811 if (arg != NULL)
812 {
813 r = pthread_barrier_wait (&b2);
814 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
815 {
816 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
817 exit (1);
818 }
819 }
820
821 /* Block SIGUSR1. */
822 sigset_t mask;
823 sigemptyset (&mask);
824 sigaddset (&mask, SIGUSR1);
825 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
826 {
827 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
828 exit (1);
829 }
830
831 siginfo_t info;
832 pthread_cleanup_push (cl, NULL);
833
834 /* Wait for SIGUSR1. */
835 sigwaitinfo (&mask, &info);
836
837 pthread_cleanup_pop (0);
838
839 printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
840 info.si_signo);
841
842 exit (1);
843 }
844
845
846 static void *
847 tf_sigtimedwait (void *arg)
848 {
849 int r = pthread_barrier_wait (&b2);
850 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
851 {
852 printf ("%s: barrier_wait failed\n", __FUNCTION__);
853 exit (1);
854 }
855
856 if (arg != NULL)
857 {
858 r = pthread_barrier_wait (&b2);
859 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
860 {
861 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
862 exit (1);
863 }
864 }
865
866 /* Block SIGUSR1. */
867 sigset_t mask;
868 sigemptyset (&mask);
869 sigaddset (&mask, SIGUSR1);
870 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
871 {
872 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
873 exit (1);
874 }
875
876 /* Wait for SIGUSR1. */
877 siginfo_t info;
878 struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
879 pthread_cleanup_push (cl, NULL);
880
881 sigtimedwait (&mask, &info, &ts);
882
883 pthread_cleanup_pop (0);
884
885 printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
886 info.si_signo);
887
888 exit (1);
889 }
890
891
892 static void *
893 tf_pause (void *arg)
894 {
895 int r = pthread_barrier_wait (&b2);
896 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
897 {
898 printf ("%s: barrier_wait failed\n", __FUNCTION__);
899 exit (1);
900 }
901
902 if (arg != NULL)
903 {
904 r = pthread_barrier_wait (&b2);
905 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
906 {
907 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
908 exit (1);
909 }
910 }
911
912 pthread_cleanup_push (cl, NULL);
913
914 pause ();
915
916 pthread_cleanup_pop (0);
917
918 printf ("%s: pause returned\n", __FUNCTION__);
919
920 exit (1);
921 }
922
923
924 static void *
925 tf_accept (void *arg)
926 {
927 struct sockaddr_un sun;
928 /* To test a non-blocking accept call we make the call file by using
929 a datagrame socket. */
930 int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
931
932 tempfd = socket (AF_UNIX, pf, 0);
933 if (tempfd == -1)
934 {
935 printf ("%s: socket call failed\n", __FUNCTION__);
936 exit (1);
937 }
938
939 int tries = 0;
940 do
941 {
942 if (++tries > 10)
943 {
944 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
945 }
946
947 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
948 if (mktemp (sun.sun_path) == NULL)
949 {
950 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
951 exit (1);
952 }
953
954 sun.sun_family = AF_UNIX;
955 }
956 while (bind (tempfd, (struct sockaddr *) &sun,
957 offsetof (struct sockaddr_un, sun_path)
958 + strlen (sun.sun_path) + 1) != 0);
959
960 unlink (sun.sun_path);
961
962 listen (tempfd, 5);
963
964 socklen_t len = sizeof (sun);
965
966 int r = pthread_barrier_wait (&b2);
967 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
968 {
969 printf ("%s: barrier_wait failed\n", __FUNCTION__);
970 exit (1);
971 }
972
973 if (arg != NULL)
974 {
975 r = pthread_barrier_wait (&b2);
976 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
977 {
978 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
979 exit (1);
980 }
981 }
982
983 pthread_cleanup_push (cl, NULL);
984
985 accept (tempfd, (struct sockaddr *) &sun, &len);
986
987 pthread_cleanup_pop (0);
988
989 printf ("%s: accept returned\n", __FUNCTION__);
990
991 exit (1);
992 }
993
994
995 static void *
996 tf_send (void *arg)
997 {
998 struct sockaddr_un sun;
999
1000 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1001 if (tempfd == -1)
1002 {
1003 printf ("%s: first socket call failed\n", __FUNCTION__);
1004 exit (1);
1005 }
1006
1007 int tries = 0;
1008 do
1009 {
1010 if (++tries > 10)
1011 {
1012 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1013 }
1014
1015 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1016 if (mktemp (sun.sun_path) == NULL)
1017 {
1018 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1019 exit (1);
1020 }
1021
1022 sun.sun_family = AF_UNIX;
1023 }
1024 while (bind (tempfd, (struct sockaddr *) &sun,
1025 offsetof (struct sockaddr_un, sun_path)
1026 + strlen (sun.sun_path) + 1) != 0);
1027
1028 listen (tempfd, 5);
1029
1030 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1031 if (tempfd2 == -1)
1032 {
1033 printf ("%s: second socket call failed\n", __FUNCTION__);
1034 exit (1);
1035 }
1036
1037 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1038 {
1039 printf ("%s: connect failed\n", __FUNCTION__);
1040 exit(1);
1041 }
1042
1043 unlink (sun.sun_path);
1044
1045 int r = pthread_barrier_wait (&b2);
1046 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1047 {
1048 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1049 exit (1);
1050 }
1051
1052 if (arg != NULL)
1053 {
1054 r = pthread_barrier_wait (&b2);
1055 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1056 {
1057 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1058 exit (1);
1059 }
1060 }
1061
1062 pthread_cleanup_push (cl, NULL);
1063
1064 /* Very large block, so that the send call blocks. */
1065 char mem[700000];
1066
1067 send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
1068
1069 pthread_cleanup_pop (0);
1070
1071 printf ("%s: send returned\n", __FUNCTION__);
1072
1073 exit (1);
1074 }
1075
1076
1077 static void *
1078 tf_recv (void *arg)
1079 {
1080 struct sockaddr_un sun;
1081
1082 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1083 if (tempfd == -1)
1084 {
1085 printf ("%s: first socket call failed\n", __FUNCTION__);
1086 exit (1);
1087 }
1088
1089 int tries = 0;
1090 do
1091 {
1092 if (++tries > 10)
1093 {
1094 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1095 }
1096
1097 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
1098 if (mktemp (sun.sun_path) == NULL)
1099 {
1100 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1101 exit (1);
1102 }
1103
1104 sun.sun_family = AF_UNIX;
1105 }
1106 while (bind (tempfd, (struct sockaddr *) &sun,
1107 offsetof (struct sockaddr_un, sun_path)
1108 + strlen (sun.sun_path) + 1) != 0);
1109
1110 listen (tempfd, 5);
1111
1112 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1113 if (tempfd2 == -1)
1114 {
1115 printf ("%s: second socket call failed\n", __FUNCTION__);
1116 exit (1);
1117 }
1118
1119 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1120 {
1121 printf ("%s: connect failed\n", __FUNCTION__);
1122 exit(1);
1123 }
1124
1125 unlink (sun.sun_path);
1126
1127 int r = pthread_barrier_wait (&b2);
1128 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1129 {
1130 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1131 exit (1);
1132 }
1133
1134 if (arg != NULL)
1135 {
1136 r = pthread_barrier_wait (&b2);
1137 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1138 {
1139 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1140 exit (1);
1141 }
1142 }
1143
1144 pthread_cleanup_push (cl, NULL);
1145
1146 char mem[70];
1147
1148 recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
1149
1150 pthread_cleanup_pop (0);
1151
1152 printf ("%s: recv returned\n", __FUNCTION__);
1153
1154 exit (1);
1155 }
1156
1157
1158 static void *
1159 tf_recvfrom (void *arg)
1160 {
1161 struct sockaddr_un sun;
1162
1163 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1164 if (tempfd == -1)
1165 {
1166 printf ("%s: first socket call failed\n", __FUNCTION__);
1167 exit (1);
1168 }
1169
1170 int tries = 0;
1171 do
1172 {
1173 if (++tries > 10)
1174 {
1175 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1176 }
1177
1178 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
1179 if (mktemp (sun.sun_path) == NULL)
1180 {
1181 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1182 exit (1);
1183 }
1184
1185 sun.sun_family = AF_UNIX;
1186 }
1187 while (bind (tempfd, (struct sockaddr *) &sun,
1188 offsetof (struct sockaddr_un, sun_path)
1189 + strlen (sun.sun_path) + 1) != 0);
1190
1191 tempfname = strdup (sun.sun_path);
1192
1193 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1194 if (tempfd2 == -1)
1195 {
1196 printf ("%s: second socket call failed\n", __FUNCTION__);
1197 exit (1);
1198 }
1199
1200 int r = pthread_barrier_wait (&b2);
1201 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1202 {
1203 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1204 exit (1);
1205 }
1206
1207 if (arg != NULL)
1208 {
1209 r = pthread_barrier_wait (&b2);
1210 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1211 {
1212 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1213 exit (1);
1214 }
1215 }
1216
1217 pthread_cleanup_push (cl, NULL);
1218
1219 char mem[70];
1220 socklen_t len = sizeof (sun);
1221
1222 recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
1223 (struct sockaddr *) &sun, &len);
1224
1225 pthread_cleanup_pop (0);
1226
1227 printf ("%s: recvfrom returned\n", __FUNCTION__);
1228
1229 exit (1);
1230 }
1231
1232
1233 static void *
1234 tf_recvmsg (void *arg)
1235 {
1236 struct sockaddr_un sun;
1237
1238 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1239 if (tempfd == -1)
1240 {
1241 printf ("%s: first socket call failed\n", __FUNCTION__);
1242 exit (1);
1243 }
1244
1245 int tries = 0;
1246 do
1247 {
1248 if (++tries > 10)
1249 {
1250 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1251 }
1252
1253 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
1254 if (mktemp (sun.sun_path) == NULL)
1255 {
1256 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1257 exit (1);
1258 }
1259
1260 sun.sun_family = AF_UNIX;
1261 }
1262 while (bind (tempfd, (struct sockaddr *) &sun,
1263 offsetof (struct sockaddr_un, sun_path)
1264 + strlen (sun.sun_path) + 1) != 0);
1265
1266 tempfname = strdup (sun.sun_path);
1267
1268 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1269 if (tempfd2 == -1)
1270 {
1271 printf ("%s: second socket call failed\n", __FUNCTION__);
1272 exit (1);
1273 }
1274
1275 int r = pthread_barrier_wait (&b2);
1276 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1277 {
1278 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1279 exit (1);
1280 }
1281
1282 if (arg != NULL)
1283 {
1284 r = pthread_barrier_wait (&b2);
1285 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1286 {
1287 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1288 exit (1);
1289 }
1290 }
1291
1292 pthread_cleanup_push (cl, NULL);
1293
1294 char mem[70];
1295 struct iovec iov[1];
1296 iov[0].iov_base = mem;
1297 iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
1298
1299 struct msghdr m;
1300 m.msg_name = &sun;
1301 m.msg_namelen = sizeof (sun);
1302 m.msg_iov = iov;
1303 m.msg_iovlen = 1;
1304 m.msg_control = NULL;
1305 m.msg_controllen = 0;
1306
1307 recvmsg (tempfd2, &m, 0);
1308
1309 pthread_cleanup_pop (0);
1310
1311 printf ("%s: recvmsg returned\n", __FUNCTION__);
1312
1313 exit (1);
1314 }
1315
1316
1317 static void *
1318 tf_open (void *arg)
1319 {
1320 if (arg == NULL)
1321 // XXX If somebody can provide a portable test case in which open()
1322 // blocks we can enable this test to run in both rounds.
1323 abort ();
1324
1325 int r = pthread_barrier_wait (&b2);
1326 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1327 {
1328 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1329 exit (1);
1330 }
1331
1332 r = pthread_barrier_wait (&b2);
1333 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1334 {
1335 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1336 exit (1);
1337 }
1338
1339 pthread_cleanup_push (cl, NULL);
1340
1341 open ("Makefile", O_RDONLY);
1342
1343 pthread_cleanup_pop (0);
1344
1345 printf ("%s: open returned\n", __FUNCTION__);
1346
1347 exit (1);
1348 }
1349
1350
1351 static void *
1352 tf_close (void *arg)
1353 {
1354 if (arg == NULL)
1355 // XXX If somebody can provide a portable test case in which close()
1356 // blocks we can enable this test to run in both rounds.
1357 abort ();
1358
1359 char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
1360 tempfd = mkstemp (fname);
1361 if (tempfd == -1)
1362 {
1363 printf ("%s: mkstemp failed\n", __FUNCTION__);
1364 exit (1);
1365 }
1366 unlink (fname);
1367
1368 int r = pthread_barrier_wait (&b2);
1369 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1370 {
1371 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1372 exit (1);
1373 }
1374
1375 r = pthread_barrier_wait (&b2);
1376 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1377 {
1378 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1379 exit (1);
1380 }
1381
1382 pthread_cleanup_push (cl, NULL);
1383
1384 close (tempfd);
1385
1386 pthread_cleanup_pop (0);
1387
1388 printf ("%s: close returned\n", __FUNCTION__);
1389
1390 exit (1);
1391 }
1392
1393
1394 static void *
1395 tf_pread (void *arg)
1396 {
1397 if (arg == NULL)
1398 // XXX If somebody can provide a portable test case in which pread()
1399 // blocks we can enable this test to run in both rounds.
1400 abort ();
1401
1402 tempfd = open ("Makefile", O_RDONLY);
1403 if (tempfd == -1)
1404 {
1405 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1406 exit (1);
1407 }
1408
1409 int r = pthread_barrier_wait (&b2);
1410 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1411 {
1412 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1413 exit (1);
1414 }
1415
1416 r = pthread_barrier_wait (&b2);
1417 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1418 {
1419 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1420 exit (1);
1421 }
1422
1423 pthread_cleanup_push (cl, NULL);
1424
1425 char mem[10];
1426 pread (tempfd, mem, sizeof (mem), 0);
1427
1428 pthread_cleanup_pop (0);
1429
1430 printf ("%s: pread returned\n", __FUNCTION__);
1431
1432 exit (1);
1433 }
1434
1435
1436 static void *
1437 tf_pwrite (void *arg)
1438 {
1439 if (arg == NULL)
1440 // XXX If somebody can provide a portable test case in which pwrite()
1441 // blocks we can enable this test to run in both rounds.
1442 abort ();
1443
1444 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1445 tempfd = mkstemp (fname);
1446 if (tempfd == -1)
1447 {
1448 printf ("%s: mkstemp failed\n", __FUNCTION__);
1449 exit (1);
1450 }
1451 unlink (fname);
1452
1453 int r = pthread_barrier_wait (&b2);
1454 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1455 {
1456 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1457 exit (1);
1458 }
1459
1460 r = pthread_barrier_wait (&b2);
1461 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1462 {
1463 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1464 exit (1);
1465 }
1466
1467 pthread_cleanup_push (cl, NULL);
1468
1469 char mem[10];
1470 pwrite (tempfd, mem, sizeof (mem), 0);
1471
1472 pthread_cleanup_pop (0);
1473
1474 printf ("%s: pwrite returned\n", __FUNCTION__);
1475
1476 exit (1);
1477 }
1478
1479
1480 static void *
1481 tf_fsync (void *arg)
1482 {
1483 if (arg == NULL)
1484 // XXX If somebody can provide a portable test case in which fsync()
1485 // blocks we can enable this test to run in both rounds.
1486 abort ();
1487
1488 tempfd = open ("Makefile", O_RDONLY);
1489 if (tempfd == -1)
1490 {
1491 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1492 exit (1);
1493 }
1494
1495 int r = pthread_barrier_wait (&b2);
1496 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1497 {
1498 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1499 exit (1);
1500 }
1501
1502 r = pthread_barrier_wait (&b2);
1503 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1504 {
1505 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1506 exit (1);
1507 }
1508
1509 pthread_cleanup_push (cl, NULL);
1510
1511 fsync (tempfd);
1512
1513 pthread_cleanup_pop (0);
1514
1515 printf ("%s: fsync returned\n", __FUNCTION__);
1516
1517 exit (1);
1518 }
1519
1520
1521 static void *
1522 tf_msync (void *arg)
1523 {
1524 if (arg == NULL)
1525 // XXX If somebody can provide a portable test case in which msync()
1526 // blocks we can enable this test to run in both rounds.
1527 abort ();
1528
1529 tempfd = open ("Makefile", O_RDONLY);
1530 if (tempfd == -1)
1531 {
1532 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1533 exit (1);
1534 }
1535 void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
1536 if (p == MAP_FAILED)
1537 {
1538 printf ("%s: mmap failed\n", __FUNCTION__);
1539 exit (1);
1540 }
1541
1542 int r = pthread_barrier_wait (&b2);
1543 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1544 {
1545 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1546 exit (1);
1547 }
1548
1549 r = pthread_barrier_wait (&b2);
1550 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1551 {
1552 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1553 exit (1);
1554 }
1555
1556 pthread_cleanup_push (cl, NULL);
1557
1558 msync (p, 10, 0);
1559
1560 pthread_cleanup_pop (0);
1561
1562 printf ("%s: msync returned\n", __FUNCTION__);
1563
1564 exit (1);
1565 }
1566
1567
1568 static void *
1569 tf_sendto (void *arg)
1570 {
1571 if (arg == NULL)
1572 // XXX If somebody can provide a portable test case in which sendto()
1573 // blocks we can enable this test to run in both rounds.
1574 abort ();
1575
1576 struct sockaddr_un sun;
1577
1578 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1579 if (tempfd == -1)
1580 {
1581 printf ("%s: first socket call failed\n", __FUNCTION__);
1582 exit (1);
1583 }
1584
1585 int tries = 0;
1586 do
1587 {
1588 if (++tries > 10)
1589 {
1590 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1591 }
1592
1593 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1594 if (mktemp (sun.sun_path) == NULL)
1595 {
1596 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1597 exit (1);
1598 }
1599
1600 sun.sun_family = AF_UNIX;
1601 }
1602 while (bind (tempfd, (struct sockaddr *) &sun,
1603 offsetof (struct sockaddr_un, sun_path)
1604 + strlen (sun.sun_path) + 1) != 0);
1605 tempfname = strdup (sun.sun_path);
1606
1607 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1608 if (tempfd2 == -1)
1609 {
1610 printf ("%s: second socket call failed\n", __FUNCTION__);
1611 exit (1);
1612 }
1613
1614 int r = pthread_barrier_wait (&b2);
1615 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1616 {
1617 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1618 exit (1);
1619 }
1620
1621 r = pthread_barrier_wait (&b2);
1622 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1623 {
1624 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1625 exit (1);
1626 }
1627
1628 pthread_cleanup_push (cl, NULL);
1629
1630 char mem[1];
1631
1632 sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
1633 (struct sockaddr *) &sun,
1634 offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
1635
1636 pthread_cleanup_pop (0);
1637
1638 printf ("%s: sendto returned\n", __FUNCTION__);
1639
1640 exit (1);
1641 }
1642
1643
1644 static void *
1645 tf_sendmsg (void *arg)
1646 {
1647 if (arg == NULL)
1648 // XXX If somebody can provide a portable test case in which sendmsg()
1649 // blocks we can enable this test to run in both rounds.
1650 abort ();
1651
1652 struct sockaddr_un sun;
1653
1654 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1655 if (tempfd == -1)
1656 {
1657 printf ("%s: first socket call failed\n", __FUNCTION__);
1658 exit (1);
1659 }
1660
1661 int tries = 0;
1662 do
1663 {
1664 if (++tries > 10)
1665 {
1666 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1667 }
1668
1669 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1670 if (mktemp (sun.sun_path) == NULL)
1671 {
1672 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1673 exit (1);
1674 }
1675
1676 sun.sun_family = AF_UNIX;
1677 }
1678 while (bind (tempfd, (struct sockaddr *) &sun,
1679 offsetof (struct sockaddr_un, sun_path)
1680 + strlen (sun.sun_path) + 1) != 0);
1681 tempfname = strdup (sun.sun_path);
1682
1683 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1684 if (tempfd2 == -1)
1685 {
1686 printf ("%s: second socket call failed\n", __FUNCTION__);
1687 exit (1);
1688 }
1689
1690 int r = pthread_barrier_wait (&b2);
1691 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1692 {
1693 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1694 exit (1);
1695 }
1696
1697 r = pthread_barrier_wait (&b2);
1698 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1699 {
1700 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1701 exit (1);
1702 }
1703
1704 pthread_cleanup_push (cl, NULL);
1705
1706 char mem[1];
1707 struct iovec iov[1];
1708 iov[0].iov_base = mem;
1709 iov[0].iov_len = 1;
1710
1711 struct msghdr m;
1712 m.msg_name = &sun;
1713 m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1714 + strlen (sun.sun_path) + 1);
1715 m.msg_iov = iov;
1716 m.msg_iovlen = 1;
1717 m.msg_control = NULL;
1718 m.msg_controllen = 0;
1719
1720 sendmsg (tempfd2, &m, 0);
1721
1722 pthread_cleanup_pop (0);
1723
1724 printf ("%s: sendmsg returned\n", __FUNCTION__);
1725
1726 exit (1);
1727 }
1728
1729
1730 static void *
1731 tf_creat (void *arg)
1732 {
1733 if (arg == NULL)
1734 // XXX If somebody can provide a portable test case in which sendmsg()
1735 // blocks we can enable this test to run in both rounds.
1736 abort ();
1737
1738 int r = pthread_barrier_wait (&b2);
1739 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1740 {
1741 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1742 exit (1);
1743 }
1744
1745 r = pthread_barrier_wait (&b2);
1746 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1747 {
1748 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1749 exit (1);
1750 }
1751
1752 pthread_cleanup_push (cl, NULL);
1753
1754 creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1755
1756 pthread_cleanup_pop (0);
1757
1758 printf ("%s: creat returned\n", __FUNCTION__);
1759
1760 exit (1);
1761 }
1762
1763
1764 static void *
1765 tf_connect (void *arg)
1766 {
1767 if (arg == NULL)
1768 // XXX If somebody can provide a portable test case in which connect()
1769 // blocks we can enable this test to run in both rounds.
1770 abort ();
1771
1772 struct sockaddr_un sun;
1773
1774 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1775 if (tempfd == -1)
1776 {
1777 printf ("%s: first socket call failed\n", __FUNCTION__);
1778 exit (1);
1779 }
1780
1781 int tries = 0;
1782 do
1783 {
1784 if (++tries > 10)
1785 {
1786 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1787 }
1788
1789 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1790 if (mktemp (sun.sun_path) == NULL)
1791 {
1792 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1793 exit (1);
1794 }
1795
1796 sun.sun_family = AF_UNIX;
1797 }
1798 while (bind (tempfd, (struct sockaddr *) &sun,
1799 offsetof (struct sockaddr_un, sun_path)
1800 + strlen (sun.sun_path) + 1) != 0);
1801 tempfname = strdup (sun.sun_path);
1802
1803 listen (tempfd, 5);
1804
1805 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1806 if (tempfd2 == -1)
1807 {
1808 printf ("%s: second socket call failed\n", __FUNCTION__);
1809 exit (1);
1810 }
1811
1812 int r = pthread_barrier_wait (&b2);
1813 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1814 {
1815 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1816 exit (1);
1817 }
1818
1819 if (arg != NULL)
1820 {
1821 r = pthread_barrier_wait (&b2);
1822 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1823 {
1824 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1825 exit (1);
1826 }
1827 }
1828
1829 pthread_cleanup_push (cl, NULL);
1830
1831 connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1832
1833 pthread_cleanup_pop (0);
1834
1835 printf ("%s: connect returned\n", __FUNCTION__);
1836
1837 exit (1);
1838 }
1839
1840
1841 static void *
1842 tf_tcdrain (void *arg)
1843 {
1844 if (arg == NULL)
1845 // XXX If somebody can provide a portable test case in which tcdrain()
1846 // blocks we can enable this test to run in both rounds.
1847 abort ();
1848
1849 int r = pthread_barrier_wait (&b2);
1850 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1851 {
1852 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1853 exit (1);
1854 }
1855
1856 if (arg != NULL)
1857 {
1858 r = pthread_barrier_wait (&b2);
1859 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1860 {
1861 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1862 exit (1);
1863 }
1864 }
1865
1866 pthread_cleanup_push (cl, NULL);
1867
1868 /* Regardless of stderr being a terminal, the tcdrain call should be
1869 canceled. */
1870 tcdrain (STDERR_FILENO);
1871
1872 pthread_cleanup_pop (0);
1873
1874 printf ("%s: tcdrain returned\n", __FUNCTION__);
1875
1876 exit (1);
1877 }
1878
1879
1880 static void *
1881 tf_msgrcv (void *arg)
1882 {
1883 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1884
1885 int r = pthread_barrier_wait (&b2);
1886 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1887 {
1888 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1889 exit (1);
1890 }
1891
1892 if (arg != NULL)
1893 {
1894 r = pthread_barrier_wait (&b2);
1895 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1896 {
1897 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1898 exit (1);
1899 }
1900 }
1901
1902 ssize_t s;
1903
1904 pthread_cleanup_push (cl, NULL);
1905
1906 struct
1907 {
1908 long int type;
1909 char mem[10];
1910 } m;
1911 int randnr;
1912 /* We need a positive random number. */
1913 do
1914 randnr = random () % 64000;
1915 while (randnr <= 0);
1916 do
1917 {
1918 errno = 0;
1919 s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
1920 }
1921 while (errno == EIDRM || errno == EINTR);
1922
1923 pthread_cleanup_pop (0);
1924
1925 printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
1926
1927 exit (1);
1928 }
1929
1930
1931 static void *
1932 tf_msgsnd (void *arg)
1933 {
1934 if (arg == NULL)
1935 // XXX If somebody can provide a portable test case in which msgsnd()
1936 // blocks we can enable this test to run in both rounds.
1937 abort ();
1938
1939 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1940
1941 int r = pthread_barrier_wait (&b2);
1942 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1943 {
1944 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1945 exit (1);
1946 }
1947
1948 r = pthread_barrier_wait (&b2);
1949 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1950 {
1951 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1952 exit (1);
1953 }
1954
1955 pthread_cleanup_push (cl, NULL);
1956
1957 struct
1958 {
1959 long int type;
1960 char mem[1];
1961 } m;
1962 /* We need a positive random number. */
1963 do
1964 m.type = random () % 64000;
1965 while (m.type <= 0);
1966 msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
1967
1968 pthread_cleanup_pop (0);
1969
1970 printf ("%s: msgsnd returned\n", __FUNCTION__);
1971
1972 exit (1);
1973 }
1974
1975
1976 static struct
1977 {
1978 const char *name;
1979 void *(*tf) (void *);
1980 int nb;
1981 int only_early;
1982 } tests[] =
1983 {
1984 #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
1985 ADD_TEST (read, 2, 0),
1986 ADD_TEST (readv, 2, 0),
1987 ADD_TEST (select, 2, 0),
1988 ADD_TEST (pselect, 2, 0),
1989 ADD_TEST (poll, 2, 0),
1990 ADD_TEST (write, 2, 0),
1991 ADD_TEST (writev, 2, 0),
1992 ADD_TEST (sleep, 2, 0),
1993 ADD_TEST (usleep, 2, 0),
1994 ADD_TEST (nanosleep, 2, 0),
1995 ADD_TEST (wait, 2, 0),
1996 ADD_TEST (waitid, 2, 0),
1997 ADD_TEST (waitpid, 2, 0),
1998 ADD_TEST (sigpause, 2, 0),
1999 ADD_TEST (sigsuspend, 2, 0),
2000 ADD_TEST (sigwait, 2, 0),
2001 ADD_TEST (sigwaitinfo, 2, 0),
2002 ADD_TEST (sigtimedwait, 2, 0),
2003 ADD_TEST (pause, 2, 0),
2004 ADD_TEST (accept, 2, 0),
2005 ADD_TEST (send, 2, 0),
2006 ADD_TEST (recv, 2, 0),
2007 ADD_TEST (recvfrom, 2, 0),
2008 ADD_TEST (recvmsg, 2, 0),
2009 ADD_TEST (open, 2, 1),
2010 ADD_TEST (close, 2, 1),
2011 ADD_TEST (pread, 2, 1),
2012 ADD_TEST (pwrite, 2, 1),
2013 ADD_TEST (fsync, 2, 1),
2014 ADD_TEST (msync, 2, 1),
2015 ADD_TEST (sendto, 2, 1),
2016 ADD_TEST (sendmsg, 2, 1),
2017 ADD_TEST (creat, 2, 1),
2018 ADD_TEST (connect, 2, 1),
2019 ADD_TEST (tcdrain, 2, 1),
2020 ADD_TEST (msgrcv, 2, 0),
2021 ADD_TEST (msgsnd, 2, 1),
2022 };
2023 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
2024
2025
2026 static int
2027 do_test (void)
2028 {
2029 if (pipe (fds) != 0)
2030 {
2031 puts ("pipe failed");
2032 exit (1);
2033 }
2034
2035 int result = 0;
2036 size_t cnt;
2037 for (cnt = 0; cnt < ntest_tf; ++cnt)
2038 {
2039 if (tests[cnt].only_early)
2040 continue;
2041
2042 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2043 {
2044 puts ("b2 init failed");
2045 exit (1);
2046 }
2047
2048 /* Reset the counter for the cleanup handler. */
2049 cl_called = 0;
2050
2051 pthread_t th;
2052 if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
2053 {
2054 printf ("create for '%s' test failed\n", tests[cnt].name);
2055 result = 1;
2056 continue;
2057 }
2058
2059 int r = pthread_barrier_wait (&b2);
2060 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2061 {
2062 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2063 result = 1;
2064 continue;
2065 }
2066
2067 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
2068 while (nanosleep (&ts, &ts) != 0)
2069 continue;
2070
2071 if (pthread_cancel (th) != 0)
2072 {
2073 printf ("cancel for '%s' failed\n", tests[cnt].name);
2074 result = 1;
2075 continue;
2076 }
2077
2078 void *status;
2079 if (pthread_join (th, &status) != 0)
2080 {
2081 printf ("join for '%s' failed\n", tests[cnt].name);
2082 result = 1;
2083 continue;
2084 }
2085 if (status != PTHREAD_CANCELED)
2086 {
2087 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2088 result = 1;
2089 continue;
2090 }
2091
2092 if (pthread_barrier_destroy (&b2) != 0)
2093 {
2094 puts ("barrier_destroy failed");
2095 result = 1;
2096 continue;
2097 }
2098
2099 if (cl_called == 0)
2100 {
2101 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2102 result = 1;
2103 continue;
2104 }
2105 if (cl_called > 1)
2106 {
2107 printf ("cleanup handler called more than once for '%s'\n",
2108 tests[cnt].name);
2109 result = 1;
2110 continue;
2111 }
2112
2113 printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
2114
2115 if (tempfd != -1)
2116 {
2117 close (tempfd);
2118 tempfd = -1;
2119 }
2120 if (tempfd2 != -1)
2121 {
2122 close (tempfd2);
2123 tempfd2 = -1;
2124 }
2125 if (tempfname != NULL)
2126 {
2127 unlink (tempfname);
2128 free (tempfname);
2129 tempfname = NULL;
2130 }
2131 if (tempmsg != -1)
2132 {
2133 msgctl (tempmsg, IPC_RMID, NULL);
2134 tempmsg = -1;
2135 }
2136 }
2137
2138 for (cnt = 0; cnt < ntest_tf; ++cnt)
2139 {
2140 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2141 {
2142 puts ("b2 init failed");
2143 exit (1);
2144 }
2145
2146 /* Reset the counter for the cleanup handler. */
2147 cl_called = 0;
2148
2149 pthread_t th;
2150 if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
2151 {
2152 printf ("create for '%s' test failed\n", tests[cnt].name);
2153 result = 1;
2154 continue;
2155 }
2156
2157 int r = pthread_barrier_wait (&b2);
2158 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2159 {
2160 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2161 result = 1;
2162 continue;
2163 }
2164
2165 if (pthread_cancel (th) != 0)
2166 {
2167 printf ("cancel for '%s' failed\n", tests[cnt].name);
2168 result = 1;
2169 continue;
2170 }
2171
2172 r = pthread_barrier_wait (&b2);
2173 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2174 {
2175 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2176 result = 1;
2177 continue;
2178 }
2179
2180 void *status;
2181 if (pthread_join (th, &status) != 0)
2182 {
2183 printf ("join for '%s' failed\n", tests[cnt].name);
2184 result = 1;
2185 continue;
2186 }
2187 if (status != PTHREAD_CANCELED)
2188 {
2189 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2190 result = 1;
2191 continue;
2192 }
2193
2194 if (pthread_barrier_destroy (&b2) != 0)
2195 {
2196 puts ("barrier_destroy failed");
2197 result = 1;
2198 continue;
2199 }
2200
2201 if (cl_called == 0)
2202 {
2203 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2204 result = 1;
2205 continue;
2206 }
2207 if (cl_called > 1)
2208 {
2209 printf ("cleanup handler called more than once for '%s'\n",
2210 tests[cnt].name);
2211 result = 1;
2212 continue;
2213 }
2214
2215 printf ("early cancel test of '%s' successful\n", tests[cnt].name);
2216
2217 if (tempfd != -1)
2218 {
2219 close (tempfd);
2220 tempfd = -1;
2221 }
2222 if (tempfd2 != -1)
2223 {
2224 close (tempfd2);
2225 tempfd2 = -1;
2226 }
2227 if (tempfname != NULL)
2228 {
2229 unlink (tempfname);
2230 free (tempfname);
2231 tempfname = NULL;
2232 }
2233 if (tempmsg != -1)
2234 {
2235 msgctl (tempmsg, IPC_RMID, NULL);
2236 tempmsg = -1;
2237 }
2238 }
2239
2240 return result;
2241 }
2242
2243 #define TIMEOUT 60
2244 #define TEST_FUNCTION do_test ()
2245 #include "../test-skeleton.c"