source: vendor/glibc-tests/glibc/nptl/tst-cancel4.c

Last change on this file was 2036, checked in by bird, 20 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 46.2 KB
Line 
1/* Copyright (C) 2002, 2003, 2004 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. */
69static int fds[2];
70
71/* Temporary file descriptor, to be closed after each round. */
72static int tempfd = -1;
73static int tempfd2 = -1;
74/* Name of temporary file to be removed after each round. */
75static char *tempfname;
76/* Temporary message queue. */
77static int tempmsg = -1;
78
79/* Often used barrier for two threads. */
80static 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. */
90static int cl_called;
91
92static void
93cl (void *arg)
94{
95 ++cl_called;
96}
97
98
99
100static void *
101tf_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
145static void *
146tf_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
191static void *
192tf_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
237static void *
238tf_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
284static void *
285tf_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
316static void *
317tf_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
348static void *
349tf_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
381static void *
382tf_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
430static void *
431tf_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
479static void *
480tf_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
526static void *
527tf_wait (void *arg)
528{
529 pid_t pid = fork ();
530 if (pid == -1)
531 {
532 puts ("fork failed");
533 exit (1);
534 }
535
536 if (pid == 0)
537 {
538 /* Make the program disappear after a while. */
539 if (arg == NULL)
540 sleep (10);
541 exit (0);
542 }
543
544 int r;
545 if (arg != NULL)
546 {
547 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
548 while (nanosleep (&ts, &ts) != 0)
549 continue;
550
551 r = pthread_barrier_wait (&b2);
552 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
553 {
554 printf ("%s: barrier_wait failed\n", __FUNCTION__);
555 exit (1);
556 }
557 }
558
559 r = pthread_barrier_wait (&b2);
560 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
561 {
562 printf ("%s: barrier_wait failed\n", __FUNCTION__);
563 exit (1);
564 }
565
566 int s;
567 pthread_cleanup_push (cl, NULL);
568
569 s = wait (NULL);
570
571 pthread_cleanup_pop (0);
572
573 printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
574 strerror (errno));
575
576 exit (1);
577}
578
579
580static void *
581tf_waitpid (void *arg)
582{
583
584 pid_t pid = fork ();
585 if (pid == -1)
586 {
587 puts ("fork failed");
588 exit (1);
589 }
590
591 if (pid == 0)
592 {
593 /* Make the program disappear after a while. */
594 if (arg == NULL)
595 sleep (10);
596 exit (0);
597 }
598
599 int r;
600 if (arg != NULL)
601 {
602 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
603 while (nanosleep (&ts, &ts) != 0)
604 continue;
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
614 r = pthread_barrier_wait (&b2);
615 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
616 {
617 printf ("%s: barrier_wait failed\n", __FUNCTION__);
618 exit (1);
619 }
620
621 int s;
622 pthread_cleanup_push (cl, NULL);
623
624 s = waitpid (-1, NULL, 0);
625
626 pthread_cleanup_pop (0);
627
628 printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
629 strerror (errno));
630
631 exit (1);
632}
633
634
635static void *
636tf_waitid (void *arg)
637{
638 pid_t pid = fork ();
639 if (pid == -1)
640 {
641 puts ("fork failed");
642 exit (1);
643 }
644
645 if (pid == 0)
646 {
647 /* Make the program disappear after a while. */
648 if (arg == NULL)
649 sleep (10);
650 exit (0);
651 }
652
653 int r;
654 if (arg != NULL)
655 {
656 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
657 while (nanosleep (&ts, &ts) != 0)
658 continue;
659
660 r = pthread_barrier_wait (&b2);
661 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
662 {
663 printf ("%s: barrier_wait failed\n", __FUNCTION__);
664 exit (1);
665 }
666 }
667
668 r = pthread_barrier_wait (&b2);
669 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
670 {
671 printf ("%s: barrier_wait failed\n", __FUNCTION__);
672 exit (1);
673 }
674
675 int s;
676 pthread_cleanup_push (cl, NULL);
677
678#ifndef WEXITED
679# define WEXITED 0
680#endif
681 siginfo_t si;
682 s = waitid (P_PID, pid, &si, WEXITED);
683
684 pthread_cleanup_pop (0);
685
686 printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
687 strerror (errno));
688
689 exit (1);
690}
691
692
693static void *
694tf_sigpause (void *arg)
695{
696 int r = pthread_barrier_wait (&b2);
697 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
698 {
699 printf ("%s: barrier_wait failed\n", __FUNCTION__);
700 exit (1);
701 }
702
703 if (arg != NULL)
704 {
705 r = pthread_barrier_wait (&b2);
706 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
707 {
708 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
709 exit (1);
710 }
711 }
712
713 pthread_cleanup_push (cl, NULL);
714
715 /* Just for fun block the cancellation signal. We need to use
716 __xpg_sigpause since otherwise we will get the BSD version. */
717 __xpg_sigpause (SIGCANCEL);
718
719 pthread_cleanup_pop (0);
720
721 printf ("%s: sigpause returned\n", __FUNCTION__);
722
723 exit (1);
724}
725
726
727static void *
728tf_sigsuspend (void *arg)
729{
730 int r = pthread_barrier_wait (&b2);
731 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
732 {
733 printf ("%s: barrier_wait failed\n", __FUNCTION__);
734 exit (1);
735 }
736
737 if (arg != NULL)
738 {
739 r = pthread_barrier_wait (&b2);
740 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
741 {
742 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
743 exit (1);
744 }
745 }
746
747 pthread_cleanup_push (cl, NULL);
748
749 /* Just for fun block all signals. */
750 sigset_t mask;
751 sigfillset (&mask);
752 sigsuspend (&mask);
753
754 pthread_cleanup_pop (0);
755
756 printf ("%s: sigsuspend returned\n", __FUNCTION__);
757
758 exit (1);
759}
760
761
762static void *
763tf_sigwait (void *arg)
764{
765 int r = pthread_barrier_wait (&b2);
766 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
767 {
768 printf ("%s: barrier_wait failed\n", __FUNCTION__);
769 exit (1);
770 }
771
772 if (arg != NULL)
773 {
774 r = pthread_barrier_wait (&b2);
775 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
776 {
777 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
778 exit (1);
779 }
780 }
781
782 /* Block SIGUSR1. */
783 sigset_t mask;
784 sigemptyset (&mask);
785 sigaddset (&mask, SIGUSR1);
786 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
787 {
788 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
789 exit (1);
790 }
791
792 int sig;
793 pthread_cleanup_push (cl, NULL);
794
795 /* Wait for SIGUSR1. */
796 sigwait (&mask, &sig);
797
798 pthread_cleanup_pop (0);
799
800 printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
801
802 exit (1);
803}
804
805
806static void *
807tf_sigwaitinfo (void *arg)
808{
809 int r = pthread_barrier_wait (&b2);
810 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
811 {
812 printf ("%s: barrier_wait failed\n", __FUNCTION__);
813 exit (1);
814 }
815
816 if (arg != NULL)
817 {
818 r = pthread_barrier_wait (&b2);
819 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
820 {
821 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
822 exit (1);
823 }
824 }
825
826 /* Block SIGUSR1. */
827 sigset_t mask;
828 sigemptyset (&mask);
829 sigaddset (&mask, SIGUSR1);
830 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
831 {
832 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
833 exit (1);
834 }
835
836 siginfo_t info;
837 pthread_cleanup_push (cl, NULL);
838
839 /* Wait for SIGUSR1. */
840 sigwaitinfo (&mask, &info);
841
842 pthread_cleanup_pop (0);
843
844 printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
845 info.si_signo);
846
847 exit (1);
848}
849
850
851static void *
852tf_sigtimedwait (void *arg)
853{
854 int r = pthread_barrier_wait (&b2);
855 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
856 {
857 printf ("%s: barrier_wait failed\n", __FUNCTION__);
858 exit (1);
859 }
860
861 if (arg != NULL)
862 {
863 r = pthread_barrier_wait (&b2);
864 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
865 {
866 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
867 exit (1);
868 }
869 }
870
871 /* Block SIGUSR1. */
872 sigset_t mask;
873 sigemptyset (&mask);
874 sigaddset (&mask, SIGUSR1);
875 if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
876 {
877 printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
878 exit (1);
879 }
880
881 /* Wait for SIGUSR1. */
882 siginfo_t info;
883 struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
884 pthread_cleanup_push (cl, NULL);
885
886 sigtimedwait (&mask, &info, &ts);
887
888 pthread_cleanup_pop (0);
889
890 printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
891 info.si_signo);
892
893 exit (1);
894}
895
896
897static void *
898tf_pause (void *arg)
899{
900 int r = pthread_barrier_wait (&b2);
901 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
902 {
903 printf ("%s: barrier_wait failed\n", __FUNCTION__);
904 exit (1);
905 }
906
907 if (arg != NULL)
908 {
909 r = pthread_barrier_wait (&b2);
910 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
911 {
912 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
913 exit (1);
914 }
915 }
916
917 pthread_cleanup_push (cl, NULL);
918
919 pause ();
920
921 pthread_cleanup_pop (0);
922
923 printf ("%s: pause returned\n", __FUNCTION__);
924
925 exit (1);
926}
927
928
929static void *
930tf_accept (void *arg)
931{
932 struct sockaddr_un sun;
933 /* To test a non-blocking accept call we make the call file by using
934 a datagrame socket. */
935 int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
936
937 tempfd = socket (AF_UNIX, pf, 0);
938 if (tempfd == -1)
939 {
940 printf ("%s: socket call failed\n", __FUNCTION__);
941 exit (1);
942 }
943
944 int tries = 0;
945 do
946 {
947 if (++tries > 10)
948 {
949 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
950 }
951
952 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
953 if (mktemp (sun.sun_path) == NULL)
954 {
955 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
956 exit (1);
957 }
958
959 sun.sun_family = AF_UNIX;
960 }
961 while (bind (tempfd, (struct sockaddr *) &sun,
962 offsetof (struct sockaddr_un, sun_path)
963 + strlen (sun.sun_path) + 1) != 0);
964
965 unlink (sun.sun_path);
966
967 listen (tempfd, 5);
968
969 socklen_t len = sizeof (sun);
970
971 int r = pthread_barrier_wait (&b2);
972 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
973 {
974 printf ("%s: barrier_wait failed\n", __FUNCTION__);
975 exit (1);
976 }
977
978 if (arg != NULL)
979 {
980 r = pthread_barrier_wait (&b2);
981 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
982 {
983 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
984 exit (1);
985 }
986 }
987
988 pthread_cleanup_push (cl, NULL);
989
990 accept (tempfd, (struct sockaddr *) &sun, &len);
991
992 pthread_cleanup_pop (0);
993
994 printf ("%s: accept returned\n", __FUNCTION__);
995
996 exit (1);
997}
998
999
1000static void *
1001tf_send (void *arg)
1002{
1003 struct sockaddr_un sun;
1004
1005 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1006 if (tempfd == -1)
1007 {
1008 printf ("%s: first socket call failed\n", __FUNCTION__);
1009 exit (1);
1010 }
1011
1012 int tries = 0;
1013 do
1014 {
1015 if (++tries > 10)
1016 {
1017 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1018 }
1019
1020 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1021 if (mktemp (sun.sun_path) == NULL)
1022 {
1023 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1024 exit (1);
1025 }
1026
1027 sun.sun_family = AF_UNIX;
1028 }
1029 while (bind (tempfd, (struct sockaddr *) &sun,
1030 offsetof (struct sockaddr_un, sun_path)
1031 + strlen (sun.sun_path) + 1) != 0);
1032
1033 listen (tempfd, 5);
1034
1035 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1036 if (tempfd2 == -1)
1037 {
1038 printf ("%s: second socket call failed\n", __FUNCTION__);
1039 exit (1);
1040 }
1041
1042 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1043 {
1044 printf ("%s: connect failed\n", __FUNCTION__);
1045 exit(1);
1046 }
1047
1048 unlink (sun.sun_path);
1049
1050 int r = pthread_barrier_wait (&b2);
1051 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1052 {
1053 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1054 exit (1);
1055 }
1056
1057 if (arg != NULL)
1058 {
1059 r = pthread_barrier_wait (&b2);
1060 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1061 {
1062 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1063 exit (1);
1064 }
1065 }
1066
1067 pthread_cleanup_push (cl, NULL);
1068
1069 /* Very large block, so that the send call blocks. */
1070 char mem[700000];
1071
1072 send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
1073
1074 pthread_cleanup_pop (0);
1075
1076 printf ("%s: send returned\n", __FUNCTION__);
1077
1078 exit (1);
1079}
1080
1081
1082static void *
1083tf_recv (void *arg)
1084{
1085 struct sockaddr_un sun;
1086
1087 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1088 if (tempfd == -1)
1089 {
1090 printf ("%s: first socket call failed\n", __FUNCTION__);
1091 exit (1);
1092 }
1093
1094 int tries = 0;
1095 do
1096 {
1097 if (++tries > 10)
1098 {
1099 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1100 }
1101
1102 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
1103 if (mktemp (sun.sun_path) == NULL)
1104 {
1105 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1106 exit (1);
1107 }
1108
1109 sun.sun_family = AF_UNIX;
1110 }
1111 while (bind (tempfd, (struct sockaddr *) &sun,
1112 offsetof (struct sockaddr_un, sun_path)
1113 + strlen (sun.sun_path) + 1) != 0);
1114
1115 listen (tempfd, 5);
1116
1117 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1118 if (tempfd2 == -1)
1119 {
1120 printf ("%s: second socket call failed\n", __FUNCTION__);
1121 exit (1);
1122 }
1123
1124 if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1125 {
1126 printf ("%s: connect failed\n", __FUNCTION__);
1127 exit(1);
1128 }
1129
1130 unlink (sun.sun_path);
1131
1132 int r = pthread_barrier_wait (&b2);
1133 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1134 {
1135 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1136 exit (1);
1137 }
1138
1139 if (arg != NULL)
1140 {
1141 r = pthread_barrier_wait (&b2);
1142 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1143 {
1144 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1145 exit (1);
1146 }
1147 }
1148
1149 pthread_cleanup_push (cl, NULL);
1150
1151 char mem[70];
1152
1153 recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
1154
1155 pthread_cleanup_pop (0);
1156
1157 printf ("%s: recv returned\n", __FUNCTION__);
1158
1159 exit (1);
1160}
1161
1162
1163static void *
1164tf_recvfrom (void *arg)
1165{
1166 struct sockaddr_un sun;
1167
1168 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1169 if (tempfd == -1)
1170 {
1171 printf ("%s: first socket call failed\n", __FUNCTION__);
1172 exit (1);
1173 }
1174
1175 int tries = 0;
1176 do
1177 {
1178 if (++tries > 10)
1179 {
1180 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1181 }
1182
1183 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
1184 if (mktemp (sun.sun_path) == NULL)
1185 {
1186 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1187 exit (1);
1188 }
1189
1190 sun.sun_family = AF_UNIX;
1191 }
1192 while (bind (tempfd, (struct sockaddr *) &sun,
1193 offsetof (struct sockaddr_un, sun_path)
1194 + strlen (sun.sun_path) + 1) != 0);
1195
1196 tempfname = strdup (sun.sun_path);
1197
1198 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1199 if (tempfd2 == -1)
1200 {
1201 printf ("%s: second socket call failed\n", __FUNCTION__);
1202 exit (1);
1203 }
1204
1205 int r = pthread_barrier_wait (&b2);
1206 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1207 {
1208 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1209 exit (1);
1210 }
1211
1212 if (arg != NULL)
1213 {
1214 r = pthread_barrier_wait (&b2);
1215 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1216 {
1217 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1218 exit (1);
1219 }
1220 }
1221
1222 pthread_cleanup_push (cl, NULL);
1223
1224 char mem[70];
1225 socklen_t len = sizeof (sun);
1226
1227 recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
1228 (struct sockaddr *) &sun, &len);
1229
1230 pthread_cleanup_pop (0);
1231
1232 printf ("%s: recvfrom returned\n", __FUNCTION__);
1233
1234 exit (1);
1235}
1236
1237
1238static void *
1239tf_recvmsg (void *arg)
1240{
1241 struct sockaddr_un sun;
1242
1243 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1244 if (tempfd == -1)
1245 {
1246 printf ("%s: first socket call failed\n", __FUNCTION__);
1247 exit (1);
1248 }
1249
1250 int tries = 0;
1251 do
1252 {
1253 if (++tries > 10)
1254 {
1255 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1256 }
1257
1258 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
1259 if (mktemp (sun.sun_path) == NULL)
1260 {
1261 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1262 exit (1);
1263 }
1264
1265 sun.sun_family = AF_UNIX;
1266 }
1267 while (bind (tempfd, (struct sockaddr *) &sun,
1268 offsetof (struct sockaddr_un, sun_path)
1269 + strlen (sun.sun_path) + 1) != 0);
1270
1271 tempfname = strdup (sun.sun_path);
1272
1273 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1274 if (tempfd2 == -1)
1275 {
1276 printf ("%s: second socket call failed\n", __FUNCTION__);
1277 exit (1);
1278 }
1279
1280 int r = pthread_barrier_wait (&b2);
1281 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1282 {
1283 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1284 exit (1);
1285 }
1286
1287 if (arg != NULL)
1288 {
1289 r = pthread_barrier_wait (&b2);
1290 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1291 {
1292 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1293 exit (1);
1294 }
1295 }
1296
1297 pthread_cleanup_push (cl, NULL);
1298
1299 char mem[70];
1300 struct iovec iov[1];
1301 iov[0].iov_base = mem;
1302 iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
1303
1304 struct msghdr m;
1305 m.msg_name = &sun;
1306 m.msg_namelen = sizeof (sun);
1307 m.msg_iov = iov;
1308 m.msg_iovlen = 1;
1309 m.msg_control = NULL;
1310 m.msg_controllen = 0;
1311
1312 recvmsg (tempfd2, &m, 0);
1313
1314 pthread_cleanup_pop (0);
1315
1316 printf ("%s: recvmsg returned\n", __FUNCTION__);
1317
1318 exit (1);
1319}
1320
1321
1322static void *
1323tf_open (void *arg)
1324{
1325 if (arg == NULL)
1326 // XXX If somebody can provide a portable test case in which open()
1327 // blocks we can enable this test to run in both rounds.
1328 abort ();
1329
1330 int r = pthread_barrier_wait (&b2);
1331 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1332 {
1333 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1334 exit (1);
1335 }
1336
1337 r = pthread_barrier_wait (&b2);
1338 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1339 {
1340 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1341 exit (1);
1342 }
1343
1344 pthread_cleanup_push (cl, NULL);
1345
1346 open ("Makefile", O_RDONLY);
1347
1348 pthread_cleanup_pop (0);
1349
1350 printf ("%s: open returned\n", __FUNCTION__);
1351
1352 exit (1);
1353}
1354
1355
1356static void *
1357tf_close (void *arg)
1358{
1359 if (arg == NULL)
1360 // XXX If somebody can provide a portable test case in which close()
1361 // blocks we can enable this test to run in both rounds.
1362 abort ();
1363
1364 char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
1365 tempfd = mkstemp (fname);
1366 if (tempfd == -1)
1367 {
1368 printf ("%s: mkstemp failed\n", __FUNCTION__);
1369 exit (1);
1370 }
1371 unlink (fname);
1372
1373 int r = pthread_barrier_wait (&b2);
1374 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1375 {
1376 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1377 exit (1);
1378 }
1379
1380 r = pthread_barrier_wait (&b2);
1381 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1382 {
1383 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1384 exit (1);
1385 }
1386
1387 pthread_cleanup_push (cl, NULL);
1388
1389 close (tempfd);
1390
1391 pthread_cleanup_pop (0);
1392
1393 printf ("%s: close returned\n", __FUNCTION__);
1394
1395 exit (1);
1396}
1397
1398
1399static void *
1400tf_pread (void *arg)
1401{
1402 if (arg == NULL)
1403 // XXX If somebody can provide a portable test case in which pread()
1404 // blocks we can enable this test to run in both rounds.
1405 abort ();
1406
1407 tempfd = open ("Makefile", O_RDONLY);
1408 if (tempfd == -1)
1409 {
1410 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1411 exit (1);
1412 }
1413
1414 int r = pthread_barrier_wait (&b2);
1415 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1416 {
1417 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1418 exit (1);
1419 }
1420
1421 r = pthread_barrier_wait (&b2);
1422 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1423 {
1424 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1425 exit (1);
1426 }
1427
1428 pthread_cleanup_push (cl, NULL);
1429
1430 char mem[10];
1431 pread (tempfd, mem, sizeof (mem), 0);
1432
1433 pthread_cleanup_pop (0);
1434
1435 printf ("%s: pread returned\n", __FUNCTION__);
1436
1437 exit (1);
1438}
1439
1440
1441static void *
1442tf_pwrite (void *arg)
1443{
1444 if (arg == NULL)
1445 // XXX If somebody can provide a portable test case in which pwrite()
1446 // blocks we can enable this test to run in both rounds.
1447 abort ();
1448
1449 char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1450 tempfd = mkstemp (fname);
1451 if (tempfd == -1)
1452 {
1453 printf ("%s: mkstemp failed\n", __FUNCTION__);
1454 exit (1);
1455 }
1456 unlink (fname);
1457
1458 int r = pthread_barrier_wait (&b2);
1459 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1460 {
1461 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1462 exit (1);
1463 }
1464
1465 r = pthread_barrier_wait (&b2);
1466 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1467 {
1468 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1469 exit (1);
1470 }
1471
1472 pthread_cleanup_push (cl, NULL);
1473
1474 char mem[10];
1475 pwrite (tempfd, mem, sizeof (mem), 0);
1476
1477 pthread_cleanup_pop (0);
1478
1479 printf ("%s: pwrite returned\n", __FUNCTION__);
1480
1481 exit (1);
1482}
1483
1484
1485static void *
1486tf_fsync (void *arg)
1487{
1488 if (arg == NULL)
1489 // XXX If somebody can provide a portable test case in which fsync()
1490 // blocks we can enable this test to run in both rounds.
1491 abort ();
1492
1493 tempfd = open ("Makefile", O_RDONLY);
1494 if (tempfd == -1)
1495 {
1496 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1497 exit (1);
1498 }
1499
1500 int r = pthread_barrier_wait (&b2);
1501 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1502 {
1503 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1504 exit (1);
1505 }
1506
1507 r = pthread_barrier_wait (&b2);
1508 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1509 {
1510 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1511 exit (1);
1512 }
1513
1514 pthread_cleanup_push (cl, NULL);
1515
1516 fsync (tempfd);
1517
1518 pthread_cleanup_pop (0);
1519
1520 printf ("%s: fsync returned\n", __FUNCTION__);
1521
1522 exit (1);
1523}
1524
1525
1526static void *
1527tf_msync (void *arg)
1528{
1529 if (arg == NULL)
1530 // XXX If somebody can provide a portable test case in which msync()
1531 // blocks we can enable this test to run in both rounds.
1532 abort ();
1533
1534 tempfd = open ("Makefile", O_RDONLY);
1535 if (tempfd == -1)
1536 {
1537 printf ("%s: cannot open Makefile\n", __FUNCTION__);
1538 exit (1);
1539 }
1540 void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
1541 if (p == MAP_FAILED)
1542 {
1543 printf ("%s: mmap failed\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 msync (p, 10, 0);
1564
1565 pthread_cleanup_pop (0);
1566
1567 printf ("%s: msync returned\n", __FUNCTION__);
1568
1569 exit (1);
1570}
1571
1572
1573static void *
1574tf_sendto (void *arg)
1575{
1576 if (arg == NULL)
1577 // XXX If somebody can provide a portable test case in which sendto()
1578 // blocks we can enable this test to run in both rounds.
1579 abort ();
1580
1581 struct sockaddr_un sun;
1582
1583 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1584 if (tempfd == -1)
1585 {
1586 printf ("%s: first socket call failed\n", __FUNCTION__);
1587 exit (1);
1588 }
1589
1590 int tries = 0;
1591 do
1592 {
1593 if (++tries > 10)
1594 {
1595 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1596 }
1597
1598 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1599 if (mktemp (sun.sun_path) == NULL)
1600 {
1601 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1602 exit (1);
1603 }
1604
1605 sun.sun_family = AF_UNIX;
1606 }
1607 while (bind (tempfd, (struct sockaddr *) &sun,
1608 offsetof (struct sockaddr_un, sun_path)
1609 + strlen (sun.sun_path) + 1) != 0);
1610 tempfname = strdup (sun.sun_path);
1611
1612 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1613 if (tempfd2 == -1)
1614 {
1615 printf ("%s: second socket call failed\n", __FUNCTION__);
1616 exit (1);
1617 }
1618
1619 int r = pthread_barrier_wait (&b2);
1620 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1621 {
1622 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1623 exit (1);
1624 }
1625
1626 r = pthread_barrier_wait (&b2);
1627 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1628 {
1629 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1630 exit (1);
1631 }
1632
1633 pthread_cleanup_push (cl, NULL);
1634
1635 char mem[1];
1636
1637 sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
1638 (struct sockaddr *) &sun,
1639 offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
1640
1641 pthread_cleanup_pop (0);
1642
1643 printf ("%s: sendto returned\n", __FUNCTION__);
1644
1645 exit (1);
1646}
1647
1648
1649static void *
1650tf_sendmsg (void *arg)
1651{
1652 if (arg == NULL)
1653 // XXX If somebody can provide a portable test case in which sendmsg()
1654 // blocks we can enable this test to run in both rounds.
1655 abort ();
1656
1657 struct sockaddr_un sun;
1658
1659 tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1660 if (tempfd == -1)
1661 {
1662 printf ("%s: first socket call failed\n", __FUNCTION__);
1663 exit (1);
1664 }
1665
1666 int tries = 0;
1667 do
1668 {
1669 if (++tries > 10)
1670 {
1671 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1672 }
1673
1674 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1675 if (mktemp (sun.sun_path) == NULL)
1676 {
1677 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1678 exit (1);
1679 }
1680
1681 sun.sun_family = AF_UNIX;
1682 }
1683 while (bind (tempfd, (struct sockaddr *) &sun,
1684 offsetof (struct sockaddr_un, sun_path)
1685 + strlen (sun.sun_path) + 1) != 0);
1686 tempfname = strdup (sun.sun_path);
1687
1688 tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1689 if (tempfd2 == -1)
1690 {
1691 printf ("%s: second socket call failed\n", __FUNCTION__);
1692 exit (1);
1693 }
1694
1695 int r = pthread_barrier_wait (&b2);
1696 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1697 {
1698 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1699 exit (1);
1700 }
1701
1702 r = pthread_barrier_wait (&b2);
1703 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1704 {
1705 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1706 exit (1);
1707 }
1708
1709 pthread_cleanup_push (cl, NULL);
1710
1711 char mem[1];
1712 struct iovec iov[1];
1713 iov[0].iov_base = mem;
1714 iov[0].iov_len = 1;
1715
1716 struct msghdr m;
1717 m.msg_name = &sun;
1718 m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1719 + strlen (sun.sun_path) + 1);
1720 m.msg_iov = iov;
1721 m.msg_iovlen = 1;
1722 m.msg_control = NULL;
1723 m.msg_controllen = 0;
1724
1725 sendmsg (tempfd2, &m, 0);
1726
1727 pthread_cleanup_pop (0);
1728
1729 printf ("%s: sendmsg returned\n", __FUNCTION__);
1730
1731 exit (1);
1732}
1733
1734
1735static void *
1736tf_creat (void *arg)
1737{
1738 if (arg == NULL)
1739 // XXX If somebody can provide a portable test case in which sendmsg()
1740 // blocks we can enable this test to run in both rounds.
1741 abort ();
1742
1743 int r = pthread_barrier_wait (&b2);
1744 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1745 {
1746 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1747 exit (1);
1748 }
1749
1750 r = pthread_barrier_wait (&b2);
1751 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1752 {
1753 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1754 exit (1);
1755 }
1756
1757 pthread_cleanup_push (cl, NULL);
1758
1759 creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1760
1761 pthread_cleanup_pop (0);
1762
1763 printf ("%s: creat returned\n", __FUNCTION__);
1764
1765 exit (1);
1766}
1767
1768
1769static void *
1770tf_connect (void *arg)
1771{
1772 if (arg == NULL)
1773 // XXX If somebody can provide a portable test case in which connect()
1774 // blocks we can enable this test to run in both rounds.
1775 abort ();
1776
1777 struct sockaddr_un sun;
1778
1779 tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1780 if (tempfd == -1)
1781 {
1782 printf ("%s: first socket call failed\n", __FUNCTION__);
1783 exit (1);
1784 }
1785
1786 int tries = 0;
1787 do
1788 {
1789 if (++tries > 10)
1790 {
1791 printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1792 }
1793
1794 strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1795 if (mktemp (sun.sun_path) == NULL)
1796 {
1797 printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1798 exit (1);
1799 }
1800
1801 sun.sun_family = AF_UNIX;
1802 }
1803 while (bind (tempfd, (struct sockaddr *) &sun,
1804 offsetof (struct sockaddr_un, sun_path)
1805 + strlen (sun.sun_path) + 1) != 0);
1806 tempfname = strdup (sun.sun_path);
1807
1808 listen (tempfd, 5);
1809
1810 tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1811 if (tempfd2 == -1)
1812 {
1813 printf ("%s: second socket call failed\n", __FUNCTION__);
1814 exit (1);
1815 }
1816
1817 int r = pthread_barrier_wait (&b2);
1818 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1819 {
1820 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1821 exit (1);
1822 }
1823
1824 if (arg != NULL)
1825 {
1826 r = pthread_barrier_wait (&b2);
1827 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1828 {
1829 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1830 exit (1);
1831 }
1832 }
1833
1834 pthread_cleanup_push (cl, NULL);
1835
1836 connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1837
1838 pthread_cleanup_pop (0);
1839
1840 printf ("%s: connect returned\n", __FUNCTION__);
1841
1842 exit (1);
1843}
1844
1845
1846static void *
1847tf_tcdrain (void *arg)
1848{
1849 if (arg == NULL)
1850 // XXX If somebody can provide a portable test case in which tcdrain()
1851 // blocks we can enable this test to run in both rounds.
1852 abort ();
1853
1854 int r = pthread_barrier_wait (&b2);
1855 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1856 {
1857 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1858 exit (1);
1859 }
1860
1861 if (arg != NULL)
1862 {
1863 r = pthread_barrier_wait (&b2);
1864 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1865 {
1866 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1867 exit (1);
1868 }
1869 }
1870
1871 pthread_cleanup_push (cl, NULL);
1872
1873 /* Regardless of stderr being a terminal, the tcdrain call should be
1874 canceled. */
1875 tcdrain (STDERR_FILENO);
1876
1877 pthread_cleanup_pop (0);
1878
1879 printf ("%s: tcdrain returned\n", __FUNCTION__);
1880
1881 exit (1);
1882}
1883
1884
1885static void *
1886tf_msgrcv (void *arg)
1887{
1888 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1889 if (tempmsg == -1)
1890 {
1891 printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
1892 exit (1);
1893 }
1894
1895 int r = pthread_barrier_wait (&b2);
1896 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1897 {
1898 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1899 exit (1);
1900 }
1901
1902 if (arg != NULL)
1903 {
1904 r = pthread_barrier_wait (&b2);
1905 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1906 {
1907 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1908 exit (1);
1909 }
1910 }
1911
1912 ssize_t s;
1913
1914 pthread_cleanup_push (cl, NULL);
1915
1916 struct
1917 {
1918 long int type;
1919 char mem[10];
1920 } m;
1921 int randnr;
1922 /* We need a positive random number. */
1923 do
1924 randnr = random () % 64000;
1925 while (randnr <= 0);
1926 do
1927 {
1928 errno = 0;
1929 s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
1930 }
1931 while (errno == EIDRM || errno == EINTR);
1932
1933 pthread_cleanup_pop (0);
1934
1935 printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
1936
1937 msgctl (tempmsg, IPC_RMID, NULL);
1938
1939 exit (1);
1940}
1941
1942
1943static void *
1944tf_msgsnd (void *arg)
1945{
1946 if (arg == NULL)
1947 // XXX If somebody can provide a portable test case in which msgsnd()
1948 // blocks we can enable this test to run in both rounds.
1949 abort ();
1950
1951 tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1952 if (tempmsg == -1)
1953 {
1954 printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
1955 exit (1);
1956 }
1957
1958 int r = pthread_barrier_wait (&b2);
1959 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1960 {
1961 printf ("%s: barrier_wait failed\n", __FUNCTION__);
1962 exit (1);
1963 }
1964
1965 r = pthread_barrier_wait (&b2);
1966 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1967 {
1968 printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1969 exit (1);
1970 }
1971
1972 pthread_cleanup_push (cl, NULL);
1973
1974 struct
1975 {
1976 long int type;
1977 char mem[1];
1978 } m;
1979 /* We need a positive random number. */
1980 do
1981 m.type = random () % 64000;
1982 while (m.type <= 0);
1983 msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
1984
1985 pthread_cleanup_pop (0);
1986
1987 printf ("%s: msgsnd returned\n", __FUNCTION__);
1988
1989 msgctl (tempmsg, IPC_RMID, NULL);
1990
1991 exit (1);
1992}
1993
1994
1995static struct
1996{
1997 const char *name;
1998 void *(*tf) (void *);
1999 int nb;
2000 int only_early;
2001} tests[] =
2002{
2003#define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
2004 ADD_TEST (read, 2, 0),
2005 ADD_TEST (readv, 2, 0),
2006 ADD_TEST (select, 2, 0),
2007 ADD_TEST (pselect, 2, 0),
2008 ADD_TEST (poll, 2, 0),
2009 ADD_TEST (write, 2, 0),
2010 ADD_TEST (writev, 2, 0),
2011 ADD_TEST (sleep, 2, 0),
2012 ADD_TEST (usleep, 2, 0),
2013 ADD_TEST (nanosleep, 2, 0),
2014 ADD_TEST (wait, 2, 0),
2015 ADD_TEST (waitid, 2, 0),
2016 ADD_TEST (waitpid, 2, 0),
2017 ADD_TEST (sigpause, 2, 0),
2018 ADD_TEST (sigsuspend, 2, 0),
2019 ADD_TEST (sigwait, 2, 0),
2020 ADD_TEST (sigwaitinfo, 2, 0),
2021 ADD_TEST (sigtimedwait, 2, 0),
2022 ADD_TEST (pause, 2, 0),
2023 ADD_TEST (accept, 2, 0),
2024 ADD_TEST (send, 2, 0),
2025 ADD_TEST (recv, 2, 0),
2026 ADD_TEST (recvfrom, 2, 0),
2027 ADD_TEST (recvmsg, 2, 0),
2028 ADD_TEST (open, 2, 1),
2029 ADD_TEST (close, 2, 1),
2030 ADD_TEST (pread, 2, 1),
2031 ADD_TEST (pwrite, 2, 1),
2032 ADD_TEST (fsync, 2, 1),
2033 ADD_TEST (msync, 2, 1),
2034 ADD_TEST (sendto, 2, 1),
2035 ADD_TEST (sendmsg, 2, 1),
2036 ADD_TEST (creat, 2, 1),
2037 ADD_TEST (connect, 2, 1),
2038 ADD_TEST (tcdrain, 2, 1),
2039 ADD_TEST (msgrcv, 2, 0),
2040 ADD_TEST (msgsnd, 2, 1),
2041};
2042#define ntest_tf (sizeof (tests) / sizeof (tests[0]))
2043
2044
2045static int
2046do_test (void)
2047{
2048 int val;
2049 socklen_t len;
2050
2051 if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
2052 {
2053 perror ("socketpair");
2054 exit (1);
2055 }
2056
2057 val = 1;
2058 len = sizeof(val);
2059 setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2060 if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
2061 {
2062 perror ("getsockopt");
2063 exit (1);
2064 }
2065 if (val >= WRITE_BUFFER_SIZE)
2066 {
2067 puts ("minimum write buffer size too large");
2068 exit (1);
2069 }
2070 setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2071
2072 int result = 0;
2073 size_t cnt;
2074 for (cnt = 0; cnt < ntest_tf; ++cnt)
2075 {
2076 if (tests[cnt].only_early)
2077 continue;
2078
2079 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2080 {
2081 puts ("b2 init failed");
2082 exit (1);
2083 }
2084
2085 /* Reset the counter for the cleanup handler. */
2086 cl_called = 0;
2087
2088 pthread_t th;
2089 if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
2090 {
2091 printf ("create for '%s' test failed\n", tests[cnt].name);
2092 result = 1;
2093 continue;
2094 }
2095
2096 int r = pthread_barrier_wait (&b2);
2097 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2098 {
2099 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2100 result = 1;
2101 continue;
2102 }
2103
2104 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
2105 while (nanosleep (&ts, &ts) != 0)
2106 continue;
2107
2108 if (pthread_cancel (th) != 0)
2109 {
2110 printf ("cancel for '%s' failed\n", tests[cnt].name);
2111 result = 1;
2112 continue;
2113 }
2114
2115 void *status;
2116 if (pthread_join (th, &status) != 0)
2117 {
2118 printf ("join for '%s' failed\n", tests[cnt].name);
2119 result = 1;
2120 continue;
2121 }
2122 if (status != PTHREAD_CANCELED)
2123 {
2124 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2125 result = 1;
2126 continue;
2127 }
2128
2129 if (pthread_barrier_destroy (&b2) != 0)
2130 {
2131 puts ("barrier_destroy failed");
2132 result = 1;
2133 continue;
2134 }
2135
2136 if (cl_called == 0)
2137 {
2138 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2139 result = 1;
2140 continue;
2141 }
2142 if (cl_called > 1)
2143 {
2144 printf ("cleanup handler called more than once for '%s'\n",
2145 tests[cnt].name);
2146 result = 1;
2147 continue;
2148 }
2149
2150 printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
2151
2152 if (tempfd != -1)
2153 {
2154 close (tempfd);
2155 tempfd = -1;
2156 }
2157 if (tempfd2 != -1)
2158 {
2159 close (tempfd2);
2160 tempfd2 = -1;
2161 }
2162 if (tempfname != NULL)
2163 {
2164 unlink (tempfname);
2165 free (tempfname);
2166 tempfname = NULL;
2167 }
2168 if (tempmsg != -1)
2169 {
2170 msgctl (tempmsg, IPC_RMID, NULL);
2171 tempmsg = -1;
2172 }
2173 }
2174
2175 for (cnt = 0; cnt < ntest_tf; ++cnt)
2176 {
2177 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2178 {
2179 puts ("b2 init failed");
2180 exit (1);
2181 }
2182
2183 /* Reset the counter for the cleanup handler. */
2184 cl_called = 0;
2185
2186 pthread_t th;
2187 if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
2188 {
2189 printf ("create for '%s' test failed\n", tests[cnt].name);
2190 result = 1;
2191 continue;
2192 }
2193
2194 int r = pthread_barrier_wait (&b2);
2195 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2196 {
2197 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2198 result = 1;
2199 continue;
2200 }
2201
2202 if (pthread_cancel (th) != 0)
2203 {
2204 printf ("cancel for '%s' failed\n", tests[cnt].name);
2205 result = 1;
2206 continue;
2207 }
2208
2209 r = pthread_barrier_wait (&b2);
2210 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2211 {
2212 printf ("%s: barrier_wait failed\n", __FUNCTION__);
2213 result = 1;
2214 continue;
2215 }
2216
2217 void *status;
2218 if (pthread_join (th, &status) != 0)
2219 {
2220 printf ("join for '%s' failed\n", tests[cnt].name);
2221 result = 1;
2222 continue;
2223 }
2224 if (status != PTHREAD_CANCELED)
2225 {
2226 printf ("thread for '%s' not canceled\n", tests[cnt].name);
2227 result = 1;
2228 continue;
2229 }
2230
2231 if (pthread_barrier_destroy (&b2) != 0)
2232 {
2233 puts ("barrier_destroy failed");
2234 result = 1;
2235 continue;
2236 }
2237
2238 if (cl_called == 0)
2239 {
2240 printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2241 result = 1;
2242 continue;
2243 }
2244 if (cl_called > 1)
2245 {
2246 printf ("cleanup handler called more than once for '%s'\n",
2247 tests[cnt].name);
2248 result = 1;
2249 continue;
2250 }
2251
2252 printf ("early cancel test of '%s' successful\n", tests[cnt].name);
2253
2254 if (tempfd != -1)
2255 {
2256 close (tempfd);
2257 tempfd = -1;
2258 }
2259 if (tempfd2 != -1)
2260 {
2261 close (tempfd2);
2262 tempfd2 = -1;
2263 }
2264 if (tempfname != NULL)
2265 {
2266 unlink (tempfname);
2267 free (tempfname);
2268 tempfname = NULL;
2269 }
2270 if (tempmsg != -1)
2271 {
2272 msgctl (tempmsg, IPC_RMID, NULL);
2273 tempmsg = -1;
2274 }
2275 }
2276
2277 return result;
2278}
2279
2280#define TIMEOUT 60
2281#define TEST_FUNCTION do_test ()
2282#include "../test-skeleton.c"
Note: See TracBrowser for help on using the repository browser.