Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!mailrus!cornell!uw-beaver!fluke!ssc-vax!uvicctr!tholm From: tholm@uvicctr.UUCP (Terrence W. Holm) Newsgroups: comp.os.minix Subject: POSIX sleep(3) Message-ID: <527@uvicctr.UUCP> Date: 25 Oct 88 20:39:49 GMT Reply-To: tholm@uvicctr.UUCP (Terrence W. Holm) Organization: University of Victoria, Victoria B.C. Canada Lines: 99 EFTH MINIX report #51 - October 1988 - POSIX sleep(3) The MINIX 1.3 sleep(3) does not handle alarm(2) pending when sleep(3) is called. Nor does it return a correct value. The following corrects these problems. ---------------------------------------------------------- echo x - sleep.3 gres '^X' '' > sleep.3 << '/' XSUBROUTINES X sleep(3) - suspend execution for awhile X XINVOCATION X unsigned sleep( secs ) X unsigned secs; X XEXPLANATION X The process halts execution for seconds. It X will wake up early if any non-ignored signal occurs. X X If an alarm(2) was already set then sleep(3) uses X the minimum of the time remaining and as the X sleep time. If the alarm(2) signal expires first, then X its handler is called and sleep(3) returns. X X If an alarm(2) is still pending after sleep(3) completes, X then its time is adjusted by how long the process X really slept. X XRESULTS X Returns the number of seconds remaining until X should occur. This is non-zero when another signal woke X up sleep(3) early. X XREFERENCES X alarm(2), kill(2), pause(2), signal(2) / echo x - sleep.c gres '^X' '' > sleep.c << '/' X/* sleep(3) X * X * Sleep(n) pauses for 'n' seconds by scheduling an alarm interrupt. X * X * Changed to conform with POSIX Terrence W. Holm Oct. 1988 X */ X X#include X X Xstatic _alfun() /* Used with sleep() below */ X { X } X X Xunsigned sleep( secs ) X unsigned secs; X X { X unsigned current_secs; X unsigned remaining_secs; X void (*old_signal)(); X X if ( secs == 0 ) X return( 0 ); X X current_secs = alarm( 0 ); /* Is there currently an alarm? */ X X if ( current_secs == 0 || current_secs > secs ) X { X old_signal = signal( SIGALRM, _alfun ); X X alarm( secs ); X pause(); X remaining_secs = alarm( 0 ); X X signal( SIGALRM, old_signal ); X X if ( current_secs > secs ) X alarm( current_secs - ( secs - remaining_secs ) ); X X return( remaining_secs ); X } X X X /* current_secs <= secs, ie. alarm should occur before secs */ X X alarm( current_secs ); X pause(); X remaining_secs = alarm( 0 ); X X alarm( remaining_secs ); X X return( secs - ( current_secs - remaining_secs ) ); X } / ---------------------------------------------------------- Terrence W. Holm uw-beaver!uvicctr!tholm