15dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes#include <unistd.h> 25dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes#include <sys/types.h> 35dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes#include <signal.h> 45dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes#include <sys/wait.h> 55dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes#include <stdio.h> 65dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes#include <string.h> 75dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 85dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes/* Expected order is: 95dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * Child signals parent 105dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * Parent got signal 115dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * Child will exit now 125dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * 135dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * The bug we test for: under strace -f, last two lines are swapped 145dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * because wait syscall is suspended by strace and thus can't be interrupted. 155dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes */ 165dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 175dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughesstatic const char msg1[] = "Child signals parent\n"; 185dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughesstatic const char msg2[] = "Parent got signal\n"; 195dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughesstatic const char msg3[] = "Child will exit now\n"; 205dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 215dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughesstatic void handler(int s) 225dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes{ 235dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes write(1, msg2, sizeof(msg2)-1); 245dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes} 255dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 265dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughesstatic void test() 275dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes{ 285dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes /* Note: in Linux, signal() installs handler with SA_RESTART flag, 295dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes * therefore wait will be restarted. 305dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes */ 315dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes signal(SIGALRM, handler); 325dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 335dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes if (fork() == 0) { 345dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes /* child */ 355dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes sleep(1); 365dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes write(1, msg1, sizeof(msg1)-1); 375dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes kill(getppid(), SIGALRM); 385dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes sleep(1); 395dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes write(1, msg3, sizeof(msg3)-1); 405dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes _exit(0); 415dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes } 425dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 435dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes /* parent */ 445dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes wait(NULL); 455dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes _exit(0); 465dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes} 475dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 485dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughesint main() 495dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes{ 505dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes char buf1[80]; 515dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes char buf2[80]; 525dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes char buf3[80]; 535dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes int pipefd[2]; 545dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 555dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes printf("Please run me under 'strace -f'\n"); 565dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 575dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes pipe(pipefd); 585dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 595dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes if (fork() == 0) { 605dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes if (pipefd[1] != 1) { 615dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes dup2(pipefd[1], 1); 625dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes close(pipefd[1]); 635dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes } 645dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes test(); 655dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes } 665dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 675dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes if (pipefd[0] != 0) { 685dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes dup2(pipefd[0], 0); 695dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes close(pipefd[0]); 705dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes } 715dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes fgets(buf1, 80, stdin); printf("%s", buf1); 725dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes fgets(buf2, 80, stdin); printf("%s", buf2); 735dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes fgets(buf3, 80, stdin); printf("%s", buf3); 745dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes 755dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes if (strcmp(buf1, msg1) != 0 765dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes || strcmp(buf2, msg2) != 0 775dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes || strcmp(buf3, msg3) != 0 785dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes ) { 795dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes printf("ERROR! Expected order:\n%s%s%s", msg1, msg2, msg3); 805dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes return 1; 815dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes } 825dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes printf("Good: wait seems to be correctly interrupted by signals\n"); 835dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes return 0; 845dec78d0c2663930cd1bbcecbbcee47f68bc52f3Elliott Hughes} 85