Gregg Wonderly <kermit%okstate.csnet@CSNET-RELAY.ARPA> (12/20/84)
[munch...munch...munch...] I am working with V7 UN*X. I need a way to scan the standard input stream for a character, but not wait. If I set to cbreak mode, the machine still waits for at least one character. Looking at stdio.h gave me no clues as it seems that the routine _filbuf() is called when no characters are available, and this is where the system hangs. I am looking for a more or less portable solution if possible. Also, I almost forgot. I need to put the character back on to stdin or only look at stdin and not take the character from the buffer. This appears more than trivial, so any help would be appreciated Thanks in advance... Gregg Wonderly Department of Computing and Information Sciences Oklahoma State University 1 ...!ihnp4!umn-cs!isucs1!\ /|\ UUCP: ...!ucbvax!mtxinu!ea! > okstate!kermit | | ...!convex!ctvax!uokvax!/ _____//|\\_____ |_|_|_||_||_|_|_| |_|_|_|||||_|_|_| ARPA: kermit%okstate.csnet@csnet-relay.arpa
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/20/84)
> I am working with V7 UN*X. I need a way to scan the standard input > stream for a character, but not wait. This is not supported by 7th Edition UNIX. You need to add something to your kernel to do this directly; the Rand Corp. empty() call has been distributed by USENIX a long time ago, and more recent approaches include VTIME,VMIN in AT&T UNIX Systems III & V and select() in 4.2BSD. A groady way to accomplish this on any UNIX is to use a second process that communicates with the controlling process via a pipe. > I need to put the character back on to stdin or > only look at stdin and not take the character from the buffer. ungetc() does this (only one character of pushback). If you need more pushback, see the buffered input routines in Software Tools.
Barry Gold <lcc.barry@UCLA-LOCUS.ARPA> (12/20/84)
May I suggest: A. ioctl(fildes,FIONREAD, &count) which will tell you whether there are any characters available from the file. B. If you're using stdio, look in the buffer--the format of the stdio FILE construct is published. C. Run in cbreak mode and make the character you want to spot (I assume it's one specific character you're interested in) into an interrupt character (INT or QUIT) which you can then catch. If you really want never to hang on that input stream, you'd better not use stdio. barry
geoff@desint.UUCP (Geoff Kuenning) (12/24/84)
>> I am working with V7 UN*X. I need a way to scan the standard input >> stream for a character, but not wait. > >This is not supported by 7th Edition UNIX. You need to add something >to your kernel to do this directly; the Rand Corp. empty() call has >been distributed by USENIX a long time ago, and more recent approaches >include VTIME,VMIN in AT&T UNIX Systems III & V and select() in 4.2BSD. Also the FIONREAD ioctl found in 4.1BSD and 4.2BSD. If you have access to BSD code, you may be able to copy that one, since it isn't complex code. I prefer the idea of doing it with an ioctl anyway. >A groady way to accomplish this on any UNIX is to use a second process >that communicates with the controlling process via a pipe. An even grodier way is to use a 1-second alarm to blast you off the read if there is nothing coming. This is obviously not much good unless it is the unusual case (e.g., a missed packet in a packet protocol). A final note. If part of your concern is packet protocol efficiency, some people have hacked V7 uucp to do the following: if the last read returned only 1 character, they sleep for some baud-rate-dependent time (calculated to be approximately one packet time) before they issue another read. This markedly improved CPU availability on some V7 systems without affecting uucp performance. -- Geoff Kuenning ...!ihnp4!trwrb!desint!geoff
david@ukma.UUCP (David Herron, NPR Lover) (12/27/84)
We had to do this a couple of years ago to get running a multi-user
version of empire and some other games. (We do important work
around here!!!!) We did the following:
The system call fstat(2) is used to get info about a file... It is
located in sys3.c in the kernel. Normally, the st_size field in
the stat structure is set to the size of the file. This is always
zero if the file is a tty. So, we put in a test to see if the
file was a tty, and if it was, we stored the sum of the char counts
of the character queues associated with that tty (simple huh).
If we had the code in front of us, we could be more specific, but
that's life in the big city. Hint: I think we checked the major
device number -- you'll see where this gets assigned into the
stat structure. I think the if(...) was a compound OR or AND so
there was more than one thing we needed to check...
(wws, whuxlg!wws, on vacation)
--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:-
David Herron; ARPA-> "ukma!david"@ANL-MCS
(Try the arpa address w/ and w/o the quotes, I have had much trouble with both.)
UUCP -:--:--:--:--:--:--:--:--:- (follow one of these routes)
{ucbvax,unmvax,boulder,research} ! {anlams,anl-mcs} -----\ vvvvvvvvvvv
>-!ukma!david
{cbosgd!hasmed,mcvax!qtlon,vax135,mddc} ! qusavx -----/ ^^^^^^^^^^^
jwg@galbp.UUCP (Joe Guthridge) (12/28/84)
>> I am working with V7 UN*X. I need a way to scan the standard input >> stream for a character, but not wait. > >This is not supported by 7th Edition UNIX. You need to add something >to your kernel to do this directly; the Rand Corp. empty() call has >been distributed by USENIX a long time ago, and more recent approaches >include VTIME,VMIN in AT&T UNIX Systems III & V and select() in 4.2BSD. > Xenix has a system call rdchk() to do this. -- Joe Guthridge ..!akgua!galbp!jwg NOTE NEW MACHINE NAME ^^^^^
phil@qfdts.OZ (Phil Chadwick) (01/11/85)
>> I am working with V7 UN*X. I need a way to scan the standard input >> stream for a character, but not wait. > >This is not supported by 7th Edition UNIX. You need to add something >to your kernel to do this directly; the Rand Corp. empty() call has >been distributed by USENIX a long time ago, and more recent approaches >include VTIME,VMIN in AT&T UNIX Systems III & V and select() in 4.2BSD. VTIME and VMIN index the control character array in the termio structure of USG systems. They appear to be potentially very usefull, but I have been unable to locate any printed documentation on how to manipulate c_cc[VTIME] and c_cc[VMIN] to achieve a non-blocking read. Can anyone enlighten me please? ---- Phil Chadwick Australia: (07) 2296500 Department of Forestry International: +61 7 2296500 PO Box 5 Brisbane, Roma Street SUN: phil:qfdts AUSTRALIA 4001 UUCP: {decvax,vax135}!mulga!phil:qfdts
guy@rlgvax.UUCP (Guy Harris) (01/15/85)
> VTIME and VMIN index the control character array in the termio structure > of USG systems. They appear to be potentially very usefull, but I have > been unable to locate any printed documentation on how to manipulate > c_cc[VTIME] and c_cc[VMIN] to achieve a non-blocking read. Can anyone > enlighten me please? The way to do non-blocking reads on terminals in USG systems is not to fiddle with VMIN and VTIME, but to set the O_NDELAY flag for the terminal's file descriptor using "fcntl". A way to do it is: if ((oldflags = fcntl(tty_fd, F_GETFL, 0)) < 0) fprintf(stderr, "Oops! [THIS SHOULD NOT HAPPEN]\n"); fcntl(tty_fd, F_SETFL, oldflags|O_NDELAY); ... fcntl(tty_fd, F_SETFL, oldflags); exit(0); Now, any reads on "tty_fd" will only return the number of characters immediately available, and not wait for any to become available. Note that if there are no characters available, the read will return 0, which is indistinguishable from end-of-file. Because of this, make sure you set the flags back to their old value before you exit; otherwise, the program that ran your program, probably a shell, will try to read something and, if you haven't typed anything, will get a return of 0, think it's an EOF, and dutifully exit. (4.2BSD handles this differently; you set no-delay mode on the terminal (i.e., *all* file descriptors referring to that terminal) with the FIONBIO "ioctl" (you can do it with "fcntl" as well, but unlike the USG "fcntl" it affects all file descriptors) and, if there is no data available, a read returns -1 with the error code EWOULDBLOCK. (In 4.2, this also affects writes; the write will only write as much data as will go without blocking.) The purpose of VMIN and VTIME is to act like the input silo on a DMF32. The read doesn't complete unless c_cc[VMIN] characters have come in, or c_cc[VTIME] 10ths of a second have elapsed *AND* at least one character has come in. (Completing the read if nothing came in is useless; the silos on the DH11 and DZ11 have no builtin timeouts, so they have to be polled under the control of the CPU clock even if they're empty, which sort of loses. Admittedly, in System V (but NOT System III) if c_cc[VMIN] is zero, the read completes after c_cc[VTIME] 10ths of a second even if no data is available. This sounds to me like rewriting to code to fit user's misconceptions of what the code was supposed to do...) Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
henry@utzoo.UUCP (Henry Spencer) (01/16/85)
> >> I am working with V7 UN*X. I need a way to scan the standard input > >> stream for a character, but not wait. > > > >This is not supported by 7th Edition UNIX. You need to add something > >to your kernel to do this directly; the Rand Corp. empty() call has > >been distributed by USENIX a long time ago, and more recent approaches > >include VTIME,VMIN in AT&T UNIX Systems III & V and select() in 4.2BSD. > > VTIME and VMIN index the control character array in the termio structure > of USG systems. They appear to be potentially very usefull, but I have > been unable to locate any printed documentation on how to manipulate > c_cc[VTIME] and c_cc[VMIN] to achieve a non-blocking read. Can anyone > enlighten me please? As I understand them, VTIME and VMIN cannot be used to do non-blocking reads, contrary to the second excerpt above. What they can be used to do is to make raw mode more efficient when you have some idea of what to expect in the way of input -- you can make raw mode deliver more than one character per system call, by having it wait for a specified time or a specified number of characters (whichever comes first). But if absolutely nothing is received, you still hang waiting for something. The VTIME setting is not a timeout when waiting for the first character, it is a timeout when waiting for *more* characters. Caveat: I'm not an expert on the SysV terminal driver. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry