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