Problem with sleep and signal/alarm.
Tom Armistead
toma at swsrv1.cirr.com
Tue May 7 15:52:22 AEST 1991
In article <1991May6.153937.28635 at msuinfo.cl.msu.edu> winnard at frith.msu.edu writes:
>I'm having trouble getting the sleep function to work
>under C when I use signal/alarm function. When the
>signal/alarm call is taken out of the following code, the
>program will print "Sleep 10..." then it will wait 10 seconds
>before printing how long it did not sleep every time through the
>loop. But with the signal/alarm function in place the sleep will
>return immediately and still indicate that it slept 10 seconds
>every time through the loop.
>
>#include <stdio.h>
>#include <signal.h>
>#include <errno.h>
>
>main()
>{
> int x;
>
> signal( SIGALRM, SIG_IGN );
> alarm( 1 );
>
> while( 1 )
> {
> printf("Sleep 10...");
> x = sleep( (unsigned)10 );
> if( x == -1 ) perror("");
> else printf("unslept %d\n", x );
> }
>}
>
>If you don't know why this is happening maybe you know a way
>to timeout a read function. Either solution would be of great help.
>Thanks.
>Jamie Winnard
>winnard at frith.egr.msu.edu
sleep and alarm/signal processing are supposed to work in harmony, but I've
never been able to make that happend when the alarm/signal time was less than
the sleep time??? I would also be interested in why?
You can timeout a read() call by using alarm()/signal(). There is no need
for using sleep() (but I don't know your application, so how can I say that?).
You can also use ioctl() to setup your terminal to timeout between individual
characters (look at the ioctl(2) and termio(7) man pages - for (on Sys V)
~ICANON processing using VMIN and VTIME options).
I am assuming that you are reading from the keyboard?
Here is a brief example of how to use alarm() to interrupt a read from the
terminal. Notice that the signal catching routine calls signal() to reinstall
itself (just in case you didn't know ;-) the SIGALRM signal (and most others)
is reset to SIG_DFL when caught).
========= ... ========================
#include <stdio.h>
#include <signal.h>
#include <errno.h>
void catch() /* SIGALRM signal catching routine */
{
signal( SIGALRM, catch ); /* Need to re-install SIGALRM catcher */
alarm( 2 ); /* Reset to fire alarm in 2 more seconds */
return;
}/*end catch*/
main()
{
int timeout=0;
char buf[BUFSIZ];
signal( SIGALRM, catch ); /* Set signal catching routine */
buf[0] = '\0'; /* Empty data entry buffer */
printf( "Enter something: " );
alarm( 2 ); /* Interrupt the gets in 2 seconds */
/************************************************************************
** gets() will return NULL if interrupted (by the SIGALRM). You need to
** check for the EINTR errno (interrupted system call) also, because
** gets will also return NULL on end-of-file if no data has been entered.
*************************************************************************/
while( gets( buf ) == NULL && /* If no data from gets */
errno == EINTR ) /* Because of an interrupt (alarm) */
if( ++timeout > 5 ) /* Wait 5 timeouts before giving up */
break;
if( timeout > 5 )
puts( "\nWhy didn't you enter anything?" );
}/*end main*/
========= ... ========================
Tom
--
Tom Armistead - Software Services - 2918 Dukeswood Dr. - Garland, Tx 75040
===========================================================================
toma at swsrv1.cirr.com {egsner,letni,ozdaltx,void}!swsrv1!toma
More information about the Comp.unix.questions
mailing list