--- /dev/null
+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 */
+}