_sleep.c

Go to the documentation of this file.
00001 /*      sleep() - Sleep for a number of seconds.        Author: Kees J. Bot
00002  *                                                              24 Apr 2000
00003  * (Inspired by the Minix-vmd version of same, except that
00004  * this implementation doesn't bother to check if all the signal
00005  * functions succeed.  Under Minix that is no problem.)
00006  */
00007 
00008 #include <lib.h>
00009 #define sleep _sleep
00010 #include <signal.h>
00011 #include <unistd.h>
00012 #include <time.h>
00013 
00014 static void handler(int sig)
00015 {
00016         /* Dummy signal handler. */
00017 }
00018 
00019 unsigned sleep(unsigned sleep_seconds)
00020 {
00021         sigset_t ss_full, ss_orig, ss_alarm;
00022         struct sigaction action_alarm, action_orig;
00023         unsigned alarm_seconds, nap_seconds;
00024 
00025         if (sleep_seconds == 0) return 0;       /* No rest for the wicked */
00026 
00027         /* Mask all signals. */
00028         sigfillset(&ss_full);
00029         sigprocmask(SIG_BLOCK, &ss_full, &ss_orig);
00030 
00031         /* Cancel currently running alarm. */
00032         alarm_seconds= alarm(0);
00033 
00034         /* How long can we nap without interruptions? */
00035         nap_seconds= sleep_seconds;
00036         if (alarm_seconds != 0 && alarm_seconds < sleep_seconds) {
00037                 nap_seconds= alarm_seconds;
00038         }
00039 
00040         /* Now sleep. */
00041         action_alarm.sa_handler= handler;
00042         sigemptyset(&action_alarm.sa_mask);
00043         action_alarm.sa_flags= 0;
00044         sigaction(SIGALRM, &action_alarm, &action_orig);
00045         alarm(nap_seconds);
00046 
00047         /* Wait for a wakeup call, either our alarm, or some other signal. */
00048         ss_alarm= ss_orig;
00049         sigdelset(&ss_alarm, SIGALRM);
00050         sigsuspend(&ss_alarm);
00051 
00052         /* Cancel alarm, set mask and stuff back to normal. */
00053         nap_seconds -= alarm(0);
00054         sigaction(SIGALRM, &action_orig, NULL);
00055         sigprocmask(SIG_SETMASK, &ss_orig, NULL);
00056 
00057         /* Restore alarm counter to the time remaining. */
00058         if (alarm_seconds != 0 && alarm_seconds >= nap_seconds) {
00059                 alarm_seconds -= nap_seconds;
00060                 if (alarm_seconds == 0) {
00061                         raise(SIGALRM);         /* Alarm expires now! */
00062                 } else {
00063                         alarm(alarm_seconds);   /* Count time remaining. */
00064                 }
00065         }
00066 
00067         /* Return time not slept. */
00068         return sleep_seconds - nap_seconds;
00069 }

Generated on Fri Apr 14 22:57:27 2006 for minix by  doxygen 1.4.6