]> granicus.if.org Git - strace/blob - test/wait_must_be_interruptible.c
Add argument to tprint_iov() specifying whether to decode each iovec
[strace] / test / wait_must_be_interruptible.c
1 #include <unistd.h>
2 #include <sys/types.h>
3 #include <signal.h>
4 #include <sys/wait.h>
5 #include <stdio.h>
6
7 /* Expected order is:
8  * Child signals parent
9  * Parent got signal
10  * Child will exit now
11  *
12  * The bug we test for: under strace -f, last two lines are swapped
13  * because wait syscall is suspended by strace and thus can't be interrupted.
14  */
15
16 static const char msg1[] = "Child signals parent\n";
17 static const char msg2[] = "Parent got signal\n";
18 static const char msg3[] = "Child will exit now\n";
19
20 static void handler(int s)
21 {
22         write(1, msg2, sizeof(msg2)-1);
23 }
24
25 static void test()
26 {
27         /* Note: in Linux, signal() installs handler with SA_RESTART flag,
28          * therefore wait will be restarted.
29          */
30         signal(SIGALRM, handler);
31
32         if (fork() == 0) {
33                 /* child */
34                 sleep(1);
35                 write(1, msg1, sizeof(msg1)-1);
36                 kill(getppid(), SIGALRM);
37                 sleep(1);
38                 write(1, msg3, sizeof(msg3)-1);
39                 _exit(0);
40         }
41
42         /* parent */
43         wait(NULL);
44         _exit(0);
45 }
46
47 int main()
48 {
49         char buf1[80];
50         char buf2[80];
51         char buf3[80];
52         int pipefd[2];
53
54         printf("Please run me under 'strace -f'\n");
55
56         pipe(pipefd);
57
58         if (fork() == 0) {
59                 if (pipefd[1] != 1) {
60                         dup2(pipefd[1], 1);
61                         close(pipefd[1]);
62                 }
63                 test();
64         }
65
66         if (pipefd[0] != 0) {
67                 dup2(pipefd[0], 0);
68                 close(pipefd[0]);
69         }
70         fgets(buf1, 80, stdin); printf("%s", buf1);
71         fgets(buf2, 80, stdin); printf("%s", buf2);
72         fgets(buf3, 80, stdin); printf("%s", buf3);
73
74         if (strcmp(buf1, msg1) != 0
75          || strcmp(buf2, msg2) != 0
76          || strcmp(buf3, msg3) != 0
77         ) {
78                 printf("ERROR! Expected order:\n%s%s%s", msg1, msg2, msg3);
79                 return 1;
80         }
81         printf("Good: wait seems to be correctly interrupted by signals\n");
82         return 0;
83 }