#include #include #include /* for write*/ #include /* for exit */ #include /* for EINTR*/ static void sig_alrm(int); #define MAXLINE 200 void err_sys(char * msg) { printf("%s \n", msg); exit(-1); } int main(void) { int n; char line[MAXLINE]; extern int errno; struct sigaction act; /*if (signal(SIGALRM, sig_alrm) == SIG_ERR) err_sys("signal(SIGALRM) error");*/ /* this code is equivalent to the former; however, it allows us to change the default action when a blocking system call is called. The default is to restart it when a signal comes. Here we force it to be interrupted. */ act.sa_handler = sig_alrm; sigemptyset(&act.sa_mask); act.sa_flags=SA_INTERRUPT; /* use SA_RESTART to restart system call*/ sigaction(SIGALRM, &act, NULL); alarm(2); /* 1. There is a race condition here. Think of having this process blocked for more than "2" seconds (or the number we set). 2. If the system call (read) is restarted automatically (default action since 2001, the timeout does nothing! */ if ( (n = read(STDIN_FILENO, line, MAXLINE)) < 0) if (errno!=EINTR) err_sys("read error"); else write(STDOUT_FILENO, "Interrumpted\n", 13); alarm(0); write(STDOUT_FILENO, line, n); exit(0); } static void sig_alrm(int signo) { printf("Paso la alarma !!!\n"); return; /* nothing to do, just return to interrupt the read */ }