1 /* Copyright (C) 2002-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 /* NOTE: this tests functionality beyond POSIX.  POSIX does not allow
19    exit to be called more than once.  */
20 
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sys/ipc.h>
29 #include <sys/msg.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <pthread.h>
34 #include <fcntl.h>
35 #include <termios.h>
36 #include <sys/mman.h>
37 #include <sys/poll.h>
38 #include <sys/wait.h>
39 #include <sys/stat.h>
40 #include <sys/uio.h>
41 #include <libc-diag.h>
42 
43 
44 /* Since STREAMS are not supported in the standard Linux kernel and
45    there we don't advertise STREAMS as supported is no need to test
46    the STREAMS related functions.  This affects
47      getmsg()              getpmsg()          putmsg()
48      putpmsg()
49 
50    lockf() and fcntl() are tested in tst-cancel16.
51 
52    pthread_join() is tested in tst-join5.
53 
54    pthread_testcancel()'s only purpose is to allow cancellation.  This
55    is tested in several places.
56 
57    sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
58 
59    mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
60    in tst-mqueue8{,x} tests.
61 
62    aio_suspend() is tested in tst-cancel17.
63 
64    clock_nanosleep() is tested in tst-cancel18.
65 
66    Linux sendmmsg and recvmmsg are checked in tst-cancel4_1.c and
67    tst-cancel4_2.c respectively.
68 */
69 
70 #include "tst-cancel4-common.h"
71 
72 
73 #ifndef IPC_ADDVAL
74 # define IPC_ADDVAL 0
75 #endif
76 
77 
78 static void *
tf_read(void * arg)79 tf_read  (void *arg)
80 {
81   int fd;
82 
83   if (arg == NULL)
84     fd = fds[0];
85   else
86     {
87       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
88       tempfd = fd = mkstemp (fname);
89       if (fd == -1)
90 	FAIL_EXIT1 ("mkstemp failed: %m");
91       unlink (fname);
92 
93       xpthread_barrier_wait (&b2);
94     }
95 
96   xpthread_barrier_wait (&b2);
97 
98   ssize_t s;
99   pthread_cleanup_push (cl, NULL);
100 
101   char buf[100];
102   s = read (fd, buf, sizeof (buf));
103 
104   pthread_cleanup_pop (0);
105 
106   FAIL_EXIT1 ("read returns with %zd", s);
107 }
108 
109 
110 static void *
tf_readv(void * arg)111 tf_readv  (void *arg)
112 {
113   int fd;
114 
115   if (arg == NULL)
116     fd = fds[0];
117   else
118     {
119       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
120       tempfd = fd = mkstemp (fname);
121       if (fd == -1)
122 	FAIL_EXIT1 ("mkstemp failed: %m");
123       unlink (fname);
124 
125       xpthread_barrier_wait (&b2);
126     }
127 
128   xpthread_barrier_wait (&b2);
129 
130   ssize_t s;
131   pthread_cleanup_push (cl, NULL);
132 
133   char buf[100];
134   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
135   s = readv (fd, iov, 1);
136 
137   pthread_cleanup_pop (0);
138 
139   FAIL_EXIT1 ("readv returns with %zd", s);
140 }
141 
142 
143 static void *
tf_write(void * arg)144 tf_write  (void *arg)
145 {
146   int fd;
147 
148   if (arg == NULL)
149     fd = fds[1];
150   else
151     {
152       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
153       tempfd = fd = mkstemp (fname);
154       if (fd == -1)
155 	FAIL_EXIT1 ("mkstemp failed: %m");
156       unlink (fname);
157 
158       xpthread_barrier_wait (&b2);
159     }
160 
161   xpthread_barrier_wait (&b2);
162 
163   ssize_t s;
164   pthread_cleanup_push (cl, NULL);
165 
166   char buf[WRITE_BUFFER_SIZE];
167   memset (buf, '\0', sizeof (buf));
168   s = write (fd, buf, sizeof (buf));
169   /* The write can return a value higher than 0 (meaning partial write)
170      due to the SIGCANCEL, but the thread may still be pending
171      cancellation.  */
172   pthread_testcancel ();
173 
174   pthread_cleanup_pop (0);
175 
176   FAIL_EXIT1 ("write returns with %zd", s);
177 }
178 
179 
180 static void *
tf_writev(void * arg)181 tf_writev  (void *arg)
182 {
183   int fd;
184 
185   if (arg == NULL)
186     fd = fds[1];
187   else
188     {
189       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
190       tempfd = fd = mkstemp (fname);
191       if (fd == -1)
192 	FAIL_EXIT1 ("mkstemp failed: %m");
193       unlink (fname);
194 
195       xpthread_barrier_wait (&b2);
196     }
197 
198   xpthread_barrier_wait (&b2);
199 
200   ssize_t s;
201   pthread_cleanup_push (cl, NULL);
202 
203   char buf[WRITE_BUFFER_SIZE];
204   memset (buf, '\0', sizeof (buf));
205   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
206   s = writev (fd, iov, 1);
207 
208   pthread_cleanup_pop (0);
209 
210   FAIL_EXIT1 ("writev returns with %zd", s);
211 }
212 
213 
214 static void *
tf_sleep(void * arg)215 tf_sleep (void *arg)
216 {
217   xpthread_barrier_wait (&b2);
218 
219   if (arg != NULL)
220     xpthread_barrier_wait (&b2);
221 
222   pthread_cleanup_push (cl, NULL);
223 
224   sleep (arg == NULL ? 1000000 : 0);
225 
226   pthread_cleanup_pop (0);
227 
228   FAIL_EXIT1 ("sleep returns");
229 }
230 
231 
232 static void *
tf_usleep(void * arg)233 tf_usleep (void *arg)
234 {
235   xpthread_barrier_wait (&b2);
236 
237   if (arg != NULL)
238     xpthread_barrier_wait (&b2);
239 
240   pthread_cleanup_push (cl, NULL);
241 
242   usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
243 
244   pthread_cleanup_pop (0);
245 
246   FAIL_EXIT1 ("usleep returns");
247 }
248 
249 
250 static void *
tf_nanosleep(void * arg)251 tf_nanosleep (void *arg)
252 {
253   xpthread_barrier_wait (&b2);
254 
255   if (arg != NULL)
256     xpthread_barrier_wait (&b2);
257 
258   pthread_cleanup_push (cl, NULL);
259 
260   struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
261   TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
262 
263   pthread_cleanup_pop (0);
264 
265   FAIL_EXIT1 ("nanosleep returns");
266 }
267 
268 
269 static void *
tf_select(void * arg)270 tf_select (void *arg)
271 {
272   int fd;
273 
274   if (arg == NULL)
275     fd = fds[0];
276   else
277     {
278       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
279       tempfd = fd = mkstemp (fname);
280       if (fd == -1)
281 	FAIL_EXIT1 ("mkstemp failed: %m");
282       unlink (fname);
283 
284       xpthread_barrier_wait (&b2);
285     }
286 
287   xpthread_barrier_wait (&b2);
288 
289   fd_set rfs;
290   FD_ZERO (&rfs);
291   FD_SET (fd, &rfs);
292 
293   int s;
294   pthread_cleanup_push (cl, NULL);
295 
296   s = select (fd + 1, &rfs, NULL, NULL, NULL);
297 
298   pthread_cleanup_pop (0);
299 
300   FAIL_EXIT1 ("select returns with %d: %m", s);
301 }
302 
303 
304 static void *
tf_pselect(void * arg)305 tf_pselect (void *arg)
306 {
307   int fd;
308 
309   if (arg == NULL)
310     fd = fds[0];
311   else
312     {
313       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
314       tempfd = fd = mkstemp (fname);
315       if (fd == -1)
316 	FAIL_EXIT1 ("mkstemp failed: %m");
317       unlink (fname);
318 
319       xpthread_barrier_wait (&b2);
320     }
321 
322   xpthread_barrier_wait (&b2);
323 
324   fd_set rfs;
325   FD_ZERO (&rfs);
326   FD_SET (fd, &rfs);
327 
328   int s;
329   pthread_cleanup_push (cl, NULL);
330 
331   s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
332 
333   pthread_cleanup_pop (0);
334 
335   FAIL_EXIT1 ("pselect returns with %d: %m", s);
336 }
337 
338 
339 static void *
tf_poll(void * arg)340 tf_poll (void *arg)
341 {
342   int fd;
343 
344   if (arg == NULL)
345     fd = fds[0];
346   else
347     {
348       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
349       tempfd = fd = mkstemp (fname);
350       if (fd == -1)
351 	FAIL_EXIT1 ("mkstemp failed: %m");
352       unlink (fname);
353 
354       xpthread_barrier_wait (&b2);
355     }
356 
357   xpthread_barrier_wait (&b2);
358 
359   struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
360 
361   int s;
362   pthread_cleanup_push (cl, NULL);
363 
364   s = poll (rfs, 1, -1);
365 
366   pthread_cleanup_pop (0);
367 
368   FAIL_EXIT1 ("poll returns with %d: %m", s);
369 }
370 
371 
372 static void *
tf_ppoll(void * arg)373 tf_ppoll (void *arg)
374 {
375   int fd;
376 
377   if (arg == NULL)
378     fd = fds[0];
379   else
380     {
381       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
382       tempfd = fd = mkstemp (fname);
383       if (fd == -1)
384 	FAIL_EXIT1 ("mkstemp failed: %m");
385       unlink (fname);
386 
387       xpthread_barrier_wait (&b2);
388     }
389 
390   xpthread_barrier_wait (&b2);
391 
392   struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
393 
394   int s;
395   pthread_cleanup_push (cl, NULL);
396 
397   s = ppoll (rfs, 1, NULL, NULL);
398 
399   pthread_cleanup_pop (0);
400 
401   FAIL_EXIT1 ("ppoll returns with %d: %m", s);
402 }
403 
404 
405 static void *
tf_wait(void * arg)406 tf_wait (void *arg)
407 {
408   pid_t pid = fork ();
409   if (pid == -1)
410     FAIL_EXIT1 ("fork: %m");
411 
412   if (pid == 0)
413     {
414       /* Make the program disappear after a while.  */
415       if (arg == NULL)
416 	sleep (10);
417       exit (0);
418     }
419 
420   if (arg != NULL)
421     {
422       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
423       while (nanosleep (&ts, &ts) != 0)
424 	continue;
425 
426       xpthread_barrier_wait (&b2);
427     }
428 
429   xpthread_barrier_wait (&b2);
430 
431   int s;
432   pthread_cleanup_push (cl, NULL);
433 
434   s = wait (NULL);
435 
436   pthread_cleanup_pop (0);
437 
438   FAIL_EXIT1 ("wait returns with %d: %m", s);
439 }
440 
441 
442 static void *
tf_waitpid(void * arg)443 tf_waitpid (void *arg)
444 {
445   pid_t pid = fork ();
446   if (pid == -1)
447     FAIL_EXIT1 ("fork: %m");
448 
449   if (pid == 0)
450     {
451       /* Make the program disappear after a while.  */
452       if (arg == NULL)
453 	sleep (10);
454       exit (0);
455     }
456 
457   if (arg != NULL)
458     {
459       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
460       while (nanosleep (&ts, &ts) != 0)
461 	continue;
462 
463       xpthread_barrier_wait (&b2);
464     }
465 
466   xpthread_barrier_wait (&b2);
467 
468   int s;
469   pthread_cleanup_push (cl, NULL);
470 
471   s = waitpid (-1, NULL, 0);
472 
473   pthread_cleanup_pop (0);
474 
475   FAIL_EXIT1 ("waitpid returns with %d: %m", s);
476 }
477 
478 
479 static void *
tf_waitid(void * arg)480 tf_waitid (void *arg)
481 {
482   pid_t pid = fork ();
483   if (pid == -1)
484     FAIL_EXIT1 ("fork: %m");
485 
486   if (pid == 0)
487     {
488       /* Make the program disappear after a while.  */
489       if (arg == NULL)
490 	sleep (10);
491       exit (0);
492     }
493 
494   if (arg != NULL)
495     {
496       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
497       while (nanosleep (&ts, &ts) != 0)
498 	continue;
499 
500       xpthread_barrier_wait (&b2);
501     }
502 
503   xpthread_barrier_wait (&b2);
504 
505   int s;
506   pthread_cleanup_push (cl, NULL);
507 
508 #ifndef WEXITED
509 # define WEXITED 0
510 #endif
511   siginfo_t si;
512   s = waitid (P_PID, pid, &si, WEXITED);
513 
514   pthread_cleanup_pop (0);
515 
516   FAIL_EXIT1 ("waitid returns with %d: %m", s);
517 }
518 
519 
520 static void *
tf_sigpause(void * arg)521 tf_sigpause (void *arg)
522 {
523   xpthread_barrier_wait (&b2);
524 
525   if (arg != NULL)
526     xpthread_barrier_wait (&b2);
527 
528   pthread_cleanup_push (cl, NULL);
529 
530   /* This tests the deprecated sigpause and sigmask functions.  The
531      file is compiled with -Wno-errno so that the sigmask deprecation
532      warning is not fatal.  */
533   DIAG_PUSH_NEEDS_COMMENT;
534   DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
535   sigpause (sigmask (SIGINT));
536   DIAG_POP_NEEDS_COMMENT;
537 
538   pthread_cleanup_pop (0);
539 
540   FAIL_EXIT1 ("sigpause returned");
541 }
542 
543 
544 static void *
tf_sigsuspend(void * arg)545 tf_sigsuspend (void *arg)
546 {
547   xpthread_barrier_wait (&b2);
548 
549   if (arg != NULL)
550     xpthread_barrier_wait (&b2);
551 
552   pthread_cleanup_push (cl, NULL);
553 
554   /* Just for fun block all signals.  */
555   sigset_t mask;
556   sigfillset (&mask);
557   sigsuspend (&mask);
558 
559   pthread_cleanup_pop (0);
560 
561   FAIL_EXIT1 ("sigsuspend returned");
562 }
563 
564 
565 static void *
tf_sigwait(void * arg)566 tf_sigwait (void *arg)
567 {
568   xpthread_barrier_wait (&b2);
569 
570   if (arg != NULL)
571     xpthread_barrier_wait (&b2);
572 
573   /* Block SIGUSR1.  */
574   sigset_t mask;
575   sigemptyset (&mask);
576   sigaddset (&mask, SIGUSR1);
577   TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0);
578 
579   int sig;
580   pthread_cleanup_push (cl, NULL);
581 
582   /* Wait for SIGUSR1.  */
583   sigwait (&mask, &sig);
584 
585   pthread_cleanup_pop (0);
586 
587   FAIL_EXIT1 ("sigwait returned with signal %d", sig);
588 }
589 
590 
591 static void *
tf_sigwaitinfo(void * arg)592 tf_sigwaitinfo (void *arg)
593 {
594   xpthread_barrier_wait (&b2);
595 
596   if (arg != NULL)
597     xpthread_barrier_wait (&b2);
598 
599   /* Block SIGUSR1.  */
600   sigset_t mask;
601   sigemptyset (&mask);
602   sigaddset (&mask, SIGUSR1);
603   TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0);
604 
605   siginfo_t info;
606   pthread_cleanup_push (cl, NULL);
607 
608   /* Wait for SIGUSR1.  */
609   int ret;
610   ret = sigwaitinfo (&mask, &info);
611   if (ret == -1 && errno == ENOSYS)
612     {
613       int sig;
614 
615       printf ("sigwaitinfo not supported\n");
616       sigwait (&mask, &sig);
617     }
618 
619   pthread_cleanup_pop (0);
620 
621   FAIL_EXIT1 ("sigwaitinfo returned with signal %d", info.si_signo);
622 }
623 
624 
625 static void *
tf_sigtimedwait(void * arg)626 tf_sigtimedwait (void *arg)
627 {
628   xpthread_barrier_wait (&b2);
629 
630   if (arg != NULL)
631     xpthread_barrier_wait (&b2);
632 
633   /* Block SIGUSR1.  */
634   sigset_t mask;
635   sigemptyset (&mask);
636   sigaddset (&mask, SIGUSR1);
637   TEST_VERIFY_EXIT (pthread_sigmask (SIG_BLOCK, &mask, NULL) == 0);
638 
639   /* Wait for SIGUSR1.  */
640   siginfo_t info;
641   struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
642   pthread_cleanup_push (cl, NULL);
643 
644   int ret;
645   ret = sigtimedwait (&mask, &info, &ts);
646   if (ret == -1 && errno == ENOSYS)
647     {
648       int sig;
649       printf ("sigtimedwait not supported\n");
650 
651       sigwait (&mask, &sig);
652     }
653 
654   pthread_cleanup_pop (0);
655 
656   FAIL_EXIT1 ("sigtimedwait returned with signal %d", info.si_signo);
657 }
658 
659 
660 static void *
tf_pause(void * arg)661 tf_pause (void *arg)
662 {
663   xpthread_barrier_wait (&b2);
664 
665   if (arg != NULL)
666     xpthread_barrier_wait (&b2);
667 
668   pthread_cleanup_push (cl, NULL);
669 
670   pause ();
671 
672   pthread_cleanup_pop (0);
673 
674   FAIL_EXIT1 ("pause returned");
675 }
676 
677 
678 static void *
tf_accept(void * arg)679 tf_accept (void *arg)
680 {
681   struct sockaddr_un sun;
682   /* To test a non-blocking accept call we make the call file by using
683      a datagrame socket.  */
684   int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
685 
686   tempfd = socket (AF_UNIX, pf, 0);
687   if (tempfd == -1)
688     FAIL_EXIT1 ("socket (AF_UNIX, %s, 0): %m", arg == NULL ? "SOCK_STREAM"
689 					       : "SOCK_DGRAM");
690 
691   int tries = 0;
692   do
693     {
694       TEST_VERIFY_EXIT (tries++ < 10);
695 
696       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
697       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
698 
699       sun.sun_family = AF_UNIX;
700     }
701   while (bind (tempfd, (struct sockaddr *) &sun,
702 	       offsetof (struct sockaddr_un, sun_path)
703 	       + strlen (sun.sun_path) + 1) != 0);
704 
705   unlink (sun.sun_path);
706 
707   listen (tempfd, 5);
708 
709   socklen_t len = sizeof (sun);
710 
711   xpthread_barrier_wait (&b2);
712 
713   if (arg != NULL)
714     xpthread_barrier_wait (&b2);
715 
716   pthread_cleanup_push (cl, NULL);
717 
718   accept (tempfd, (struct sockaddr *) &sun, &len);
719 
720   pthread_cleanup_pop (0);
721 
722   FAIL_EXIT1 ("accept returned");
723 }
724 
725 
726 static void *
tf_send(void * arg)727 tf_send (void *arg)
728 {
729   struct sockaddr_un sun;
730 
731   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
732   if (tempfd == -1)
733     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
734 
735   int tries = 0;
736   do
737     {
738       TEST_VERIFY_EXIT (tries++ < 10);
739 
740       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
741       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
742 
743       sun.sun_family = AF_UNIX;
744     }
745   while (bind (tempfd, (struct sockaddr *) &sun,
746 	       offsetof (struct sockaddr_un, sun_path)
747 	       + strlen (sun.sun_path) + 1) != 0);
748 
749   listen (tempfd, 5);
750 
751   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
752   if (tempfd2 == -1)
753     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
754 
755   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
756     FAIL_EXIT1 ("connect: %m");
757 
758   unlink (sun.sun_path);
759 
760   set_socket_buffer (tempfd2);
761 
762   xpthread_barrier_wait (&b2);
763 
764   if (arg != NULL)
765     xpthread_barrier_wait (&b2);
766 
767   pthread_cleanup_push (cl, NULL);
768 
769   char mem[WRITE_BUFFER_SIZE];
770 
771   size_t s = send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
772   /* The send can return a value higher than 0 (meaning partial send)
773      due to the SIGCANCEL, but the thread may still be pending
774      cancellation.  */
775   pthread_testcancel ();
776   printf("send returned %zd\n", s);
777 
778   pthread_cleanup_pop (0);
779 
780   FAIL_EXIT1 ("send returned");
781 }
782 
783 
784 static void *
tf_recv(void * arg)785 tf_recv (void *arg)
786 {
787   struct sockaddr_un sun;
788 
789   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
790   if (tempfd == -1)
791     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
792 
793   int tries = 0;
794   do
795     {
796       TEST_VERIFY_EXIT (tries++ < 10);
797 
798       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
799       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
800 
801       sun.sun_family = AF_UNIX;
802     }
803   while (bind (tempfd, (struct sockaddr *) &sun,
804 	       offsetof (struct sockaddr_un, sun_path)
805 	       + strlen (sun.sun_path) + 1) != 0);
806 
807   listen (tempfd, 5);
808 
809   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
810   if (tempfd2 == -1)
811     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
812 
813   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
814     FAIL_EXIT1 ("connect: %m");
815 
816   unlink (sun.sun_path);
817 
818   xpthread_barrier_wait (&b2);
819 
820   if (arg != NULL)
821     xpthread_barrier_wait (&b2);
822 
823   pthread_cleanup_push (cl, NULL);
824 
825   char mem[70];
826 
827   recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
828 
829   pthread_cleanup_pop (0);
830 
831   FAIL_EXIT1 ("recv returned");
832 }
833 
834 
835 static void *
tf_recvfrom(void * arg)836 tf_recvfrom (void *arg)
837 {
838   struct sockaddr_un sun;
839 
840   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
841   if (tempfd == -1)
842     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
843 
844   int tries = 0;
845   do
846     {
847       TEST_VERIFY_EXIT (tries++ < 10);
848 
849       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
850       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
851 
852       sun.sun_family = AF_UNIX;
853     }
854   while (bind (tempfd, (struct sockaddr *) &sun,
855 	       offsetof (struct sockaddr_un, sun_path)
856 	       + strlen (sun.sun_path) + 1) != 0);
857 
858   tempfname = strdup (sun.sun_path);
859 
860   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
861   if (tempfd2 == -1)
862     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
863 
864   xpthread_barrier_wait (&b2);
865 
866   if (arg != NULL)
867     xpthread_barrier_wait (&b2);
868 
869   pthread_cleanup_push (cl, NULL);
870 
871   char mem[70];
872   socklen_t len = sizeof (sun);
873 
874   recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
875 	    (struct sockaddr *) &sun, &len);
876 
877   pthread_cleanup_pop (0);
878 
879   FAIL_EXIT1 ("recvfrom returned");
880 }
881 
882 
883 static void *
tf_recvmsg(void * arg)884 tf_recvmsg (void *arg)
885 {
886   struct sockaddr_un sun;
887 
888   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
889   if (tempfd == -1)
890     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
891 
892   int tries = 0;
893   do
894     {
895       TEST_VERIFY_EXIT (tries++ < 10);
896 
897       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
898       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
899 
900       sun.sun_family = AF_UNIX;
901     }
902   while (bind (tempfd, (struct sockaddr *) &sun,
903 	       offsetof (struct sockaddr_un, sun_path)
904 	       + strlen (sun.sun_path) + 1) != 0);
905 
906   tempfname = strdup (sun.sun_path);
907 
908   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
909   if (tempfd2 == -1)
910     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
911 
912   xpthread_barrier_wait (&b2);
913 
914   if (arg != NULL)
915     xpthread_barrier_wait (&b2);
916 
917   pthread_cleanup_push (cl, NULL);
918 
919   char mem[70];
920   struct iovec iov[1];
921   iov[0].iov_base = mem;
922   iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
923 
924   struct msghdr m;
925   m.msg_name = &sun;
926   m.msg_namelen = sizeof (sun);
927   m.msg_iov = iov;
928   m.msg_iovlen = 1;
929   m.msg_control = NULL;
930   m.msg_controllen = 0;
931 
932   recvmsg (tempfd2, &m, 0);
933 
934   pthread_cleanup_pop (0);
935 
936   FAIL_EXIT1 ("recvmsg returned");
937 }
938 
939 static void *
tf_open(void * arg)940 tf_open (void *arg)
941 {
942   if (arg == NULL)
943     {
944       fifofd = mkfifo (fifoname, S_IWUSR | S_IRUSR);
945       if (fifofd == -1)
946 	FAIL_EXIT1 ("mkfifo: %m");
947     }
948   else
949     {
950       xpthread_barrier_wait (&b2);
951     }
952 
953   xpthread_barrier_wait (&b2);
954 
955   pthread_cleanup_push (cl_fifo, NULL);
956 
957   open (arg ? "Makefile" : fifoname, O_RDONLY);
958 
959   pthread_cleanup_pop (0);
960 
961   FAIL_EXIT1 ("open returned");
962 }
963 
964 
965 static void *
tf_close(void * arg)966 tf_close (void *arg)
967 {
968   if (arg == NULL)
969     // XXX If somebody can provide a portable test case in which close()
970     // blocks we can enable this test to run in both rounds.
971     abort ();
972 
973   char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
974   tempfd = mkstemp (fname);
975   if (tempfd == -1)
976     FAIL_EXIT1 ("mkstemp failed: %m");
977   unlink (fname);
978 
979   xpthread_barrier_wait (&b2);
980 
981   xpthread_barrier_wait (&b2);
982 
983   pthread_cleanup_push (cl, NULL);
984 
985   close (tempfd);
986 
987   pthread_cleanup_pop (0);
988 
989   FAIL_EXIT1 ("close returned");
990 }
991 
992 
993 static void *
tf_pread(void * arg)994 tf_pread (void *arg)
995 {
996   if (arg == NULL)
997     // XXX If somebody can provide a portable test case in which pread()
998     // blocks we can enable this test to run in both rounds.
999     abort ();
1000 
1001   tempfd = open ("Makefile", O_RDONLY);
1002   if (tempfd == -1)
1003     FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1004 
1005   xpthread_barrier_wait (&b2);
1006 
1007   xpthread_barrier_wait (&b2);
1008 
1009   pthread_cleanup_push (cl, NULL);
1010 
1011   char mem[10];
1012   pread (tempfd, mem, sizeof (mem), 0);
1013 
1014   pthread_cleanup_pop (0);
1015 
1016   FAIL_EXIT1 ("pread returned");
1017 }
1018 
1019 
1020 static void *
tf_pwrite(void * arg)1021 tf_pwrite (void *arg)
1022 {
1023   if (arg == NULL)
1024     // XXX If somebody can provide a portable test case in which pwrite()
1025     // blocks we can enable this test to run in both rounds.
1026     abort ();
1027 
1028   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1029   tempfd = mkstemp (fname);
1030   if (tempfd == -1)
1031     FAIL_EXIT1 ("mkstemp failed: %m");
1032   unlink (fname);
1033 
1034   xpthread_barrier_wait (&b2);
1035 
1036   xpthread_barrier_wait (&b2);
1037 
1038   pthread_cleanup_push (cl, NULL);
1039 
1040   char mem[10];
1041   pwrite (tempfd, mem, sizeof (mem), 0);
1042 
1043   pthread_cleanup_pop (0);
1044 
1045   FAIL_EXIT1 ("pwrite returned");
1046 }
1047 
1048 static void *
tf_preadv(void * arg)1049 tf_preadv (void *arg)
1050 {
1051   int fd;
1052 
1053   if (arg == NULL)
1054     /* XXX If somebody can provide a portable test case in which preadv
1055        blocks we can enable this test to run in both rounds.  */
1056     abort ();
1057 
1058   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1059   tempfd = fd = mkstemp (fname);
1060   if (fd == -1)
1061     FAIL_EXIT1 ("mkstemp failed: %m");
1062   unlink (fname);
1063 
1064   xpthread_barrier_wait (&b2);
1065 
1066   xpthread_barrier_wait (&b2);
1067 
1068   ssize_t s;
1069   pthread_cleanup_push (cl, NULL);
1070 
1071   char buf[100];
1072   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1073   s = preadv (fd, iov, 1, 0);
1074 
1075   pthread_cleanup_pop (0);
1076 
1077   FAIL_EXIT1 ("preadv returns with %zd", s);
1078 }
1079 
1080 static void *
tf_pwritev(void * arg)1081 tf_pwritev (void *arg)
1082 {
1083   int fd;
1084 
1085   if (arg == NULL)
1086     /* XXX If somebody can provide a portable test case in which pwritev
1087        blocks we can enable this test to run in both rounds.  */
1088     abort ();
1089 
1090   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1091   tempfd = fd = mkstemp (fname);
1092   if (fd == -1)
1093     FAIL_EXIT1 ("mkstemp failed: %m");
1094   unlink (fname);
1095 
1096   xpthread_barrier_wait (&b2);
1097 
1098   xpthread_barrier_wait (&b2);
1099 
1100   ssize_t s;
1101   pthread_cleanup_push (cl, NULL);
1102 
1103   char buf[WRITE_BUFFER_SIZE];
1104   memset (buf, '\0', sizeof (buf));
1105   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1106   s = pwritev (fd, iov, 1, 0);
1107 
1108   pthread_cleanup_pop (0);
1109 
1110   FAIL_EXIT1 ("pwritev returns with %zd", s);
1111 }
1112 
1113 static void *
tf_pwritev2(void * arg)1114 tf_pwritev2 (void *arg)
1115 {
1116   int fd;
1117 
1118   if (arg == NULL)
1119     /* XXX If somebody can provide a portable test case in which pwritev2
1120        blocks we can enable this test to run in both rounds.  */
1121     abort ();
1122 
1123   errno = 0;
1124 
1125   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1126   tempfd = fd = mkstemp (fname);
1127   if (fd == -1)
1128     FAIL_EXIT1 ("mkstemp: %m");
1129   unlink (fname);
1130 
1131   xpthread_barrier_wait (&b2);
1132 
1133   xpthread_barrier_wait (&b2);
1134 
1135   ssize_t s;
1136   pthread_cleanup_push (cl, NULL);
1137 
1138   char buf[WRITE_BUFFER_SIZE];
1139   memset (buf, '\0', sizeof (buf));
1140   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1141   s = pwritev2 (fd, iov, 1, 0, 0);
1142 
1143   pthread_cleanup_pop (0);
1144 
1145   FAIL_EXIT1 ("pwritev2 returns with %zd", s);
1146 }
1147 
1148 static void *
tf_preadv2(void * arg)1149 tf_preadv2 (void *arg)
1150 {
1151   int fd;
1152 
1153   if (arg == NULL)
1154     /* XXX If somebody can provide a portable test case in which preadv2
1155        blocks we can enable this test to run in both rounds.  */
1156     abort ();
1157 
1158   errno = 0;
1159 
1160   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1161   tempfd = fd = mkstemp (fname);
1162   if (fd == -1)
1163     FAIL_EXIT1 ("mkstemp failed: %m");
1164   unlink (fname);
1165 
1166   xpthread_barrier_wait (&b2);
1167 
1168   xpthread_barrier_wait (&b2);
1169 
1170   ssize_t s;
1171   pthread_cleanup_push (cl, NULL);
1172 
1173   char buf[100];
1174   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
1175   s = preadv2 (fd, iov, 1, 0, 0);
1176 
1177   pthread_cleanup_pop (0);
1178 
1179   FAIL_EXIT1 ("preadv2 returns with %zd", s);
1180 }
1181 
1182 static void *
tf_fsync(void * arg)1183 tf_fsync (void *arg)
1184 {
1185   if (arg == NULL)
1186     // XXX If somebody can provide a portable test case in which fsync()
1187     // blocks we can enable this test to run in both rounds.
1188     abort ();
1189 
1190   tempfd = open ("Makefile", O_RDONLY);
1191   if (tempfd == -1)
1192     FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1193 
1194   xpthread_barrier_wait (&b2);
1195 
1196   xpthread_barrier_wait (&b2);
1197 
1198   pthread_cleanup_push (cl, NULL);
1199 
1200   fsync (tempfd);
1201 
1202   pthread_cleanup_pop (0);
1203 
1204   FAIL_EXIT1 ("fsync returned");
1205 }
1206 
1207 
1208 static void *
tf_fdatasync(void * arg)1209 tf_fdatasync (void *arg)
1210 {
1211   if (arg == NULL)
1212     // XXX If somebody can provide a portable test case in which fdatasync()
1213     // blocks we can enable this test to run in both rounds.
1214     abort ();
1215 
1216   tempfd = open ("Makefile", O_RDONLY);
1217   if (tempfd == -1)
1218     FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1219 
1220   xpthread_barrier_wait (&b2);
1221 
1222   xpthread_barrier_wait (&b2);
1223 
1224   pthread_cleanup_push (cl, NULL);
1225 
1226   fdatasync (tempfd);
1227 
1228   pthread_cleanup_pop (0);
1229 
1230   FAIL_EXIT1 ("fdatasync returned");
1231 }
1232 
1233 
1234 static void *
tf_msync(void * arg)1235 tf_msync (void *arg)
1236 {
1237   if (arg == NULL)
1238     // XXX If somebody can provide a portable test case in which msync()
1239     // blocks we can enable this test to run in both rounds.
1240     abort ();
1241 
1242   tempfd = open ("Makefile", O_RDONLY);
1243   if (tempfd == -1)
1244     FAIL_EXIT1 ("open (\"Makefile\", O_RDONLY): %m");
1245 
1246   void *p = xmmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd);
1247 
1248   xpthread_barrier_wait (&b2);
1249 
1250   xpthread_barrier_wait (&b2);
1251 
1252   pthread_cleanup_push (cl, NULL);
1253 
1254   msync (p, 10, 0);
1255 
1256   pthread_cleanup_pop (0);
1257 
1258   FAIL_EXIT1 ("msync returned");
1259 }
1260 
1261 
1262 static void *
tf_sendto(void * arg)1263 tf_sendto (void *arg)
1264 {
1265   struct sockaddr_un sun;
1266 
1267   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1268   if (tempfd == -1)
1269     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1270 
1271   int tries = 0;
1272   do
1273     {
1274       TEST_VERIFY_EXIT (tries++ < 10);
1275 
1276       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1277       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
1278 
1279       sun.sun_family = AF_UNIX;
1280     }
1281   while (bind (tempfd, (struct sockaddr *) &sun,
1282 	       offsetof (struct sockaddr_un, sun_path)
1283 	       + strlen (sun.sun_path) + 1) != 0);
1284 
1285   listen (tempfd, 5);
1286 
1287   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1288   if (tempfd2 == -1)
1289     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1290 
1291   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1292     FAIL_EXIT1 ("connect: %m");
1293 
1294   unlink (sun.sun_path);
1295 
1296   set_socket_buffer (tempfd2);
1297 
1298   xpthread_barrier_wait (&b2);
1299 
1300   if (arg != NULL)
1301     xpthread_barrier_wait (&b2);
1302 
1303   pthread_cleanup_push (cl, NULL);
1304 
1305   char mem[WRITE_BUFFER_SIZE];
1306 
1307   sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0, NULL, 0);
1308 
1309   pthread_cleanup_pop (0);
1310 
1311   FAIL_EXIT1 ("sendto returned");
1312 }
1313 
1314 
1315 static void *
tf_sendmsg(void * arg)1316 tf_sendmsg (void *arg)
1317 {
1318   if (arg == NULL)
1319     // XXX If somebody can provide a portable test case in which sendmsg()
1320     // blocks we can enable this test to run in both rounds.
1321     abort ();
1322 
1323   struct sockaddr_un sun;
1324 
1325   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1326   if (tempfd == -1)
1327     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
1328 
1329   int tries = 0;
1330   do
1331     {
1332       TEST_VERIFY_EXIT (tries++ < 10);
1333 
1334       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1335       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
1336 
1337       sun.sun_family = AF_UNIX;
1338     }
1339   while (bind (tempfd, (struct sockaddr *) &sun,
1340 	       offsetof (struct sockaddr_un, sun_path)
1341 	       + strlen (sun.sun_path) + 1) != 0);
1342   tempfname = strdup (sun.sun_path);
1343 
1344   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1345   if (tempfd2 == -1)
1346     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
1347 
1348   xpthread_barrier_wait (&b2);
1349 
1350   xpthread_barrier_wait (&b2);
1351 
1352   pthread_cleanup_push (cl, NULL);
1353 
1354   char mem[1];
1355   struct iovec iov[1];
1356   iov[0].iov_base = mem;
1357   iov[0].iov_len = 1;
1358 
1359   struct msghdr m;
1360   m.msg_name = &sun;
1361   m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1362 		   + strlen (sun.sun_path) + 1);
1363   m.msg_iov = iov;
1364   m.msg_iovlen = 1;
1365   m.msg_control = NULL;
1366   m.msg_controllen = 0;
1367 
1368   sendmsg (tempfd2, &m, 0);
1369 
1370   pthread_cleanup_pop (0);
1371 
1372   FAIL_EXIT1 ("sendmsg returned");
1373 }
1374 
1375 
1376 static void *
tf_creat(void * arg)1377 tf_creat (void *arg)
1378 {
1379   if (arg == NULL)
1380     // XXX If somebody can provide a portable test case in which sendmsg()
1381     // blocks we can enable this test to run in both rounds.
1382     abort ();
1383 
1384   xpthread_barrier_wait (&b2);
1385 
1386   xpthread_barrier_wait (&b2);
1387 
1388   pthread_cleanup_push (cl, NULL);
1389 
1390   creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1391 
1392   pthread_cleanup_pop (0);
1393 
1394   FAIL_EXIT1 ("creat returned");
1395 }
1396 
1397 
1398 static void *
tf_connect(void * arg)1399 tf_connect (void *arg)
1400 {
1401   if (arg == NULL)
1402     // XXX If somebody can provide a portable test case in which connect()
1403     // blocks we can enable this test to run in both rounds.
1404     abort ();
1405 
1406   struct sockaddr_un sun;
1407 
1408   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1409   if (tempfd == -1)
1410     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1411 
1412   int tries = 0;
1413   do
1414     {
1415       TEST_VERIFY_EXIT (tries++ < 10);
1416 
1417       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1418       TEST_VERIFY_EXIT (mktemp (sun.sun_path) != NULL);
1419 
1420       sun.sun_family = AF_UNIX;
1421     }
1422   while (bind (tempfd, (struct sockaddr *) &sun,
1423 	       offsetof (struct sockaddr_un, sun_path)
1424 	       + strlen (sun.sun_path) + 1) != 0);
1425   tempfname = strdup (sun.sun_path);
1426 
1427   listen (tempfd, 5);
1428 
1429   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1430   if (tempfd2 == -1)
1431     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
1432 
1433   xpthread_barrier_wait (&b2);
1434 
1435   if (arg != NULL)
1436     xpthread_barrier_wait (&b2);
1437 
1438   pthread_cleanup_push (cl, NULL);
1439 
1440   connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1441 
1442   pthread_cleanup_pop (0);
1443 
1444   FAIL_EXIT1 ("connect returned");
1445 }
1446 
1447 
1448 static void *
tf_tcdrain(void * arg)1449 tf_tcdrain (void *arg)
1450 {
1451   if (arg == NULL)
1452     // XXX If somebody can provide a portable test case in which tcdrain()
1453     // blocks we can enable this test to run in both rounds.
1454     abort ();
1455 
1456   xpthread_barrier_wait (&b2);
1457 
1458   if (arg != NULL)
1459     xpthread_barrier_wait (&b2);
1460 
1461   pthread_cleanup_push (cl, NULL);
1462 
1463   /* Regardless of stderr being a terminal, the tcdrain call should be
1464      canceled.  */
1465   tcdrain (STDERR_FILENO);
1466 
1467   pthread_cleanup_pop (0);
1468 
1469   FAIL_EXIT1 ("tcdrain returned");
1470 }
1471 
1472 
1473 static void *
tf_msgrcv(void * arg)1474 tf_msgrcv (void *arg)
1475 {
1476   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1477   if (tempmsg == -1)
1478     {
1479       if (errno == ENOSYS)
1480 	{
1481 	  printf ("msgget not supported\n");
1482 	  tf_usleep (arg);
1483 	  pthread_exit (NULL);
1484 	}
1485       else
1486 	FAIL_EXIT1 ("msgget (IPC_PRIVATE, 0666 | IPC_CREAT): %m");
1487     }
1488 
1489   xpthread_barrier_wait (&b2);
1490 
1491   if (arg != NULL)
1492     xpthread_barrier_wait (&b2);
1493 
1494   ssize_t s;
1495 
1496   pthread_cleanup_push (cl, NULL);
1497 
1498   struct
1499   {
1500     long int type;
1501     char mem[10];
1502   } m;
1503   int randnr;
1504   /* We need a positive random number.  */
1505   do
1506     randnr = random () % 64000;
1507   while (randnr <= 0);
1508   do
1509     {
1510       errno = 0;
1511       s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
1512     }
1513   while (errno == EIDRM || errno == EINTR);
1514 
1515   pthread_cleanup_pop (0);
1516 
1517   msgctl (tempmsg, IPC_RMID, NULL);
1518 
1519   FAIL_EXIT1 ("msgrcv returned %zd", s);
1520 }
1521 
1522 
1523 static void *
tf_msgsnd(void * arg)1524 tf_msgsnd (void *arg)
1525 {
1526   if (arg == NULL)
1527     // XXX If somebody can provide a portable test case in which msgsnd()
1528     // blocks we can enable this test to run in both rounds.
1529     abort ();
1530 
1531   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1532   if (tempmsg == -1)
1533     {
1534       if (errno == ENOSYS)
1535 	{
1536 	  printf ("msgget not supported\n");
1537 	  tf_usleep (arg);
1538 	  pthread_exit (NULL);
1539 	}
1540       else
1541 	FAIL_EXIT1 ("msgget (IPC_PRIVATE, 0666 | IPC_CREAT): %m");
1542     }
1543 
1544   xpthread_barrier_wait (&b2);
1545 
1546   xpthread_barrier_wait (&b2);
1547 
1548   pthread_cleanup_push (cl, NULL);
1549 
1550   struct
1551   {
1552     long int type;
1553     char mem[1];
1554   } m;
1555   /* We need a positive random number.  */
1556   do
1557     m.type = random () % 64000;
1558   while (m.type <= 0);
1559   msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
1560 
1561   pthread_cleanup_pop (0);
1562 
1563   msgctl (tempmsg, IPC_RMID, NULL);
1564 
1565   FAIL_EXIT1 ("msgsnd returned");
1566 }
1567 
1568 
1569 struct cancel_tests tests[] =
1570 {
1571   ADD_TEST (read, 2, 0),
1572   ADD_TEST (readv, 2, 0),
1573   ADD_TEST (select, 2, 0),
1574   ADD_TEST (pselect, 2, 0),
1575   ADD_TEST (poll, 2, 0),
1576   ADD_TEST (ppoll, 2, 0),
1577   ADD_TEST (write, 2, 0),
1578   ADD_TEST (writev, 2, 0),
1579   ADD_TEST (sleep, 2, 0),
1580   ADD_TEST (usleep, 2, 0),
1581   ADD_TEST (nanosleep, 2, 0),
1582   ADD_TEST (wait, 2, 0),
1583   ADD_TEST (waitid, 2, 0),
1584   ADD_TEST (waitpid, 2, 0),
1585   ADD_TEST (sigpause, 2, 0),
1586   ADD_TEST (sigsuspend, 2, 0),
1587   ADD_TEST (sigwait, 2, 0),
1588   ADD_TEST (sigwaitinfo, 2, 0),
1589   ADD_TEST (sigtimedwait, 2, 0),
1590   ADD_TEST (pause, 2, 0),
1591   ADD_TEST (accept, 2, 0),
1592   ADD_TEST (send, 2, 0),
1593   ADD_TEST (recv, 2, 0),
1594   ADD_TEST (recvfrom, 2, 0),
1595   ADD_TEST (recvmsg, 2, 0),
1596   ADD_TEST (preadv, 2, 1),
1597   ADD_TEST (preadv2, 2, 1),
1598   ADD_TEST (pwritev, 2, 1),
1599   ADD_TEST (pwritev2, 2, 1),
1600   ADD_TEST (open, 2, 1),
1601   ADD_TEST (close, 2, 1),
1602   ADD_TEST (pread, 2, 1),
1603   ADD_TEST (pwrite, 2, 1),
1604   ADD_TEST (fsync, 2, 1),
1605   ADD_TEST (fdatasync, 2, 1),
1606   ADD_TEST (msync, 2, 1),
1607   ADD_TEST (sendto, 2, 1),
1608   ADD_TEST (sendmsg, 2, 1),
1609   ADD_TEST (creat, 2, 1),
1610   ADD_TEST (connect, 2, 1),
1611   ADD_TEST (tcdrain, 2, 1),
1612   ADD_TEST (msgrcv, 2, 0),
1613   ADD_TEST (msgsnd, 2, 1),
1614 };
1615 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
1616 
1617 #include "tst-cancel4-common.c"
1618