3 * Copyright (C) 2002 Simone Piccardi
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.
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.
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.
19 /****************************************************************
22 * Example implementation for sleep
24 * Author: Simone Piccardi
27 ****************************************************************/
29 * Include needed headers
31 #include <unistd.h> /* unix standard library */
32 #include <signal.h> /* signal constants, types and functions */
36 unsigned int sleep(unsigned int seconds)
39 * Variables definition
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 */
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 */
65 * Signal Handler for SIGALRM
67 void alarm_hand(int sig) {
68 /* just return to interrupt sigsuspend */