guido@mcvax.uucp (Guido van Rossum) (11/19/86)
I have just figured out what's probably the best way of to read characters in 'RAW' mode, and a few other things. First, what is RAW mode? Suppose you are writing an editor, or other program which doesn't do read input lines but acts upon each character received. Then you usually want two things: no echoing of the input, and no special treatment of ^C and other special characters (^S, ^P and ^Z). For a while, I thought that DOS function 6 was the way to go. It will indeed read a character without echo and ^C interpretation. But there is no convenient way to find out if a character was actually read or not -- at least not from MSC 3.0 (nor from Lattice C 2.xx; don't know about higher levels). The "right" way to do it is the following: - put handle 0 in RAW mode using DOS function 0x44 (IOCTL), subfunctions 0 and 1. Specifically, do subfunction 0 (GET), clear DH, set bit 5 of DL, and do subfunction 1 (SET); all with BX set to 0, the handle to stdin. (I've found that this also sets stdout in RAW mode - it's almost Unix???!!!) Be sure to reset this mode when your program exits! - call setmode(0, O_BINARY) if you want to prevent the MSC library from converting CR to LF and treating ^Z as EOF. - to check whether a character is ready, call IOCTL with subfunction 6 (get input status) for handle 0. This will say the device is 'ready' when a character is available. - to read a character, use something like char c; if (read(0, &c, 1) == 1) return c; else /* Read error or EOF */ Now you will receive all control characters as data. Control-Break appears as ^C. Function keys and other special keys (arrows etc.) appear as Ascii NUL followed by a scan code; see the Basic manual or Technical Reference. You must also make sure that Control-Break checking (^C checking in MS-DOS terms) is off; this is easily done with DOS function 33. If this is not turned off, a type-ahead of ^C might interrupt any disk I/O or other system calls you are making. The MSC library function kbhit() still forces a ^C check; I believe some output functions will also do this, but output to stdout seems safe (because it is also put in RAW mode). Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>