Versione finale del client ECHO su TCP, con esempio di uso della funzione
[gapil.git] / sources / Sleep.c
1 /* Sleep.c
2  * 
3  * Copyright (C) 2002 Simone Piccardi
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /****************************************************************
20  *
21  * Program Sleep.c: 
22  * Example implementation for sleep
23  *
24  * Author: Simone Piccardi
25  * Apr. 2002
26  *
27  ****************************************************************/
28 /* 
29  * Include needed headers
30  */
31 #include <unistd.h>      /* unix standard library */
32 #include <signal.h>      /* POSIX signal library */
33
34 void alarm_hand(int);
35
36 unsigned int sleep(unsigned int seconds)
37 {
38 /* 
39  * Variables definition  
40  */
41     struct sigaction new_action, old_action;
42     sigset_t old_mask, stop_mask, sleep_mask;
43     /* set the signal handler */
44     sigemptyset(&new_action.sa_mask);              /* no signal blocked */
45     new_action.sa_handler = alarm_hand;            /* set handler */
46     new_action.sa_flags = 0;                       /* no flags */
47     sigaction(SIGALRM, &new_action, &old_action);  /* install action */
48     /* block SIGALRM to avoid race conditions */
49     sigemptyset(&stop_mask);                       /* init mask to empty */
50     sigaddset(&stop_mask, SIGALRM);                /* add SIGALRM */
51     sigprocmask(SIG_BLOCK, &stop_mask, &old_mask); /* add SIGALRM to blocked */
52     /* send the alarm */
53     alarm(seconds); 
54     /* going to sleep enabling SIGALRM */
55     sleep_mask = old_mask;                         /* take mask */
56     sigdelset(&sleep_mask, SIGALRM);               /* remove SIGALRM */
57     sigsuspend(&sleep_mask);                       /* go to sleep */
58     /* restore previous settings */
59     sigprocmask(SIG_SETMASK, &old_mask, NULL);     /* reset signal mask */    
60     sigaction(SIGALRM, &old_action, NULL);         /* reset signal action */
61     /* return remaining time */
62     return alarm(0);
63 }
64 /*
65  * Signal Handler for SIGALRM
66  */
67 void alarm_hand(int sig) {
68     /* just return to interrupt sigsuspend */
69     return;
70 }