taylorr@glycine.cs.unc.edu (Russell Taylor) (06/14/90)
I want to do non-blocking keyboard I/O in a program. Basically, the routine will read a character from the keyboard if there is one and return NULL if there is not. This is done in a tight loop with reads and writes to other devices. How to I get a character from the keyboard if there is one and a NULL if there is not? Thanks, Russell Taylor taylorr@cs.unc.edu
archer@elysium.esd.sgi.com (Archer Sully) (06/14/90)
In article <14670@thorin.cs.unc.edu> taylorr@glycine.cs.unc.edu (Russell Taylor) writes: > I want to do non-blocking keyboard I/O in a program. Basically, the >routine will read a character from the keyboard if there is one and return >NULL if there is not. This is done in a tight loop with reads and writes >to other devices. How to I get a character from the keyboard if there is >one and a NULL if there is not? Check out 'Advanced UNIX(tm) Programming' by Marc Rochkind. It contains more answers to this (and all of the other questions that you will inevitably have) than I would care to post. -- Archer Sully | Ask not what you can do for you country, (archer@esd.sgi.com) | But what your country's been doing to you. | -- The Avengers
mike@BRL.MIL (Mike Muuss) (06/14/90)
The best way to do it is to use the select() system call. Here is a portable subroutine that will show you how to do it. Best, -Mike ------- /* * B S D S E L E C T * * Ordinarily, a stub for select() could have been implemented here, * but the IRIS defines a graphics library routine select(). * On non-BSD systems, select() is a name likely to have been reused, * so this special interface has been created. This also has the slight * advantage of centralizing the struct timeval stuff. */ #if defined(BSD) # include <sys/types.h> /* for fd_set macros */ #endif #if defined(BSD) || defined(CRAY) # include <sys/time.h> /* for struct timeval. Includes <time.h> */ #else # include <time.h> #endif #if defined(sgi) # if !defined(mips) || defined(SGI4D_Rel2) /* 3D systems, and Rel2 4D systems. */ # include <bsd/sys/types.h> # include <bsd/sys/time.h> # else /* Rel3 4D systems got it right */ # include <sys/types.h> # include <sys/time.h> # endif #endif #ifdef stellar # include <sys/timeval.h> #endif #ifdef FD_SET /* The 4.3 BSD version */ bsdselect( readfds, sec, us ) long readfds; { fd_set fdset; int width; struct timeval tv; int ret; tv.tv_sec = sec; tv.tv_usec = us; if( (width = getdtablesize()) <= 0 ) width = 32; FD_ZERO( &fdset ); fdset.fds_bits[0] = readfds; /* peek inside! */ if( (ret = select( width, &fdset, (fd_set *)0, (fd_set *)0, &tv )) <= 0 ) { if( ret < 0 ) perror("bsdselect/select"); return(0); /* no bits ready */ } readfds = fdset.fds_bits[0]; return( readfds ); } #else /* The old version */ bsdselect( readfds, sec, us ) long readfds; { #if defined(BSD) || defined(sgi) || defined(stellar) || defined(CRAY) struct timeval tv; int ret; long mask; tv.tv_sec = sec; tv.tv_usec = us; mask = readfds; if( (ret = select( 32, &mask, 0L, 0L, &tv )) <= 0 ) { if( ret < 0 ) perror("bsdselect/select"); return(0); /* No bits ready */ } return( mask ); #else return(32-1); /* SYSV always has lots of input */ #endif } #endif /* FD_SET */
msc@ramoth.esd.sgi.com (Mark Callow) (06/15/90)
In article <9006140143.aa19050@WOLF.BRL.MIL>, mike@BRL.MIL (Mike Muuss) writes: |> The best way to do it is to use the select() system call. |> |> Here is a portable subroutine that will show you how to do it. |> Best, |> -Mike |> |> ------- |> /* |> * B S D S E L E C T |> * |> * Ordinarily, a stub for select() could have been implemented here, |> * but the IRIS defines a graphics library routine select(). |> * On non-BSD systems, select() is a name likely to have been reused, The GL routine "select" was renamed gselect in release 3.0 more than 2 years ago. -- From the TARDIS of Mark Callow msc@ramoth.sgi.com, ...{ames,decwrl}!sgi!msc "There is much virtue in a window. It is to a human being as a frame is to a painting, as a proscenium to a play. It strongly defines its content."
root@sgzh.uucp (Bruno Pape) (06/15/90)
In article <14670@thorin.cs.unc.edu> taylorr@glycine.cs.unc.edu (Russell Taylor) writes: > > I want to do non-blocking keyboard I/O in a program. Basically, the >routine will read a character from the keyboard if there is one and return >NULL if there is not. This is done in a tight loop with reads and writes >to other devices. How to I get a character from the keyboard if there is >one and a NULL if there is not? > > Thanks, > Russell Taylor > taylorr@cs.unc.edu This will do what you want. It is short and simple, but maybe not so portable. I know there are others that prefer select over ioctl, and we know who each other are, but you can choose the method best suited to your own needs. Have Fun, Bruno ----------------------- begin program -------------------------------------- #include <sys/termio.h> main() { struct termio kbd, kbd_save; char buff; if ( ioctl( 0, TCGETA, &kbd_save ) < 0 ) perror( "ioctl" ); if ( ioctl( 0, TCGETA, &kbd ) < 0 ) perror( "ioctl" ); kbd.c_lflag = kbd.c_cc[VTIME] = kbd.c_cc[VMIN] = 0; if ( ioctl( 0, TCSETA, &kbd ) < 0 ) perror( "ioctl" ); while ( read ( 0, &buff, 1 ) == 0 ) printf( "looping\n" ); printf("received %c\n", buff ); if ( ioctl( 0, TCSETA, &kbd_save ) < 0 ) perror( "ioctl" ); } ------------------------ end program ---------------------------------------