[comp.lang.c] Interrupted read

daveh@marob.masa.com (Dave Hammond) (01/23/90)

I am having a problem with one of our programs interaction with
"idle-out" daemons, such as finger or "w".  The program polls the
keyboard as part of an event gathering loop.  The Unix SysV code does a
sequence of:

	signal(SIGALRM, handler);
	alarm(1);
	read(0, ...);
	alarm(0);
	signal(SIGALRM,SIG_IGN);

to effect the poll.  This works well, except that it cause the idle-out
program to think a read has occured.  It seems that an interrupted
read() causes the stat structure a_time and m_time elements to be
updated, even though no input occured.  The following small program
demonstrates this:

/* begin demonstration program */
/*
 * This program reads from fd 0 until an EOF is seen.  If no input occurs
 * within 2 seconds, the read() is interrupted and the loop cycles.
 * The printout shows the stat structure changes with each interrupted read().
 */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>

static int aflag = 0;

main()
{
	char c[1];
	int atrap();
	struct stat sb;

	for (;;aflag=0) {
		signal(SIGALRM, atrap);
		alarm(2);
		if (read(0, c, 1) == 0)
			break;
		alarm(0);
		signal(SIGALRM, SIG_IGN);
		if (fstat(0, &sb) != -1)
			printf("%s read: atime=%ld, mtime=%ld\n",
				(aflag ? "interrupted" : "completed"),
				sb.st_atime, sb.st_mtime);
		}
	exit(0);
}

atrap()
{
	aflag++;
}
/* end demonstration program */

My question is -- given a (pre-streams) Unix SysV environment, is there
a method of polling the keyboard which will *not* produce a change to
the stat structure?  I have tried toggling the fcntl() O_NDELAY bit, but
this seems to put a greater strain on the cpu.  And, running with
O_NDELAY set for the duration of the program can really bite you, if an
unforseen death occurs.

Any solutions or suggestions will be greatly appreciated.

--
Dave Hammond
daveh@marob.masa.com
uunet!masa.com!marob!daveh