Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!decvax!tektronix!uw-beaver!tikal!sigma!uw-nsr!uw-warp!tom
From: tom@uw-warp.UUCP (Tom May)
Newsgroups: comp.lang.c,comp.sys.ibm.pc
Subject: Re: Unbuffered I/O using MicroSoft C 3.0
Message-ID: <645@uw-warp.UUCP>
Date: Mon, 12-Jan-87 03:15:08 EST
Article-I.D.: uw-warp.645
Posted: Mon Jan 12 03:15:08 1987
Date-Received: Mon, 12-Jan-87 21:51:28 EST
References: <1867@sunybcs.UUCP>
Organization: The Warp, Seattle, WA
Lines: 59
Summary: How to do it
Xref: mnetor comp.lang.c:659 comp.sys.ibm.pc:918

In article <1867@sunybcs.UUCP>, ugwayne@sunybcs (Wayne Nelligan) writes:
>     I am using MicroSoft C 3.0 and I have tried various methods but each time
> the printer only prints out when I enter a Carriage Return.  At first, I was
> using getc() and putc() and then it dawned on me that these functions
> use buffered I/O.  So I looked in the MicroSoft manuals and found the 
> function setbuf.  I tried this on the stream stdprn and then ran the program
> again.  It still didn't work.

What's going on is that your terminal input is line-buffered so you can use
backspace, function keys, etc.  A setbuf on stdin won't turn off this
buffering, since it is done by MS-DOS before the C library gets hold of
your characters.  You have to invoke MS-DOS directly, as demonstrated below.

>     Next, I used the functions read() and write() which the manual states as
> low-level I/O that do not buffer or format data.

That may be true, but the very-low-level I/O routines, i.e., MS-DOS, may still
buffer stuff.  And in fact they do, at least as far as terminal input is
concerned.

> Then, I thought that it might be that the printer was getting
> the characters one at a time (so the pogram was working) and it may need a
> Carriage Return before it does any printing (it had its own buffering).

Your printer could indeed do this type of buffering, especially if it is
bi-directional (wouldn't make a good typewriter in the first place anyway
if so).  If it does, you're out of luck.

>     With this in mind then I decided to just try my program with the standard
> input and output devices.  So when I hit a key, I would not only see my 
> keystroke but also another one which my program was then sending.  This too, 
> did not work, a Carriage Return was still needed. 

Interesting.  What should happen is you will see MS-DOS echo characters as you
type them, then when you hit return (after any line-editing) they will all
be handed to your program which would echo them again.  Weird.

So, here is the promised routine which invokes MS-DOS to get a
character from the keyboard (not stdin) without echoing it.  It also
does some things which are obvious from looking at the code.

#include 
int
grokchar() {
    union REGS regs;

    regs.h.ah = 7;      /* get char no echo */
    intdos (®s, ®s);
    return (regs.h.al == 26 ? EOF : regs.h.al == '\r' ? '\n' : regs.h.al);
}

The MS-DOS interrupts are documented in the MS-DOS Technical Reference
Manual, so if you want one that echos you can look it up there.  I think there
is also one to pass a character to the printer.

Stuff like this is why I think MS-DOS stands for Massively Suckful DOS.
Personally, I'd use either a real typewriter or an editor for this job.
-- 
Tom May.	uw-beaver!uw-nsr!uw-warp!tom
(So, do I pass the Turing test?)