[comp.std.c] ReadKey like Function in C

bph@buengc.BU.EDU (Blair P. Houghton) (08/12/89)

In article <21175@cup.portal.com> Tim_CDC_Roberts@cup.portal.com writes:
>Definitively, once again:
>
>    THERE IS NO STANDARD, O.S.-TRANSPARENT METHOD OF READING A SINGLE
>    KEYSTROKE WITHOUT A CR.  Never has been, never will be.

Never?

How about if someone begs with the ANSI committee to have its
implementation as a standard function required for compliance?

No?

Has it been tried?

				--Blair
				  "I mean, compiler code itself
				   is nonportable, right?"

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/12/89)

In article <3705@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>How about if someone begs with the ANSI committee to have its
>implementation as a standard function required for compliance?

Not only is it too late, but I think it was proposed and justly was
awarded a "VE" stock response code, meaning:  The Standard must
accommodate a variety of environments.

IEEE Std 1003.1 does specify such facilities for POSIX environments.

bph@buengc.BU.EDU (Blair P. Houghton) (08/12/89)

In article <10712@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>In article <3705@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>>How about if someone begs with the ANSI committee to have its
>>implementation as a standard function required for compliance?
>
>Not only is it too late, but I think it was proposed and justly was
>awarded a "VE" stock response code, meaning:  The Standard must
>accommodate a variety of environments.

I don't get it.

All it's gotta say is something to the effect that there should
be a function, call it "readkey()", that returns the value of
the next char from stdin as soon after it's typed as it's needed.
You could even qualify it to apply only when tty input can be
used as stdin.

The Compiler writers are in a much better position to implement
it than are a bunch of fractious C programmers arguing over
whether to use fstat() or ioctl() and the length of timeout()...

Makes me wonder why they haven't, ANSI or no.

				--Blair
				  "ANSI or no."

scs@adam.pika.mit.edu (Steve Summit) (08/13/89)

In article <3705@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>How about if someone begs with the ANSI committee to have its
>implementation as a standard function required for compliance?

In article <10712@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>Not only is it too late, but I think it was proposed and justly was
>awarded a "VE" stock response code, meaning:  The Standard must
>accommodate a variety of environments.

Doug is correct, but the astonishing frequency with which this
question arises (I think it's been asked on comp.lang.c three
times in the past week alone) indicates that the opportunity is
ripe for some kind of informal, community-"standard" solution.
(Or did someone try this already?)

One difficulty is whether the interface should be a "getkey"
routine or a set of mode-setting functions.  A straightforward
getkey implementation on Unix would suffer at least three system
call overheads per character read.  Mode setting, though hewing
to the Unix ioctl tradition, might be distasteful to MS-DOS
aficionadoes who appreciate the utility of getch() (and, on a
related note, kbhit()).  (The presence of these two simple, oft-
needed routines might be said to be one thing which DOS does
right, although it's achieved with the introduction of a bizarre
dichotomy between "Console I/O" and stdio.)

A useful approach (combining the worst of both approaches) would
accommodate mode setting _and_ a separate getkey routine:

	setkeymode(CHARATATIME);
	/* repeated calls to */ getkey();
	setkeymode(CANONICAL);

On Unix, setkeymode would play the usual games with ioctls
(V7, SYSV, or POSIX flavors), and getkey would map to getchar.
On MS-DOS, setkeymode would be a no-op and getkey would map to
getch.  On VMS, either approach could be used (there's a per-read
QIO function modifier to disable canonical processing, as well as
mode-setting QIO's.)  On other systems the scheme might be
unimplementable, but that's what I mean by an informal, community
"standard," as opposed to a mandatory part of the pANS.

If there's interest, I could post versions for the three systems
mentioned above (I'd only be able to test the V7/BSD Unix
variants), but first we have to have a long debate about what the
routines should be called...

                                            Steve Summit
                                            scs@adam.pika.mit.edu

P.S. It occurs to me that, whenever this question is asked,
     someone points out that the curses package provides a semi-
     standard means of doing character-at-a-time input, which
     could be used independently of curses' screen management
     features.  I suppose the sequence would be crmode();
     getch(); nocrmode();.  ("getch" -- what a coincidence.)

guy@auspex.auspex.com (Guy Harris) (08/13/89)

>The Compiler writers are in a much better position to implement
>it than are a bunch of fractious C programmers arguing over
>whether to use fstat() or ioctl() and the length of timeout()...

A compiler writer stuck with an operating system that supports only,
say, block-mode terminals that transmit nothing to the host until an
ENTER key is pressed, and that cannot be made to do otherwise, is in
*no* position to implement said function.

The standards committee really isn't in a good position to tell vendors of
such systems to take a flying leap, either.  The POSIX committee is in a
better position to do so, since the scope of the POSIX standard is
larger than that of the C standard.

A question to those who want thus-and-such a feature in C, rather than
in, say, POSIX: what criterion do you use to distinguish between "stuff
the C standard should require" and "stuff the C standard should leave to
things like POSIX?"  If you say the second set should be empty, what do
you propose to do about people who want to write C applications that
*don't* need the particular features in question and want or need to
have them work on systems that make it difficult or impossible to
implement said features?

(Or, to put it another way: do you think there is a role both for the
ANSI C standard and for POSIX, and if not, why not?  I, and probably a
lot of the people on the committee, *do* think there are roles for both;
the C standard is for a language that can be implemented on a wide range
of machines under a wide range of operating systems, providing some
basic I/O capabilities but *not* providing the ability to do somewhat
device-specific things like run in "character-at-a-time mode", while the
POSIX standard is for an interface, currently in C (but other bindings
are under development) to operating system services on what is probably
a smaller range of machines and operating systems, possibly excluding
e.g. some of the older mainframe OSes.)

In fact, another question for those who want thus-and-such a feature in
C: why are we all better off with it there, than in POSIX?  The ability
to do character-at-a-time I/O *and* non-blocking versions of same on
terminals is *already* in POSIX; many non-UNIX operating systems vendors
are planning to implement POSIX atop their OSes.  It might not be
possible to do so atop, say, MS-DOS, but in that case it might be better
to consider either a *de jure* or *de facto* standard "subset" of POSIX
that may include some of the "termio" functions but not include "fork"
than to burden the C standard with functions that might be difficult or
impossible to implement on, say, the older mainframe OSes mentioned above.

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/13/89)

In article <3727@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
-In article <10712@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
->The Standard must accommodate a variety of environments.
-I don't get it.
-All it's gotta say is something to the effect that there should
-be a function, call it "readkey()", that returns the value of
-the next char from stdin as soon after it's typed as it's needed.
-You could even qualify it to apply only when tty input can be
-used as stdin.

We already have such a function in the Standard; it's called "getchar()".
It returns a single character from stdin as soon as it's available.
Whether or not there is input-line canonicalization going on is a matter
that depends on the operating environment.  Some systems always canonicalize,
some never do, and some can be made to switch from one mode to the other,
sometimes with side-effects like losing all unconsumed input and sometimes
not.  Some implementations cannot readily distinguish between "terminals"
and other I/O sources/sinks. This is the "variety of environments" alluded
to.  Any fully portable standard for this wide a range of behavior would
probably be so weak as to not meet the requirements of those who keep
asking for such a facility.  In fact there are are means of obtaining
uncanonicalized terminal input on most systems, and as I pointed out before
IEEE Std 1003.1 standardizes one such method for a wide class of systems
(POSIX-compliant ones).  I don't know (or much care) whether MS/DOS has
any such standard, but certainly one could be developed by those who care.

henry@utzoo.uucp (Henry Spencer) (08/13/89)

In article <3705@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>>Definitively, once again:
>>
>>    THERE IS NO STANDARD, O.S.-TRANSPARENT METHOD OF READING A SINGLE
>>    KEYSTROKE WITHOUT A CR.  Never has been, never will be.
>
>Never?
>
>How about if someone begs with the ANSI committee to have its
>implementation as a standard function required for compliance?

The response of a vendor who is asked to make major changes to his antique
operating system for the sake of compliance with ANSI C will be laughter.
Language standards, by and large, simply do not have that kind of clout.
ANSI committees know this.  They are in the business of recognizing, tidying,
and codifying existing practice, not trying to legislate morality.  So they
will respond the same way.

>Has it been tried?

Constantly.  People who have never participated in the standards process
have *no concept* of how many times the same old dumb ideas come up and
have to be dealt with.  I saw only a bit of the X3J11 paperwork -- I wasn't
on the committee -- but from what I did see, I can assure you that nearly
every conceivable idea was proposed at least once and usually several
times.
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

henry@utzoo.uucp (Henry Spencer) (08/13/89)

In article <3727@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>>awarded a "VE" stock response code, meaning:  The Standard must
>>accommodate a variety of environments.
>
>I don't get it.
>
>All it's gotta say is something to the effect that there should
>be a function, call it "readkey()", that returns the value of
>the next char from stdin as soon after it's typed as it's needed.

And how does that magically translate into standards compliance from
compiler vendors?

The result of such a requirement will be that the people who have trouble
implementing it will ignore it.  Thus defeating one major purpose of
standardization, which is to give the users a guarantee of what they
can portably expect.

>The Compiler writers are in a much better position to implement
>it than are a bunch of fractious C programmers arguing over
>whether to use fstat() or ioctl() and the length of timeout()...

If you think these are the sorts of issues that come up in implementing
such a requirement, you have overlooked the fact that Unix is not the
whole world, and these days the majority of C implementations are not
for Unix.  It's much worse in the real world.
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

henry@utzoo.uucp (Henry Spencer) (08/13/89)

In article <13446@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes:
>Doug is correct, but the astonishing frequency with which this
>question arises (I think it's been asked on comp.lang.c three
>times in the past week alone) indicates that the opportunity is
>ripe for some kind of informal, community-"standard" solution.

I strongly suggest that you read IEEE standard 1003.1, i.e. POSIX, before
re-inventing the wheel pointlessly.  POSIX compliance will be widespread
in the very near future, so the POSIX approach will automatically be
*far* more widespread than any "community 'standard'" approach.
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/13/89)

In article <2357@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>... the scope of the POSIX standard is larger than that of the C standard.

Or smaller, depending on what you mean by scope.

>It might not be possible to [implement POSIX] atop, say, MS-DOS, but in
>that case it might be better to consider either a *de jure* or *de facto*
>standard "subset" of POSIX ...

That's essentially what nearly everybody (other than Whitesmiths) did in
the days before there were standards for the contents of the C library.
Implementors provided read(), etc. that mimicked UNIX as closely as they
reasonably could.  This approach worked pretty well..

scs@adam.pika.mit.edu (Steve Summit) (08/13/89)

In article <13446@bloom-beacon.MIT.EDU> I wrote:
>...the astonishing frequency with which this
>question arises indicates that the opportunity is
>ripe for some kind of informal, community-"standard" solution.

In article <1989Aug13.004829.28322@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>I strongly suggest that you read IEEE standard 1003.1, i.e. POSIX, before
>re-inventing the wheel pointlessly.  POSIX compliance will be widespread
>in the very near future, so the POSIX approach will automatically be
>*far* more widespread than any "community 'standard'" approach.

I agree (in fact I have a copy of 1003.1 right here on my desk)
and I'll start using its facilities as soon as they become
available on machines I use, but in the meantime, and for non-Unix
systems such as VMS and MS-DOS, I'd like to have a carrot to toss
to the people who keep asking for getch() and kbhit(), in a
similar spirit to the getopt() routines which have been floating
around for years.

You're right, the time for a "community 'standard'" approach is
not exactly ripe, but more like waning.

                                            Steve Summit
                                            scs@adam.pika.mit.edu

" Maynard) (08/13/89)

In article <3727@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>All it's gotta say is something to the effect that there should
>be a function, call it "readkey()", that returns the value of
>the next char from stdin as soon after it's typed as it's needed.
>You could even qualify it to apply only when tty input can be
>used as stdin.

Let's look at an environment where this is not possible: IBM 370-class
mainframe, with stdin (and /dev/tty??) pointed at a 3270 terminal.
Characters are not sent to the host until ENTER (or a PF key) is
pressed. There's no way to give a character to a program as soon as it's
typed because the CPU doesn't know that it has. Your readkey() cannot be
implemented in this environment, yet it is a valid one for ANSI C.

(Flames about how 3270s are horribly broken sent to /dev/null; there are
millions of them out there, doing real work every day.)

(Anyone at Amdahl wanna comment on UTS's 3270 handling?)

-- 
Jay Maynard, EMT-P, K5ZC, PP-ASEL   | Never ascribe to malice that which can
jay@splut.conmicro.com       (eieio)| adequately be explained by stupidity.
{attctc,bellcore}!texbell!splut!jay +----------------------------------------
"Rabid rerouters *love* to route mail to devnull@hell.org" - Brandon Allbery

peter@ficc.uu.net (Peter da Silva) (08/14/89)

In article <2357@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) writes:
> possible to do so atop, say, MS-DOS, but in that case it might be better
> to consider either a *de jure* or *de facto* standard "subset" of POSIX
> that may include some of the "termio" functions but not include "fork"
> than to burden the C standard with functions that might be difficult or
> impossible to implement on, say, the older mainframe OSes mentioned above.

Hmmm. Does POSIX specify that fork() is the process-creation mechanism? I
hope not... while the fork()-exec() pair is singularly elegant, it's not
implementable (without a massive number of kludges) in a wide variety of
operating systems: OS/9, VMS, RSX, AmigaOS, and in fact any O/S I can think
of off the top of my head other than UNIX.

While I'm here, what's the sentiment among C standards folks for some sort
of standard co-routine arrangement? It would not require any changes to
the language, just a few library routines: cocreate(), cocall(), codelete().
It should work on any machine without a strict stack segment (and C on such
a beast is going to have problems anyway).
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now
Personal: peter@sugar.hackercorp.com.   `-_-' |  writing is the sentence
Quote: Have you hugged your wolf today?  'U`  |  you are now reading"

chris@mimsy.UUCP (Chris Torek) (08/15/89)

In article <3727@buengc.BU.EDU> bph@buengc.BU.EDU (Blair P. Houghton) writes:
>The Compiler writers are in a much better position to implement
>it than are a bunch of fractious C programmers arguing over
>whether to use fstat() or ioctl() and the length of timeout()...

For one thing, this statement is partly false: compiler writers are not
in a position to choose the most appropriate way from {wait up to
.3 seconds for a key, send a signal on key, <any other method>},
and so cannot provide the version most suited to any particular
application.  (Many games, for instance, want `wait for key with
timeout'; many want `wait forever for key'; many want `do not wait for
key'; but still others want something else entirely.)

>Makes me wonder why they haven't, ANSI or no.

Imagine you are the president of IBM or Unisys.  You have $100 billion
worth of customers running systems that treat people like virtual card
punches.  1% of them want ANSI C.  If ANSI C includes a mandatory
ReadKey (whatever it does---all we know for certain at this point is
that it is not compatible with card readers), you will have to commit
many $ to upgrading these systems; if it does not, all you need do
is commit a few $ to writing an ANSI-conformant compiler and runtime
system for these systems.  In return for either effort, you will get
about $1 billion worth of business.

Which do you prefer: to spend about $999+ milllion in return for your
$1 billion (upgrade all those systems, losing the customers who will
not upgrade), or to spend about $1 million in return for your $1 billion
(writing, testing, and supporting compilers for all those systems)?

				-----

Now imagine you are the user on the receiving end of one of these
virtual-card-punch systems.  If ANSI puts a ReadKey function (whatever
it does; all we know is that your system cannot do it) into the
standard, IBM will not bother attempting to earn a few bucks by
upgrading your system and then providing an ANSI C, but if ANSI does
not put a ReadKey function into the standard, IBM will provide a C
compiler.  Which do you prefer: to have no C compiler at all, or
to have one without a standard ReadKey?

				-----

This is, of course, an oversimplification of the issue; but the point
is that this standard is intended to be used in places where ReadKey
cannot be done; therefore this standard cannot say that ReadKey must
be done.  You might prefer a standard that is not so accomodating:
you never touch these systems, for you want a nicer environment than
they could ever provide.  Such standards can and do exist, either
unrelated to, or `sitting above', the language standard.  The POSIX
1003.1 standard, for instance, tells you how to write a nearly
infinite variety of different ReadKey-like functions in C.  All of
them will work on all POSIX 1003.1-conformant systems.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/15/89)

In article <5672@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>Hmmm. Does POSIX specify that fork() is the process-creation mechanism? I
>hope not... while the fork()-exec() pair is singularly elegant, it's not
>implementable (without a massive number of kludges) in a wide variety of
>operating systems: OS/9, VMS, RSX, AmigaOS, and in fact any O/S I can think
>of off the top of my head other than UNIX.

Yes, IEEE Std 1003.1 requires that fork() be supported.  Early in the P1003
deliberations, it was decided not to bend over backwards simply to permit
layered implementations; the base model was UNIX.

Separate fork() and exec(), along with shared file tables etc., provide
the means to do a variety of interesting things, and UNIX-based applications
do exploit this.  If POSIX had tried to weaken this area, it would not have
been following its charter.

>While I'm here, what's the sentiment among C standards folks for some sort
>of standard co-routine arrangement?

It cannot be mandated across all implementations.  To me, that rules out
using it in my applications.  And indeed, just last week I devised an
interesting algorithm that needs to switch between two tree traversal
pointers; coroutines would have been handy, but as it stands I simply had
to devise another way to accomplish the desired algorithm within standard C.
Note that this can always be done, although it's not as convenient as having
genuine coroutine support built into the language.

peter@ficc.uu.net (Peter da Silva) (08/15/89)

I redirected this back to comp.std.c, because I'm really not interested
in the POSIX standard here. The main reason POSIX comes up in this group
is because of holes in the ANSI C standard. Many of them are reasonably
brushed aside as outside the scope of the standard, but then the POSIX
standard is referred to as something that will cover them... and as this
message (I hope) shows, that just ain't so...

I expressed dismay that POSIX mandated fork():

In article <10734@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
> Separate fork() and exec(), along with shared file tables etc., provide
> the means to do a variety of interesting things, and UNIX-based applications
> do exploit this.  If POSIX had tried to weaken this area, it would not have
> been following its charter.

But this rules out POSIX support for a wide variety of operating systems.
Fork() is just plain inefficient unless you have virtual memory support,
so few small-system or real-time operating systems use it or even support
it.  At least an alternate that allowed the use of a more conventional
process creation mechanism would be desirable.

> >While I'm here, what's the sentiment among C standards folks for some sort
> >of standard co-routine arrangement?

> It cannot be mandated across all implementations.

Well, the flip response to this is: "Maybe, but then neither can fork().",
and I'm reasonably sure you'll use that in your code.

There really are very few systems that wouldn't be able to support the
coroutines being discussed in comp.lang.c. Many vendors would just need
to fake a jmp_buf and use setjmp/longjmp. I didn't see coroutines as
one of the things rejected in the list of proposed enhancements that was
just posted here. Were they even discussed?

It seems to me that there is a need for something between X3J11 and POSIX.
Something to provide a standard platform for systems that can't provide
full-blown UNIX, but does cover areas too broad for the C standard, such
as process creation or terminal control.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now
Personal: peter@sugar.hackercorp.com.   `-_-' |  writing is the sentence
Quote: Have you hugged your wolf today?  'U`  |  you are now reading"

leea@ssc-vax.UUCP (Lee Carver) (08/15/89)

In this zoo of discussion on "getch", i'd like to add a shot in
support of "kbhit()".  In particular, I'd like kbhit to return
ture if input is waiting (i.e. getchar will NOT block) and
false otherwise.

This has the advantage of working with file streams, as well as
with "keyboards".  Also, the sematics cover such block-oriented
devices as 3270.

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/16/89)

In article <5692@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>Fork() is just plain inefficient unless you have virtual memory support,
>so few small-system or real-time operating systems use it or even support it.

Funny how we didn't think it was a big problem on PDP-11 UNIX.  The
"small systems" you mention today have more inherent power than those
PDP-11s; the problem seems to be that convenient means of exploiting
the power are not being provided.

Real-time has nothing to do with it.

>> >While I'm here, what's the sentiment among C standards folks for some sort
>> >of standard co-routine arrangement?
>> It cannot be mandated across all implementations.
>Well, the flip response to this is: "Maybe, but then neither can fork().",
>and I'm reasonably sure you'll use that in your code.

Only if the application is deliberately constrained to POSIX implementations.
I don't use fork() gratuitously.

>It seems to me that there is a need for something between X3J11 and POSIX.

Feel free.

flaps@dgp.toronto.edu (Alan J Rosenthal) (08/16/89)

leea@ssc-vax.UUCP (Lee Carver) writes:
>In this zoo of discussion on "getch", i'd like to add a shot in
>support of "kbhit()".  In particular, I'd like kbhit to return
>ture if input is waiting (i.e. getchar will NOT block) and
>false otherwise.

That's obviously standardizable (after all, however you wrote the standard
description it would probably still conform if it always returned false, or
maybe even always true), but it differs from the ibm-pc semantics.  On ibm-pcs,
kbhit() tells you whether or not _getch()_ will block%, not getchar(), and
getch()'s semantics are that it does not block if the user has pressed any
character, whether or not they have pressed return.

On an ibm-pc, if kbhit() returns true, getchar() may still block.

ajr

% Of course, nothing really blocks on the ibm-pc, it just waits.

peter@ficc.uu.net (Peter da Silva) (08/16/89)

In article <2851@ssc-vax.UUCP>, leea@ssc-vax.UUCP (Lee Carver) writes:
> In this zoo of discussion on "getch", i'd like to add a shot in
> support of "kbhit()".  In particular, I'd like kbhit to return
> ture if input is waiting (i.e. getchar will NOT block) and
> false otherwise.

Well, I'd personally prefer a function that would return the number of
characters available to read. That would have more meaningful semantics
for files, and also allow more efficient I/O under UNIX.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now
Personal: peter@sugar.hackercorp.com.   `-_-' |  writing is the sentence
Quote: Have you hugged your wolf today?  'U`  |  you are now reading"

peter@ficc.uu.net (Peter da Silva) (08/16/89)

In article <10750@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
> In article <5692@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
> >Fork() is just plain inefficient unless you have virtual memory support,
> >so few small-system or real-time operating systems use it or even support it.

> Funny how we didn't think it was a big problem on PDP-11 UNIX.

That was before I ran into RSX-11. It's amazing how much more cojones a
PDP-11 has with the right software. Too bad RSX-11 is such a poor
programming environment (albeit better than \most/ real-time systems).
I kind of miss QIO$.

> The "small systems" you mention today have more inherent power than those
> PDP-11s;

Those small systems *are* often PDP-11s, in this industry.

> >It seems to me that there is a need for something between X3J11 and POSIX.

> Feel free.

I'm working on it. Anyone have any ideas? The Software Tools VOS seems
like a good starting point. I found it real handy on those same PDP-11s
running RSX.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now
Personal: peter@sugar.hackercorp.com.   `-_-' |  writing is the sentence
Quote: Have you hugged your wolf today?  'U`  |  you are now reading"

henry@utzoo.uucp (Henry Spencer) (08/16/89)

In article <5692@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>> >of standard co-routine arrangement?
>
>> It cannot be mandated across all implementations.
>
>Well, the flip response to this is: "Maybe, but then neither can fork().",

Which is why fork() is not in ANSI C.
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gmt@arizona.edu (Gregg Townsend) (08/17/89)

The proposed ANSI standard provides

    setvbuf (file, NULL, _IONBF, 0)

for setting non-buffered mode on a file.  This would be the "standard"
approach to reading keys as they are hit, and this is the spec
implementors should follow when providing such a facility.

**HOWEVER**, support for control of buffering is implementation-defined,
and in fact I don't know of any system on which this works now.

    Gregg Townsend / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
    +1 602 621 4325      gmt@Arizona.EDU       110 57 16 W / 32 13 45 N / +758m

kdb@chinet.chi.il.us (Karl Botts) (08/22/89)

>**HOWEVER**, support for control of buffering is implementation-defined,
>and in fact I don't know of any system on which this works now.

There is another problem with mapping the MSDOS kbhit()-getch() functions
into the world of terminals which has not been discussed in this
discussion.  On the PC, all keys produce a single "scancode" (yes, I know
that sometimes it is one byte and sometimes it is two with the first being
zero, but it is always a single unambiguous code.)  This means that the
keyboard driver always knows whether a key has been hit or not.
	On most systems which support terminals, notably Unix, all the extra
keys besides the ascii keys produce escape sequences, which always start
with ascii ESC (0x1b).  The "Escape" key produces just a single ESC.  This
means that, whenever a keyboard driver sees an ESC it can't know whether
the ESC is from the Escape key or is the first char of an escape sequence.
If the input were coming from somewhere besides the keyboard, the driver
could do a lookahead to see if the next byte is part of a legal escape
sequence, and act accordingly.  But you can't lookahead at a keyboard
stream -- if the user has hit the Escape and refuses to hit another until
the keyboard driver reacts, the keyboard driver and the user are
deadlocked.
	There is no theoretical way out of this dilemma -- it is well known that
if one string in an accepting set is an initial substring of another, there
is no way to disambiguate without lookahead, except to make a rule that the
initial string is always recognized, which means that the longer string
never is.  This is why all the chars used for escape sequences in Unix
tools (mainly "\", but also, say "$" in "make", as well as others) must be
represented by themselves included twice.  The Escape key should issue
_two_ ESC bytes -- but it doesn't.
	The only way to deal with this is to wait for awhile -- typically 1/3 or
1/2 second -- when an ESC is seen, and return the ESC if no other byte comes
along.  But this is inevitably machine dependent, doesn't work worth a damn
over various kinds of wires, and so forth.  Because of the ambiguity a
kbhit() routine under Unix that tried to return a representation of an
entire keystroke would have to have this stuff built into it.  But making a
kbhit() routine that only returns keyboard bytes doesn't accomplish
anything -- it leaves the programmer still with the same problem.
	I have no solution for this.
could never map

peter@ficc.uu.net (Peter da Silva) (08/23/89)

In article <9322@chinet.chi.il.us>, kdb@chinet.chi.il.us (Karl Botts) writes:
> into the world of terminals which has not been discussed in this
> discussion.  [details of the problems of function keys on ASCII terminals]

> But making a
> kbhit() routine that only returns keyboard bytes doesn't accomplish
> anything -- it leaves the programmer still with the same problem.

Well, that's a good explanation of a problem with routines like kbhit(),
but for many applications the problem can be ignored. For example, a
readch() or testch() routine may not be dealing with a keyboard at all.
Or the application may just want to get a yes/no response.

Also, even if you solve the problem of function keys you have the problem
of portable screen output. Fortunately this is a solved problem in UNIX
with Ken Arnold's "curses" library. Implementations of curses for MS-DOS
exist, as well. Coincidentally, this solution also provides ReadKey(),
and handles function keys with a timeout (as you described).

Curses makes a good addition to the semi-standard C toolbox.

Unfortunately, this is overkill for many applications, and completely
inappropriate for others, such as a file transfer program. Something
lower level is still desirable.
-- 
Peter da Silva, *NIX support guy @ Ferranti International Controls Corporation.
Biz: peter@ficc.uu.net, +1 713 274 5180. Fun: peter@sugar.hackercorp.com. `-_-'
"The security biz is subtle, you have to pick your trade-offs carefully."   U
	-- Barry Shein