Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!convex!egsner!swsrv1!toma From: toma@swsrv1.cirr.com (Tom Armistead) Newsgroups: comp.unix.questions Subject: Re: Problem with sleep and signal/alarm. Message-ID: <1991May7.055222.19151@swsrv1.cirr.com> Date: 7 May 91 05:52:22 GMT References: <1991May6.153937.28635@msuinfo.cl.msu.edu> Organization: Software Services: Garland, Tx Lines: 100 In article <1991May6.153937.28635@msuinfo.cl.msu.edu> winnard@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 >#include >#include > >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@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 #include #include 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@swsrv1.cirr.com {egsner,letni,ozdaltx,void}!swsrv1!toma