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