blob: 3fb344977345b3ad25d435a7772979ffbcab95b4 [file] [log] [blame]
Elliott Hughes5dec78d2014-02-26 15:56:23 -08001#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
17static const char msg1[] = "Child signals parent\n";
18static const char msg2[] = "Parent got signal\n";
19static const char msg3[] = "Child will exit now\n";
20
21static void handler(int s)
22{
23 write(1, msg2, sizeof(msg2)-1);
24}
25
26static 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
48int 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}