/*---------------------------------------------------------------------- | This program writes to a pipe whose read-end has been closed | (to cause a SIGPIPE error). The program then catches the | signal. | | Inside the signal handler, the user is encouraged to try typing | "Ctrl-C". Doing so while the signal handler is executing has | no immediate effect... although it will terminate the program once | the signal handler is exited. This is because the sigaction() | is set to block the SIGINT (Ctrl-C) while the SIGPIPE handler | executes. | | Note that the program finishes in an infinite loop if the | user does not press "Ctrl-C". | | | The intentions of this "play" program are: | | 1. verify Stevens comments (p.430) about a SIGPIPE signal | being generated when writing to a closed pipe | | 2. revisit setvbuf() | | 3. give an example use of sigaction() | and verify that it can indeed block other signals | while the signal handler is executing | | | Author: Justin Gamble ----------------------------------------------------------------------*/ #include #include /* for sigaction() */ #include void myHandler(int signo); main() { struct sigaction mySignalStruct; int fd[2]; /* * change the default stdout buffering: don't use any buffering */ if (setvbuf(stdout, NULL, _IONBF, NULL) != 0) { fprintf(stderr, "setvbuf error\n"); exit(1); } /* * setup signal handler: block SIGINT while handler executes */ mySignalStruct.sa_handler = myHandler; mySignalStruct.sa_flags = 0; /* no options being used */ sigemptyset( &mySignalStruct.sa_mask); sigaddset ( &mySignalStruct.sa_mask, SIGINT); if (sigaction(SIGPIPE, &mySignalStruct, NULL) < 0) { fprintf(stderr, "sigaction error\n"); exit(1); } /* * set up pipe */ if (pipe(fd) < 0) { fprintf(stderr, "pipe error\n"); exit(1); } /* * generate SIGPIPE */ switch ( fork() ) { case -1: /* error */ fprintf(stderr, "fork error\n"); exit(1); case 0 : /* child */ close(fd[1]); close(fd[0]); /* closing read end of pipe */ exit(0); default: /* parent */ close(fd[0]); write(fd[1], "hello world\n", 12); } /* * infinite loop */ printf("Entering infinite loop..\n"); while (1); } void myHandler(int signo) { int i; printf("Caught SIGPIPE.\n"); printf(" This signal handler will execute for 15 seconds\n"); printf(" See what happens if you press Ctrl-C (SIGINT) during\n"); printf(" this time...\n"); for (i = 15; i >= 0; i--) { printf("%d\n", i); sleep(1); } }