70 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*	sleep() - Sleep for a number of seconds.	Author: Kees J. Bot
 | |
|  *								24 Apr 2000
 | |
|  * (Inspired by the Minix-vmd version of same, except that
 | |
|  * this implementation doesn't bother to check if all the signal
 | |
|  * functions succeed.  Under Minix that is no problem.)
 | |
|  */
 | |
| 
 | |
| #include <lib.h>
 | |
| #define sleep _sleep
 | |
| #include <signal.h>
 | |
| #include <unistd.h>
 | |
| #include <time.h>
 | |
| 
 | |
| static void handler(int sig)
 | |
| {
 | |
| 	/* Dummy signal handler. */
 | |
| }
 | |
| 
 | |
| unsigned sleep(unsigned sleep_seconds)
 | |
| {
 | |
| 	sigset_t ss_full, ss_orig, ss_alarm;
 | |
| 	struct sigaction action_alarm, action_orig;
 | |
| 	unsigned alarm_seconds, nap_seconds;
 | |
| 
 | |
| 	if (sleep_seconds == 0) return 0;	/* No rest for the wicked */
 | |
| 
 | |
| 	/* Mask all signals. */
 | |
| 	sigfillset(&ss_full);
 | |
| 	sigprocmask(SIG_BLOCK, &ss_full, &ss_orig);
 | |
| 
 | |
| 	/* Cancel currently running alarm. */
 | |
| 	alarm_seconds= alarm(0);
 | |
| 
 | |
| 	/* How long can we nap without interruptions? */
 | |
| 	nap_seconds= sleep_seconds;
 | |
| 	if (alarm_seconds != 0 && alarm_seconds < sleep_seconds) {
 | |
| 		nap_seconds= alarm_seconds;
 | |
| 	}
 | |
| 
 | |
| 	/* Now sleep. */
 | |
| 	action_alarm.sa_handler= handler;
 | |
| 	sigemptyset(&action_alarm.sa_mask);
 | |
| 	action_alarm.sa_flags= 0;
 | |
| 	sigaction(SIGALRM, &action_alarm, &action_orig);
 | |
| 	alarm(nap_seconds);
 | |
| 
 | |
| 	/* Wait for a wakeup call, either our alarm, or some other signal. */
 | |
| 	ss_alarm= ss_orig;
 | |
| 	sigdelset(&ss_alarm, SIGALRM);
 | |
| 	sigsuspend(&ss_alarm);
 | |
| 
 | |
| 	/* Cancel alarm, set mask and stuff back to normal. */
 | |
| 	nap_seconds -= alarm(0);
 | |
| 	sigaction(SIGALRM, &action_orig, NULL);
 | |
| 	sigprocmask(SIG_SETMASK, &ss_orig, NULL);
 | |
| 
 | |
| 	/* Restore alarm counter to the time remaining. */
 | |
| 	if (alarm_seconds != 0 && alarm_seconds >= nap_seconds) {
 | |
| 		alarm_seconds -= nap_seconds;
 | |
| 		if (alarm_seconds == 0) {
 | |
| 			raise(SIGALRM);		/* Alarm expires now! */
 | |
| 		} else {
 | |
| 			alarm(alarm_seconds);	/* Count time remaining. */
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* Return time not slept. */
 | |
| 	return sleep_seconds - nap_seconds;
 | |
| }
 | 
