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