[net.wanted] Need Non-Blocking Terminal Input Function For Berkeley 4.2

cramer@kontron.UUCP (Clayton Cramer) (01/22/86)

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.

Please don't suggest using alarm within the same process to interrupt
a read -- to quote SIGNAL(3C):

	If a caught signal occurs during certain system calls, causing
        the call to terminate prematurely, the call is automatically
        restarted.  In particular, this can occur during a _read_ or
        _write_(2) on a slow device (such as a terminal; but not a
        file) and during a _wait_(2).
        
In short, the one time it would be most useful!

mo@wgivax.UUCP (01/24/86)

If you are willing to write a simple input manager, you could use getch()
with alarm() and longjmp/setjmp() to manage your problem.

For instance:

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>

jmp_buf xyz;

main()
{
    int trapalarm();
    char string[80];

    do {
        fprintf(stderr,"Please enter string: ");
        signal(SIGALRM, trapalarm);
        alarm(5);

        if(setjmp(xyz) == 0)
        {
            get_input(string);
            fprintf(stderr,"%s",string);
        }
        else
        {
            fprintf(stderr,"no input\n");
            continue;
        }

    } while(strcmp(string,"end"));
}

get_input(str)
char *str;
{
    register char *c;

    c = str;

    do {
        *c = getchar();
        alarm(0);
    } while(*c++ != '\n');

    *c = 0;
}


trapalarm()
{
    alarm(0);
    longjmp(xyz,1);
}

===============================================================================

              Mike O'Shea   (decvax!mcnc!unccvax!wgivax!mo)

mouse@mcgill-vision.UUCP (der Mouse) (01/28/86)

I missed the original, but what's wrong with using the non-blocking mode
already provided by the kernel?

int on = 1;
ioctl(fd,FIONBIO,&on);

then if you read() and there are no data available, the read will return
with  either  EOF or  error  (return value  <=  0)  and  errno  will  be
EWOULDBLOCK.
-- 
					der Mouse

USA: {ihnp4,decvax,akgua,etc}!utcsri!mcgill-vision!mouse
     philabs!micomvax!musocs!mcgill-vision!mouse
Europe: mcvax!decvax!utcsri!mcgill-vision!mouse
        mcvax!seismo!cmcl2!philabs!micomvax!musocs!mcgill-vision!mouse

Hacker: One who accidentally destroys /
Wizard: One who recovers it afterward