54394gt@hocda.UUCP (G.TOMASEVICH) (02/06/84)
Recently I posted an article to 'net.unix-wizards' on nonblocking terminal reads. We have USG 4.2 UNIX, which has 'struct termio'; if you have an oldter system with 'struct sgtty' you cannot do it. One changes to raw mode by saving the contents of the struct for line 0, then changes some constants. Assume you have the following code: #include <termio.h> struct termio svt; /* for saving initial parameters */ struct termio stt; /* for changing line parameters */ ... ioctl(0,TCGETA,&svt); /* save old */ stt.c_iflag = stt.c_oflag = stt.c_lflag = 0; stt.c_cflag = (svt.c_cflag&CBAUD)|CS8|CREAD|CLOCAL; /* direct line */ stt.c_cc[VMIN] = 0; /* no chars needed for read() to return */ stt.c_cc[VTIME] = 0; /* timeout limit = 0 */ ioctl(0,TCSETA,&stt); To try to get a char, do the following: char key; if(read(0,&key,1) == 1) there is a char; else there is no char; If there is a character available, then the read() returns 1, so you can test the return value. I use it in conjuction with a DR11-W read/write program, which must poll the DR11-W status while waiting for characters to be typed. Of course, you hog the computer while running such a loop. If you want a blocking read, then set stt.c_cc[VMIN] = 1; I change back and forth, depending on whether anything besides keyboard input is happening at any particular instant. To avoid lousing up your line, catch all signals so you can do ioctl(0,TCSETA,&svt); and then an abort() if you want a core dump; before the process exits;
guy@rlgvax.UUCP (Guy Harris) (02/07/84)
> We have USG 4.2 UNIX, which has 'struct termio'; if you have > an oldter system with 'struct sgtty' you cannot do it. For the record, "System III" is USG 3.0.1 and "System V Release N" is USG 5.0 or later; USG 3.0 and later releases have it, although there is a bug in USG 3.0 and USG 3.0.1 (System III) that causes no-delay read not to work (it's trivial to fix). > One changes to raw mode by saving the contents of the struct for line 0, > then changes some constants. Assume you have the following code: . . . > stt.c_iflag = stt.c_oflag = stt.c_lflag = 0; > stt.c_cflag = (svt.c_cflag&CBAUD)|CS8|CREAD|CLOCAL; /* direct line */ > stt.c_cc[VMIN] = 0; /* no chars needed for read() to return */ > stt.c_cc[VTIME] = 0; /* timeout limit = 0 */ > ioctl(0,TCSETA,&stt); Two points: 1) Going into raw mode (meaning 8-bit data path with no special processing of input or output) may be overkill; one should only go into raw mode if one really wants to get 8-bit characters (i.e., the eighth bit is not a parity bit) and one wants to disable all "canonicalization" (erase, kill, eof), signals (interrupt, quit), XON/XOFF processing (think twice if you have a VT100), etc., etc.. If one is just reading single characters and responding to them directly (such as in a screen editor), merely turning the ICANON bit off in "c_lflag" will suffice. In the V7 terminal driver (and the enhanced V7 driver that comes with various Berkeley releases), turning on the CBREAK bit and possibly disabling characters like the interrupt and quit characters will suffice. 2) The trick of setting c_cc[VMIN] to 0 may not work on systems prior to USG 4.2 (I tried it on a System III system and it didn't work). I will note that the documentation of the UNIX terminal driver given in the System III and System V documentation is rather incomplete. There are several features in both drivers which are not documented, and it is not clear that all the documented features are completely or clearly documented, so be prepared for surprises if you try some things that "look" like they should work; the fact that setting c_cc[VMIN] has the effect of putting you in no-delay mode is not 100% obvious from the S3/S5 manual page. (Also, I would like to shoot the idiot at Bell who decided that the terminal driver manual pages belonged in the Administrator's Manual rather than the User's Manual. There is little correlation between administrator status and need to know the pecularities of a device interface; there is *no* correlation between administrator status and the desire or right to write a screen-oriented program, but in order to put the terminal into character-at-a-time mode you need the stuff that appears in TERMIO(7) in the *Administrator's* Manual.) Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy