Need Non-Blocking Terminal Input Function For Berkeley 4.2

John Ioannidis ji at garfield.columbia.edu
Sun Jan 26 14:49:59 AEST 1986


In article <482 at kontron.UUCP>, cramer at kontron.UUCP (Clayton Cramer) writes:
> Does anyone know of a way to do read from a terminal under Berkeley 4.2 UNIX
> so that after a specified number of seconds control is returned to the
> program if there is no response?  Right now I'm forking off of the main
> program, and having the child process do the read, with the parent setting
> an alarm to interrupt the child after a certain number of seconds.  This
> works, but it's devilishly difficult to debug using dbx.  Alternate 
> techniques would be appreciated.
> 
The idea is to use select(2) to do the waiting for you. The following program
should be obvious. See the documentation for select(2) for more details.

#include <stdio.h>
#include <sgtty.h>
#define EVER	;;
main()
{
	int rfds, sret, c;

	struct timeval {
		long tv_sec;
		long tv_usec;
	} tout;

	struct sgttyb b;

	/*
	 * Prepare tout structure, as required by select(2)
	 */

	printf( "Enter time to wait, in seconds: " );
	scanf( "%d", &tout.tv_sec );
	tout.tv_usec = 0;

	/*
	 * Some cosmetics...
	 */

	ioctl( 0, TIOCGETP, &b );
	b.sg_flags |= CBREAK;		/* Turn on CBreak mode */
	b.sg_flags &= ~ ECHO;		/* Turn off echoing */
	ioctl( 0, TIOCSETP, &b );

	setbuf( stdout, NULL ); /* Used to avoid fflush(stdout) later */

	for(EVER)
	{
		printf( "Press any key to continue..." );
		rfds = 1 << 0; 	/* really 1 but shown for clarity */

		if( ( sret=select( 20, &rfds, 0, 0, &tout ) ) > 0 )
		{
			/* something was pressed */

			c=getchar();
			printf( "\tYou pressed %c\r\n\n", c );
		}

		else if( sret==0 )
			printf( "\t*TIMEOUT WARNING*\r\n\n" );

		else
			perror( "\r\nselect" );
	}
}

The code should be obvious :-)

If you specify 0 seconds, select will timeout immediately. To 'block'
if no input is available, specify (char *)0 instead of &tout in the
select call. 

This is more elegant than using setjmp/sigalrm and far more elegant
than spawning another process just to read!

I hope this settles the question,

#include <appropriate_disclaimers>

VOICE: 	+1 212 280 5510			ARPA: ioannidis at cs.columbia.EDU
USnail:	John Ioannidis			      ji at garfield.columbia.EDU
	450 Computer Science
	Columbia University,		USENET: ...{seismo|topaz}!
	New York, NY 10027			   columbia!garfield!ji

			... It's all Greek to me!



More information about the Comp.unix mailing list