X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=listati%2Fsleep.c;fp=listati%2Fsleep.c;h=2d79551a3953465b86d22835f9e0709b21e12358;hb=bdf6e88eeb9b3aef06d57930ec8b89083639e56d;hp=0000000000000000000000000000000000000000;hpb=cf60963212306540ce7485ed7c86405e143a3352;p=gapil.git diff --git a/listati/sleep.c b/listati/sleep.c new file mode 100644 index 0000000..2d79551 --- /dev/null +++ b/listati/sleep.c @@ -0,0 +1,30 @@ +void alarm_hand(int); +unsigned int sleep(unsigned int seconds) +{ + struct sigaction new_action, old_action; + sigset_t old_mask, stop_mask, sleep_mask; + /* set the signal handler */ + sigemptyset(&new_action.sa_mask); /* no signal blocked */ + new_action.sa_handler = alarm_hand; /* set handler */ + new_action.sa_flags = 0; /* no flags */ + sigaction(SIGALRM, &new_action, &old_action); /* install action */ + /* block SIGALRM to avoid race conditions */ + sigemptyset(&stop_mask); /* init mask to empty */ + sigaddset(&stop_mask, SIGALRM); /* add SIGALRM */ + sigprocmask(SIG_BLOCK, &stop_mask, &old_mask); /* add SIGALRM to blocked */ + /* send the alarm */ + alarm(seconds); + /* going to sleep enabling SIGALRM */ + sleep_mask = old_mask; /* take mask */ + sigdelset(&sleep_mask, SIGALRM); /* remove SIGALRM */ + sigsuspend(&sleep_mask); /* go to sleep */ + /* restore previous settings */ + sigprocmask(SIG_SETMASK, &old_mask, NULL); /* reset signal mask */ + sigaction(SIGALRM, &old_action, NULL); /* reset signal action */ + /* return remaining time */ + return alarm(0); +} +void alarm_hand(int sig) +{ + return; /* just return to interrupt sigsuspend */ +}