Home | History | Annotate | Download | only in test
      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 }
     85