Timed reading in C (?)

Bevis Ip ip at ecf.toronto.edu
Sat Feb 13 08:09:27 AEST 1988


>What I want my program to do is wait a short while (like, say, 5 seconds
>or so) for an user to type in something. If the user doesn't type in
>anything after that time period, the program goes ahead and does something
>else. But if the user has already started to type, the program waits and
>lets him finish typing.
>
>What I'd like to know is how to do this in C. (By the way, I'm on BSD
>Unix 4.3.) I want the user's terminal to stay in the canonical mode,
>if possible.

Took me a while to crank the following program up, seems like it's doing
what you've asked. There're probably better ways in doing this, and I'm
open for criticism. The code is pretty straight forward (I hope), so
comments are minimal.

bevis

====================
/*
 *  Written by:	 Bevis Ip		UofT	 88/02/12
 *
 *  Known problem:
 *	There's no input editing.
 *	This works on BSD4.[23] systems only, not sure about other systems.
 */
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <sgtty.h>
#include <setjmp.h>

jmp_buf context;

main()
{
	struct sgttyb tty, ntty;
	struct sigvec sv1, sv2;
	int doinput(), dosomething();

	fcntl(0, F_SETFL, FASYNC);

	ioctl(fileno(stdin), TIOCGETP, &tty);
	ntty = tty;
	ntty.sg_flags |= CBREAK;

	sv1.sv_handler = doinput;
	sv2.sv_handler = dosomething;
	sv1.sv_mask = sv2.sv_mask = 0;
	sv1.sv_flags = sv2.sv_flags = 0;	/* sv_onstack for BSD4.2 */

    	setjmp(context);
	sigvec(SIGIO, &sv1, (struct sigvec *) 0);
	sigvec(SIGALRM, &sv2, (struct sigvec *) 0);
	alarm(5);	/* timeout for reading input */
	puts("Waiting for input: ");
	ioctl(fileno(stdin), TIOCSETN, &ntty);
	getchar();	/* wait for signal, never get executed */
	_exit(1);
}

dosomething()
{
	sigblock(sigmask(SIGIO));
	printf("\nI'm getting impatience! ");
	printf("Please type in something...\n\n");
	fflush(stdin);
	longjmp(context, 1);
}

doinput()
{
	char s[BUFSIZ];
	register char *cp = s;
	struct sigvec sv;

	alarm(0);
	sigblock(sigmask(SIGIO));

	/*	Have to read input char by char!!
	 */
	while (read(fileno(stdin), cp, 1) != EOF && *cp != '\n')
		cp++;
	*cp = '\0';
	puts(s);

	sv.sv_handler = SIG_IGN;
	sv.sv_mask = 0;
	sv.sv_flags = 0;
	sigvec(SIGIO, &sv, (struct sigvec *) 0);
	longjmp(context, 1);
}
-- 
Bevis Ip	Department of Mechanical Engineering, University of Toronto
UUCP  :	{linus,ihnp4,allegra,decvax,floyd}!utcsri!me!ip
ARPA  :	ip%me.toronto.edu at csnet-relay.arpa
BitNet:	ip at me.UTORONTO			CSNet :	ip at me.toronto.edu



More information about the Comp.unix.questions mailing list