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