daveh@marob.MASA.COM (Dave Hammond) (08/20/88)
Newsgroups: comp.lang.c Subject: Re: Re: Echoing chars and input functions References: <8808160751.aa03016@SMOKE.BRL.MIL> <5940003@hpcupt1.HP.COM> Reply-To: daveh@marob.masa.com (Dave Hammond) In article <5940003@hpcupt1.HP.COM> williamo@hpcupt1.HP.COM (William O'Saughnessy) writes: > >OK, what is the proper and portable way to get a character from stdin >without having it echoed to the screen?!!!! I wonder what makes this such a misunderstood and flammable topic. Is it such a problem to consider things such as echo, line editing and other terminal management tasks be the domain of the operating system, (and as such, machine-dependent) ? Isn't ioctl(), stty(), or fcntl() [or similar device management routine] in the same manual as getchar() [no flames about different volumes, please :-)] ? >Basic may have C beat here it defines the way with INKEY but there >appears to be no machine independent way of doing it in C! I haven't got much Basic experience, but suspect that if the Basic INKEY function is one which solicits raw (non echoed, key-at-a-time) keyboard input, there is one which will solicite cooked (echoed, editable, line-at-a-time) input as well.
swilson%thetone@Sun.COM (Scott Wilson) (08/20/88)
In article <371@marob.MASA.COM> daveh@marob.masa.com (Dave Hammond) writes: >Isn't ioctl(), stty(), or fcntl() [or similar device management routine] in >the same manual as getchar() [no flames about different volumes, please :-)] ? Again, the system with which I have the problem is THINK's LightspeedC on a Macintosh. No there isn't ioctl(), stty(), fcntl(), terminals, terminal emulation windows, or terminal drivers. Making a window look like a terminal is a function of the C libraries. And, again, the problem is that standards like ANSI appear to leave echoing alone because it is an OS issue. My question is how do we get getchars that behave similarly on different systems when for some implementations it falls under the responsibility of the C libraries because the OS doesn't have terminal support. -- Scott Wilson arpa: swilson@sun.com Sun Microsystems uucp: ...!sun!swilson Mt. View, CA
mcdonald@uxe.cso.uiuc.edu (08/20/88)
>>OK, what is the proper and portable way to get a character from stdin >>without having it echoed to the screen?!!!! >I wonder what makes this such a misunderstood and flammable topic. I know the answer to that one! >Is it such a problem to consider things such as echo, line editing >and other terminal management tasks be the domain of the operating system, >(and as such, machine-dependent) ? It is indeed a problem, but that's the way it is. Too bad all operating systems can't do it right (i.e. like MS-DOS :-) ) >Isn't ioctl(), stty(), or fcntl() [or similar device management routine] in >the same manual as getchar() [no flames about different volumes, please :-)] ? No, in fact a careful look at my C manuals finds no reference to them at all. I have absolutely no idea how to use them, or their exact use. I can guess something from the names - that is all.
egisin@watmath.waterloo.edu (Eric Gisin) (08/20/88)
In article <65071@sun.uucp>, swilson%thetone@Sun.COM (Scott Wilson) writes: > Again, the system with which I have the problem is THINK's LightspeedC on > a Macintosh. No there isn't ioctl(), stty(), fcntl(), terminals, > terminal emulation windows, or terminal drivers. Making a window look > like a terminal is a function of the C libraries. And, again, the problem is > that standards like ANSI appear to leave echoing alone because it is an > OS issue. My question is how do we get getchars that behave similarly > on different systems when for some implementations it falls under the > responsibility of the C libraries because the OS doesn't have terminal > support. > If the OS doesn't have terminal support, the C library should support it, and it should be the *default* for un-redirected stdout/stdin. If the programmer wants unechoed keyboard input, they can call non-portable OS functions. If LightspeedC doesn't work that way, complain to THINK, or get better compiler.
alanf%smile@Sun.COM (Alan Fargusson) (08/23/88)
I have always thought that this was an omission in the stdio I/O library. If turning echo on and off was defined as part of fread, fwrite, printf, ... then there would be no problem. As it is now you kind of take your chances with various version of UNIX, and non UNIX systems are hopeless (as far as portability that is). It is to late to get this into the ANSI-C standard I guess. - - - - - - - - - - - - - - - - - - - - - Alan Fargusson Sun Microsystems alanf@sun.com ..!sun!alanf
ok@quintus.uucp (Richard A. O'Keefe) (08/23/88)
In article <65197@sun.uucp> alanf%smile@Sun.COM (Alan Fargusson) writes: >I have always thought that this was an omission in the stdio I/O library. >If turning echo on and off was defined as part of fread, fwrite, printf, ... >then there would be no problem. As it is now you kind of take your chances >with various version of UNIX, and non UNIX systems are hopeless (as far as >portability that is). (1) Don't forget, the C standard has to make sense on IBM mainframes, which do not use a character-at-a-time interface to their terminals. (2) The dpANS makes it clear that fgets() and getchar() are supposed to do the same things (in general), so if one of them echoes and the other doesn't, that's broken. (3) The story with respect to UNIX and MS-DOS is nowhere near as bad as has been made out: yes the terminal ioctl() calls differ between BSD and Sys V, but if you want to control features like echoing you should probably be using Curses, and while there are differences, they aren't _that_ great. There are implementations of Curses for MS-DOS, and even VMS tries to support that interface. I loathe Curses myself, but it _is_ a de facto standard, and is being used successfully by a lot of applications programmers. It seems to me that the appropriate thing to do is to propose that Curses be part of the next version of the C standard (perhaps as an optional module so that IBM won't have to bring their operating systems into the '70s).
les@chinet.UUCP (Leslie Mikesell) (08/23/88)
In article <65197@sun.uucp> alanf%smile@Sun.COM (Alan Fargusson) writes: >I have always thought that this was an omission in the stdio I/O library. >If turning echo on and off was defined as part of fread, fwrite, printf, ... >then there would be no problem. As it is now you kind of take your chances >with various version of UNIX, and non UNIX systems are hopeless (as far as >portability that is). Maybe... What if you want to run from a half-duplex terminal? There are good reasons for this, like using a satellite link where there may be a several-second delay in the echo. If stdio provided the echo, every application would need to know how to turn if off. Handling it in the OS/tty driver makes everything work automatically. Perhaps PC types don't consider the possibility of having the keyboard and CPU separated by many thousands of miles. >It is to late to get this into the ANSI-C standard I guess. It is questionable whether it belongs there. Perhaps there should be a standard library interface to the OS or an emulation if the OS doesn't provide the service. However, if an application routinely enables echo it will cause trouble in environments where the echo is provided elsewhere. Les Mikesell
gwyn@smoke.ARPA (Doug Gwyn ) (08/23/88)
In article <65197@sun.uucp> alanf%smile@Sun.COM (Alan Fargusson) writes: >If turning echo on and off was defined as part of fread, fwrite, printf, ... >then there would be no problem. RONG. Making applications control the environment they are run in would be a massive mistake!
henry@utzoo.uucp (Henry Spencer) (08/23/88)
In article <65197@sun.uucp> alanf%smile@Sun.COM (Alan Fargusson) writes: >I have always thought that this was an omission in the stdio I/O library. >If turning echo on and off was defined as part of fread, fwrite, printf, ... > >It is to late to get this into the ANSI-C standard I guess. Much too late. But I believe POSIX's latest revision has included a set of terminal-control functions that look plausible. -- Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology they just act that way. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
henry@utzoo.uucp (Henry Spencer) (08/23/88)
In article <302@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: > ... if you want to control features like echoing you > should probably be using Curses... Urk. No! Control of echoing and such is fairly nicely done in Curses, but there is too much other baggage involved. What you should be using, as soon as it becomes available, is the POSIX set of terminal-control functions (unless it's changed again, POSIX terminal control is now done by a bunch of little functions rather than by an ioctl-style one-big-struct interface). -- Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology they just act that way. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
alanf%smile@Sun.COM (Alan Fargusson) (08/24/88)
In article <302@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes: > (1) Don't forget, the C standard has to make sense on IBM mainframes, > which do not use a character-at-a-time interface to their terminals. I didn't. This has nothing to do with turning off echo, and you can cause the IBM terminals to blank out the input area when echo is off so it does not echo in effect. BTW it is possible to do character at a time input from these guys, but it is very inefficient. > (2) The dpANS makes it clear that fgets() and getchar() are supposed to > do the same things (in general), so if one of them echoes and the > other doesn't, that's broken. I completely agree. What I think should happen is if you do a fnoecho( stdin ) then both will not echo. I just made up fnoecho(), it could be called whatever. > (3) The story with respect to UNIX and MS-DOS is nowhere near as bad as > has been made out: yes the terminal ioctl() calls differ between BSD > and Sys V, but if you want to control features like echoing you > should probably be using Curses, and while there are differences, > they aren't _that_ great. There are implementations of Curses for > MS-DOS, and even VMS tries to support that interface. It is bad enough. I maintained a runtime library that had to turn echo off and do some other things, and it was a real bear to keep it working on all the various flavors of UNIX. We couldn't use curses for this due to some limitations that I can't remember now. I think it had something to do with supporting color terminals. > > I loathe Curses myself, but it _is_ a de facto standard, and is being > used successfully by a lot of applications programmers. It seems to > me that the appropriate thing to do is to propose that Curses be part > of the next version of the C standard (perhaps as an optional module > so that IBM won't have to bring their operating systems into the '70s). I happen to like curses actually, but for simply turning echo off for a short time, then turning it back on the overhead is to high. It just isn't the right tool for this job. - - - - - - - - - - - - - - - - - - - - - Alan Fargusson Sun Microsystems alanf@sun.com ..!sun!alanf
ok@quintus.uucp (Richard A. O'Keefe) (08/24/88)
In article <1988Aug23.164855.26679@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >In article <302@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >> ... if you want to control features like echoing you >> should probably be using Curses... > >Urk. No! Control of echoing and such is fairly nicely done in Curses, >but there is too much other baggage involved. What you should be using, as >soon as it becomes available, is the POSIX set of terminal-control functions >(unless it's changed again, POSIX terminal control is now done by a bunch of >little functions rather than by an ioctl-style one-big-struct interface). Please explain what is wrong with my suggestion. Who _cares_ how much baggage comes with Curses? (a) I don't have to write it. (b) I don't have to use the other stuff. (c) On a paging system, I don't even have to page the other stuff in. The basic point is that implementations of Curses exist *NOW* for BSD UNIX System V VMS MS-DOS I don't see POSIX having much impact on MS-DOS, and surmise that VMS may not conform to POSIX for a few years yet. Using Curses (loathesome though I find it) is more portable than using POSIX features that generally aren't available yet. (We have about half-a-dozen varieties of UNIX here, and none of them has POSIX terminal control.) I also meant to suggest, but did not say plainly enough, that somone who wants control over echoing is likely to want other forms of control over the terminal (if not now, then in the next revision of the program) which are provided in Curses but aren't attainable by means of a few #ifdefs in a page of code as echo control is.
swilson%thetone@Sun.COM (Scott Wilson) (08/24/88)
>Who _cares_ how much baggage comes with Curses? >(a) I don't have to write it. >(b) I don't have to use the other stuff. >(c) On a paging system, I don't even have to page the other stuff in. >The basic point is that implementations of Curses exist *NOW* for > BSD UNIX > System V > VMS > MS-DOS I care, other people care. Some of us are developing C programs on machines like the Macintosh where you are trying to fit your OS stuff, your C programming tools, and your C project onto two 800K floppies. This is comp.lang.c, not comp.lang.c.on.a.big.machine. with.megabytes.of.disk.space.and.maybe.paging. Size is important. And curses is not universally available. -- Scott Wilson arpa: swilson@sun.com Sun Microsystems uucp: ...!sun!swilson Mt. View, CA
ok@quintus.uucp (Richard A. O'Keefe) (08/25/88)
In article <65474@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes: >>Who _cares_ how much baggage comes with Curses? >I care, other people care. Some of us are developing C programs >on machines like the Macintosh where you are trying to fit your >OS stuff, your C programming tools, and your C project onto two >800K floppies. This is comp.lang.c, not comp.lang.c.on.a.big.machine. >with.megabytes.of.disk.space.and.maybe.paging. Size is important. >And curses is not universally available. My word, how things have changed! Little wee IBM PCs running MS-DOS are now "big.machines.with.megabytes.of.disk.space.and.maybe.paging"! (I believe that there is a version of Curses for the Atari ST, too.) If you are working on a Macintosh, POSIX features aren't going to help you one tiny little bit either. What in the world is wrong with taking the bits of the Curses *interface* that you need, specifically the functions echo() and noecho(), and using them in your code? Ok, in the Macintosh version of your program, you will have to write a small Macintosh-specific file to implement them. Do everyone a favour: post the sources to comp.sys.apple.mac or whatever it is called. That's the way to produce a de facto standard, and that's how we'll get echo control in the next version of ANSI C.
daveh@marob.MASA.COM (Dave Hammond) (08/26/88)
In article <65474@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes: >.............. This is comp.lang.c, not comp.lang.c.on.a.big.machine. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >with.megabytes.of.disk.space.and.maybe.paging. Size is important. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I love it ! Dave
karl@haddock.ima.isc.com (Karl Heuer) (08/26/88)
In article <65474@sun.uucp> swilson%thetone@Sun.COM (Scott Wilson) writes: >[ok@quintus (Richard O'Keefe) writes:] >>Who _cares_ how much baggage comes with Curses? > >[On a small machine, it makes a difference.] >And curses is not universally available. And if all I want is to read a raw character (no echo and no line editing), then curses is not only overkill, but may not work. What if I don't have a termcap/terminfo entry? The ioctl doesn't need it, but at least one version of curses will silently exit(1) if it can't find one. Also, I believe that curses insists on having complete control over the terminal; you can't reliably use stdio while curses is active. Finally, endwin() always attempts to move the cursor to the bottom of the screen, which is inappropriate. (A background voice is heard: "Why don't you suggest something better, then?") See my next article. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
karl@haddock.ima.isc.com (Karl Heuer) (08/26/88)
Okay, we know that ANSI didn't standardize a raw-character input function. Some have expressed the opinion that they couldn't, because such functionality is not univerally available. I disagree: they could easily specify that the function is allowed to return a failure code. (Note that the time() function must exist on all ANSI implementations, but is permitted to return (time_t)-1 if there isn't a system clock.) Let's try to design an appropriate interface. Let's begin by ignoring the issue of exactly what "raw" means, and whether it applies to the real terminal despite redirection, or to stdin or a stream of the user's choice. We can argue that out later. We need a minimum of three functions, which I'll call rawenable(), rawdisable(), getrawchar(). The system is always in one of two states, cooked or raw, with the initial state being cooked. (This does not imply that echoing occurs or that line editing is possible; it's simply a name for the initial state.) rawenable() and rawdisable() change the state from cooked to raw or from raw to cooked, respectively; if called from the "wrong" state, the behavior is undefined. If the implementation is unable to honor the request (because there is no OS support for raw input, or because there is no terminal attached), the function returns -1; otherwise it returns 0. If getrawchar() is called from cooked mode, or any stdio function from raw mode, the behavior is undefined. When there are unread characters in the stdin stream (as a result of ungetc() or OS-level line buffering), it is implementation-defined whether getrawchar() behaves like getchar() or acts independently of stdio. In practice, some implementations will make rawenable() and rawdisable() no-ops, and getrawchar() a system call; others will put the system calls into rawenable() and rawdisable(), and make getrawchar() a synonym for getchar(). The model is designed to allow efficient implementation on a wide variety of architectures. This is a first cut at a solution; it can probably be improved. Comments? Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
dhesi@bsu-cs.UUCP (Rahul Dhesi) (08/26/88)
In article <6589@haddock.ima.isc.com> karl@haddock.isc.com (Karl Heuer) writes: >The system is always in one of two states, cooked or raw, with the initial >state being cooked. It would be nice if we applied the concept of raw-versus-cooked to the current input request rather than to the terminal. This way there is no danger of programming carelessness (or having to kill a runaway process) leaving the terminal in a funny state. This happens more often than I like on UNIX systems. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
ok@quintus.uucp (Richard A. O'Keefe) (08/26/88)
In article <6589@haddock.ima.isc.com> karl@haddock.isc.com (Karl Heuer) proposes a rawenable(), getrawchar(), rawdisable() interface. >Let's begin by ignoring the issue of exactly what "raw" means. Let's not. The original topic was reading without _echoing_, which is not the same thing as reading without line-editing. For example, when entering a password, I do *not* want it echoed (not even as "#"s, which is what login does on our Sun 386i, naughty naughty) but I *do* want to be able to correct it as I enter it. Then there's the question of what interrupt characters are heeded (which should be done per-character, but that's another story). Then again, there's the distinction between function keys sending escape sequence -vs- "keycodes". If I expect to read function keys as raw codes of some sort, how do I do that so that it will work on IBM PCs and Apollos? (Curses *does* map function keys to keycodes for you...) A program which is connected to a "terminal" might be connected directly to a keyboard, or it might be connected through a network. "raw" might well mean different things in those two cases. When you are using STREAMS, which modules are absent when you're in raw mode? >If getrawchar() is called from cooked mode, or any stdio function from raw >mode, the behavior is undefined. Does this mean ANY sort of stdio, or only stdio to streams which are not known not to be terminals? Why shouldn't I be allowed to write to a disc file while the terminal is in raw mode?
steve@umigw.MIAMI.EDU (steve emmerson) (08/26/88)
In article <6589@haddock.ima.isc.com> karl@haddock.isc.com (Karl Heuer) writes: >Rawenable() and rawdisable() change the state from cooked to raw or >from raw to cooked, respectively; if called from the "wrong" state, >the behavior is undefined. I would prefer that rawenable() and rawdisable() be idempotent* rather than undefined, unless, of course, this means that they can't be implemented on some systems. I believe this would enable slightly cleaner programs as the relevant state information would be contained (at least conceptually) in the raw{en,dis}able()/getrawchar() module -- discharging the programer from responsibility over the matter. ------------ * "idempotent" means that the effect of calling it twice is the same as calling it once, i.e. the second call is a functional no-op.) -- Steve Emmerson Inet: steve@umigw.miami.edu [128.116.10.1] SPAN: miami::emmerson (host 3074::) emmerson%miami.span@star.stanford.edu UUCP: ...!ncar!umigw!steve emmerson%miami.span@vlsi.jpl.nasa.gov "Computers are like God in the Old Testament: lots of rules and no mercy"
bill@proxftl.UUCP (T. William Wells) (08/26/88)
In article <65071@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes:
: Making a window look
: like a terminal is a function of the C libraries.
Agreed. And your compiler is broken for not doing this
correctly. I know that doesn't help you but I can suggest a
kludge:
If you use getchar() exclusively, you might be able to avoid the
problem by modifying stdio.h. You see, getchar is often
implemented as a macro:
#define getchar() getc(stdin)
or some such. You could edit your stdio.h so that the macro is
something like:
#define getchar() (putchar(getchar()))
This has the advantage of leaving your program portable but the
disadvantage of using a non-standard configuration for your
compiler (watch those upgrades!). And, if you slip and use
something else, you'll get surprised.
: My question is how do we get getchars that behave similarly
: on different systems when for some implementations it falls under the
: responsibility of the C libraries because the OS doesn't have terminal
: support.
The way you get such getchars is to buy the compiler that
provides them. I'm serious. You got screwed by this compiler
implementer (I'll take that back if they fix this bug).
Standards will *not* fix the problem if the implementers do not
adhere to them.
As for interactive terminals, I do not know of *any* other system
that does not provide echoing under normal circumstances when one
does getchar(). (No doubt that will provoke a flood of
counterexamples. So be it.) Your apparent lack of uniformity
appears to be an artifact of a compiler that fails to conform to
the de facto standards. You certainly can't complain if it fails
to conform to the ANSI standard, as that *does not* exist. Yet.
It does appear to be the case that the *proposed* ANSI standard
is somewhat, shall we say, concise :-) when defining interactive
devices. Here are the relevant passages.
Rationale 2.1.2.3:
"The class of *interactive devices* is intended to include at
least asynchronous terminals, or paired display screens and
keyboards. An implementation may extend the definition to
include other input and output devices or even network
inter-program connections, provided they obey the Standard's
characterization of interactivity."
2.1.2.3:
"The input and output dynamics of interactive devices shall take
place as specified in 4.9.3. The intent of these requirements is
that unbuffered or line-buffered output appear as soon as
possible, to ensure that prompting messages actually appear prior
to a program waiting for input.
What constitutes an interactive device is
implementation-defined."
4.9.3:
"... are fully buffered if and only if the stream can be
determined not to refer to an interactive device."
4.9.5.3:
"... is fully buffered if and only if the stream can be
determined not to refer to an interactive device."
And that, I am afraid, would seem to be all.
To clarify this for those on comp.std.c (to which this has been
cross-posted), the original complaint was that his compiler's
getchar() does not echo characters! I agree with him that an
interactive device ought to be defined as one intended to provide
echoing of some kind of the user's input.
The third draft does not seem to say anything like this. Does
anyone out there have any additional information? If not, I'll
ask that they add this to the standard. It ought to be
acceptable, as this would seem to be an editorial change -- is it
interactive if you can't see your input??!
---
Bill
novavax!proxftl!bill
bill@proxftl.UUCP (T. William Wells) (08/26/88)
In article <65197@sun.uucp> alanf%smile@Sun.COM (Alan Fargusson) writes:
: I have always thought that this was an omission in the stdio I/O library.
: If turning echo on and off was defined as part of fread, fwrite, printf, ...
: then there would be no problem. As it is now you kind of take your chances
: with various version of UNIX, and non UNIX systems are hopeless (as far as
: portability that is).
It is remotely possible that requiring echoing could be put into
the standard as an "editorial change". There is not a chance in
hell that control of echoing will. I seriously doubt that it
ever will, as there are important systems where turning off
echoing is *not* possible since echoing is done by parts of the
hardware that can't be affected by the system.
---
Bill
novavax!proxftl!bill
karl@haddock.ima.isc.com (Karl Heuer) (08/26/88)
In article <3761@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >In article <6589@haddock.ima.isc.com> karl@haddock (Karl Heuer) writes: >>The system is always in one of two states, cooked or raw > >It would be nice if we applied the concept of raw-versus-cooked to the >current input request rather than to the terminal. This way there is >no danger of programming carelessness (or having to kill a runaway >process) leaving the terminal in a funny state. This happens more >often than I like on UNIX systems. While this behavior may be more desirable for some applications, insisting on it would require too much overhead on UNIX. My proposal was designed so that rawenable(); while ((c = getrawchar()) != QUIT_CMD) do_command(c); rawdisable(); could be implemented with just one system call (instead of three) for each iteration of the loop. To defend against the "funny state" problem, you can set up traps: signal(SIGINT, rawdisable); atexit(rawdisable); (My "tio" package has an option to automatically do this when you call the equivalent of rawenable().) Alternately, you could get the exact behavior you described by wrapping another layer around the primitives: int getch(void) { int c; rawenable(); c = getrawchar(); rawdisable(); return c; } If what you're really saying is that UNIX should be changed, then I agree (a "/dev/rtty" would be within the Spirit). But that's not a C issue. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
henry@utzoo.uucp (Henry Spencer) (08/27/88)
In article <313@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >... post the sources to comp.sys.apple.mac or whatever it >is called. That's the way to produce a de facto standard, and that's how >we'll get echo control in the next version of ANSI C. If you propose this, the odds are very high that X3J11 will say "(a) this is not a portable construct, since some operating systems cannot implement it; (b) POSIX already does this" and reject it. Admittedly, POSIX is not here yet... but *that's* the standardized interface for such things that you should be trying to use. I would expect to see subsets of that interface made available in most non-Unix C implementations as well. -- Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology they just act that way. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
gwyn@smoke.ARPA (Doug Gwyn ) (08/27/88)
In article <624@proxftl.UUCP> bill@proxftl.UUCP (T. William Wells) writes: >#define getchar() (putchar(getchar())) Ahem. Consider (in UNIX shell notation): filter <infile >outfile There really is no way to do this right in the application code; it has to be dealt with in the run-time environment.
gwyn@smoke.ARPA (Doug Gwyn ) (08/28/88)
In article <1988Aug26.170448.23115@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >Admittedly, POSIX is not here yet... Actually, it is, at least the part (1003.1) you're talking about. A couple of days ago I got a note from Jim Isaak saying that the final IEEE Std 1003.1 had been approved. (Draft 13, I think.)
bill@proxftl.UUCP (T. William Wells) (08/29/88)
In article <8384@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: : In article <624@proxftl.UUCP> bill@proxftl.UUCP (T. William Wells) writes: : >#define getchar() (putchar(getchar())) : : Ahem. Consider (in UNIX shell notation): : filter <infile >outfile : : There really is no way to do this right in the application code; : it has to be dealt with in the run-time environment. Please recall that he wanted a fix for his Macintosh, where there is no such thing as a command line, much less redirection. (Actually, I hear that there is a kludge in Lightspeed C that lets the user type in part of a command line at program start; but according to a guy who is working with that compiler, getchar() echoes when this kludge is used, so I suppose that the guy with the problem isn't using this kludge.) Of course, you really should have got me for this; I wrote: : #define getchar() (putchar(getchar())) And I should have written: : #define getchar() (putchar(getc(stdin))) I do agree that this would be a brain-damaged thing to do on almost any other system. And, I agree, the run-time environment should deal with this; that was the first thing I said in the message that you responded to: In article <624@proxftl.UUCP> I wrote: : In article <65071@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes: : : Making a window look : : like a terminal is a function of the C libraries. : : Agreed. And your compiler is broken for not doing this : correctly. --- Bill novavax!proxftl!bill
peter@ficc.uu.net (Peter da Silva) (08/29/88)
In article <627@proxftl.UUCP>, bill@proxftl.UUCP (T. William Wells) writes: > ever will, as there are important systems where turning off > echoing is *not* possible since echoing is done by parts of the > hardware that can't be affected by the system. I haven't used IBM systems, but the batch terminal systems I'm familiar with at least allow you to change the characters to black-on-black, which is adequate for a password... -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) (08/30/88)
Another one of those fine confused wish list discussions. Unfortunately, like the other discussions of this type, it is fatally flawed. The problem is, evreyone seems to be confusing language functionality with os functionality. Terminal echo is a function provided by the operating system (in this case, UNIX(tm)). Whether or not echoing is going on is invisible to getchar(), and read. The tty device driver is controlling this operation, and only an ioctl can change its behaviour. In many cases, the echoing function is not even taking place on the same processor. In the NCR TOWER(tm) series, the echoing is being done on the HPSIO (a separate 68010 based processor) and is thereby not burdening the CPU. In Amdahl hosts running UTS in a network, the echoing may be done by and Amdahl 4705(tm) channel attached to the host. Ioctl calls will generate commnds to the front end processor to change its character reading behaviour. In fact, in many cases, the echo may already have occurred before the echoing can be turned off. Before you go mucking with the language, I suggest you learn a bit more about your hardware, your operating system, and how they interrelate. Then I suggest you do what I did when I wrote a menuing system - read everything available about the tty device drivers, stty, and termio, experiment like crazy, then write your own raw character input routines. No flame intended. Dan Mercer - NCR COMTEN
ok@quintus.uucp (Richard A. O'Keefe) (08/30/88)
In article <1988Aug26.170448.23115@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >In article <313@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >>[about echo control] >Admittedly, POSIX is not here yet... but *that's* the standardized interface >for such things that you should be trying to use. I would expect to see >subsets of that interface made available in most non-Unix C implementations >as well. Given that the main criticism of my proposal to use the Curses interface was that Curses carries too much with it, I imagine that this won't please *present* Macintosh users (other than A/UX users) much either. I'd be delighted to use POSIX terminal control, except that we don't seem to have it on our Suns yet, or any of our other machines either. (1) Is the POSIX terminal interface settled yet? (2) Which vendors have hinted at a shipping date for POSIX-compatible terminal control? (serious) Have the OSF? (joke) (3) Has anyone produced a free "approximation" of the POSIX terminal interface which can sit on top of either BSD 4.3 or V.3?
swilson%thetone@Sun.COM (Scott Wilson) (08/31/88)
In article <731@ncrcce.StPaul.NCR.COM> mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes: >Terminal echo is a function provided by the >operating system (in this case, UNIX(tm)). Who said we were talking about UNIX? Again, for the nth time, the environment in question is THINK's Lightspeed C 3.0 running on a Macintosh under MacOS. There are no terminals, terminal drivers, terminal emulation windows, stty, or ioctl's. Any terminal emulation is provided by the C runtime libraries. Under UNIX, echoing clearly falls under the realm of the operating system and it would be wrong for a language to specify something that it can't or shouldn't control. I think the real question is that in abscence of OS support for terminals (or interactive input) should the C environment be forced to provide a "normal" input mechanism including echoing and maybe primitive line editing. -- Scott Wilson arpa: swilson@sun.com Sun Microsystems uucp: ...!sun!swilson Mt. View, CA
terry@wsccs.UUCP (Every system needs one) (08/31/88)
In article <313@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes: > In article <65474@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes: > >>Who _cares_ how much baggage comes with Curses? > >I care, other people care. Some of us are developing C programs > >on machines like the Macintosh where you are trying to fit your > >OS stuff, your C programming tools, and your C project onto two > >800K floppies. This is comp.lang.c, not comp.lang.c.on.a.big.machine. > >with.megabytes.of.disk.space.and.maybe.paging. Size is important. > >And curses is not universally available. Bravo, Scott! > My word, how things have changed! Little wee IBM PCs running MS-DOS > are now "big.machines.with.megabytes.of.disk.space.and.maybe.paging"! > (I believe that there is a version of Curses for the Atari ST, too.) > If you are working on a Macintosh, POSIX features aren't going to help > you one tiny little bit either. No, we're talking curses, not something else. Does AT&T say this package of which you speak is curses? > What in the world is wrong with taking the bits of the Curses *interface* > that you need, specifically the functions echo() and noecho(), and using > them in your code? Ok, in the Macintosh version of your program, you will > have to write a small Macintosh-specific file to implement them. Do > everyone a favour: post the sources to comp.sys.apple.mac or whatever it > is called. That's the way to produce a de facto standard, and that's how > we'll get echo control in the next version of ANSI C. <FFFFFFLLLLLAAAAAMMMMMEEEEE GHHHHHOOOOSSSSSSST! (like 'Space Ghost')> Urk. "what's wrong?"? Try Copyright AT&T. Besides, curses is seriously buggy in a number of places, like: XS,XN,AM,SG,UG,GG,tputs(), etc. I can site specific examples; the one you are probably curious about, is, however, tputs(). 1) It doesn't necessarily cause an I/O to occur in a single write operation. This is BAD as transparent printing gets more popular, and seriously kills paged-screen multiple sessions. 2) Not all implementations know about pad characters, and instead print the numbers on the screen. The tgetent() does not malloc() the save area; you have to know how big the maximum area is going to be beforehand when you're coding your own code; that's bad enough... but if some idiot has a monster termcap/info entry, curses can't be made happy without kludges. Curses depends (according to SVID) on the terminfo file. This is a kludge. 1) It is not extensible. It depends on a struct compiled into libcurses. 2) It is hard to fix. Most manufacturers do not provide source. 3) Many terminal definitions are wrong; specifically, SCO Xenix is the only system I've seen that has gotten the Wyse-50 and the Televideo 950 graphics correct, and I had a lot to do with that. True, it's usually broken in termcap, but at least I can fix that. 4) It will not work with a true VT100 terminal or emualation. Since VT100's are probably the most emulated terminal, this is stupid, and obviously a result of poor or no testing. I expect a company like AT&T to be able to afford one of each of the terminals they say they support, considering what they are charging for a liscence. To get it to work, you have to lie and say you are on a 'vt100-nam' or remove the "AM" attr. Standout is not properly handled. In most cases, there is a "protect" bit which can be used in lieu of reverse to at least correctly emulate standout. This is true of all Wyse and Televideo terminals. Curses is brain-damaged with windows. The window implementation is bad in that it 1) Does not understand hardware scrolling (though this is more a terminfo fault, in that it can not be extended to fix this deficiency anyway). 2) Can not move a window in the background while leaving another in the foreground untouched. This is the fault of the model used to implement the window and it's memory mapping. Layered windows were chosen to avoid "excessive memory allocation" for the save buffer area. The point of diminishing returns, to correct this misinformation, is when all windows are n x m or larger where n+1 x m+1 is the virtual screen size. There are no field input primitives. Typical code sizes change from: 270k -> 288k 508k -> 527k when libcurses is used instead of libtermcap. While it is true that disk space is no longer a problem on most systems, space on distribution media is limited. This is an 18-19k increase, and can force an additional disk if there are several executables and distribution space is already tight (it has in 3 cases at our company, due to the target system no longer supporting termcap). Internationalization is hard when most implementations use the 8th bit for their own nefariousness (using a short yields 9 attr bits that way). It is ridiculous to think that a company would ship a product *HEAVILY* dependant on it's display without writing their own code or buying someone elses. Need I say more? <Unflame without much enthusiasm> | Terry Lambert UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry | | @ Century Software OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry | | SLC, Utah | | These opinions are not my companies, but if you find them | | useful, send a $20.00 donation to Brisbane Australia... | | 'I have an eight user poetic liscence' - me |
mcdonald@uxe.cso.uiuc.edu (08/31/88)
>Another one of those fine confused wish list discussions. Unfortunately, >like the other discussions of this type, it is fatally flawed. >The problem is, evreyone seems to be confusing language functionality >with os functionality. Terminal echo is a function provided by the >operating system (in this case, UNIX(tm)). Whether or not echoing >is going on is invisible to getchar(), and read. The tty device driver >is controlling this operation, and only an ioctl can change its >behaviour. In many cases, the echoing function is not even taking >place on the same processor. In the NCR TOWER(tm) series, the >echoing is being done on the HPSIO (a separate 68010 based processor) >and is thereby not burdening the CPU. > Before you go mucking with the language, I suggest you learn > a bit more about your hardware, your operating system, and > how they interrelate. Then I suggest you do what I did when I > wrote a menuing system - read everything available about the > tty device drivers, stty, and termio, experiment like > crazy, then write your own raw character input routines. We want it put in the language so that programs will run portably, and MOST IMPORTANTLY, so that operating system designers will have to fix their operating systems so that it can be done portably!!!!!!!!!! Doug McDonald
mouse@mcgill-vision.UUCP (der Mouse) (09/01/88)
In article <6589@haddock.ima.isc.com>, karl@haddock.ima.isc.com (Karl Heuer) writes: > [raw-character input: first-cut proposal] > rawenable() and rawdisable() change the state from cooked to raw or > from raw to cooked, respectively; if called from the "wrong" state, > the behavior is undefined. I would much prefer for calling rawenable from raw mode, or rawdisable from cooked mode, to be a no-op. I'd also want an inquiry function, to determine the current state. If these features aren't provided, you can be sure lots (most?) of the applications using this will immediately provide static int inrawmode = 0; startraw(){if(!inrawmode){rawenable();inrawmode=1;}} stopraw(){if(inrawmode){rawdisable();inrawmode=0;}} raw_p(){return(inrawmode);} so you might as well standardize them that way. > If getrawchar() is called from cooked mode, or any stdio function > from raw mode, the behavior is undefined. Does this include all stdio functions, all stdio functions that actually perform I/O, or only stdio functions acting on stdin (or the stream in question, if any stream may be put in raw mode)? > Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) (09/02/88)
In article <225800061@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes:
:
:> Before you go mucking with the language, I suggest you learn
:> a bit more about your hardware, your operating system, and
:> how they interrelate. Then I suggest you do what I did when I
:> wrote a menuing system - read everything available about the
:> tty device drivers, stty, and termio, experiment like
:> crazy, then write your own raw character input routines.
:
:We want it put in the language so that programs will run portably,
:and MOST IMPORTANTLY, so that operating system designers will
:have to fix their operating systems so that it can be done
:portably!!!!!!!!!!
:
:Doug McDonald
I think you misunderstand portability. 'C' is portable because
its not machine dependent. The run time support libraries
are machine dependent. Strcpy on some systems is written in
'C', but in most cases, is probably written in assembler
to maximize machine efficiencies.
'C' run time support differs from machine to machine, and
operating system to operating system. Forking on UNIX(tm)
creates another concurrently running process. No such luck
on MS-DOS(tm).
Portability doesn't mean I can write a program for my PC and
recompile it for my NCR Tower and expect it to run the same.
Get real. And don't expect operating system designers to
redesign their operating systems just because someone's too
dumb to figure out how to turn off echoing.
Dan Mercer
NCR Comten
karl@haddock.ima.isc.com (Karl Heuer) (09/03/88)
In article <319@quintus.UUCP> ok@quintus.uucp (Richard A. O'Keefe) writes: >In article <6589@haddock.ima.isc.com> karl@haddock.isc.com (Karl Heuer) >proposes a rawenable(), getrawchar(), rawdisable() interface. > >>Let's begin by ignoring the issue of exactly what "raw" means. > >Let's not. The original topic was reading without _echoing_, which is >not the same thing as reading without line-editing. Right. Which is why I didn't define "raw"; I wanted to leave open the possibility that it could mean "with line editing, but no echo". Such variants can be (and are, in my current implementation) handled via arguments passed to rawenable(). The set of legal feature-combinations is, of course, implementation-defined. (It may even be empty, in which case the request always fails.) >>If getrawchar() is called from cooked mode, or any stdio function from raw >>mode, the behavior is undefined. > >Does this mean ANY sort of stdio ...? Good point. Let's make it "any stdio function which applies to the raw terminal", or something like that. In <155@umigw.MIAMI.EDU> and <1276@mcgill-vision.UUCP>, steve and mouse suggest that rawenable() and rawdisable() should be idempotent instead of causing undefined behavior on repetition. But it may be better to allow them to stack, instead. (E.g. if you want to call getpass() from within raw mode, and if getpass() is implemented using rawenable().) I figured it's better to leave it undefined until the details are worked out. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
tanner@cdis-1.uucp (Dr. T. Andrews) (09/05/88)
In article <733@ncrcce.StPaul.NCR.COM>, mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes: > Portability doesn't mean I can write a program for my PC and > recompile it for my NCR Tower and expect it to run the same. I would beg to differ. What portability means to us (who supply software for more than one machine) is exactly that: I can take a program written for a PC, re-compile it for the NCR Tower, and expect it to run the same. We actually go the other direction: write on big computer, build version for PC after it works on big computer. We then sell both versions. Other than the installation and back-up instructions, we ship the same manual, too. -- ...!bikini.cis.ufl.edu!ki4pv!cdis-1!tanner ...!bpa!cdin-1!cdis-1!tanner or... {allegra killer gatech!uflorida decvax!ucf-cs}!ki4pv!cdis-1!tanner
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) (09/08/88)
:In article <733@ncrcce.StPaul.NCR.COM>, mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes:
:> Portability doesn't mean I can write a program for my PC and
:> recompile it for my NCR Tower and expect it to run the same.
:
:I would beg to differ. What portability means to us (who supply
:software for more than one machine) is exactly that: I can take a
:program written for a PC, re-compile it for the NCR Tower, and
:expect it to run the same.
:
:We actually go the other direction: write on big computer, build
:version for PC after it works on big computer. We then sell both
:versions. Other than the installation and back-up instructions,
:we ship the same manual, too.
:--
:...!bikini.cis.ufl.edu!ki4pv!cdis-1!tanner ...!bpa!cdin-1!cdis-1!tanner
:or... {allegra killer gatech!uflorida decvax!ucf-cs}!ki4pv!cdis-1!tanner
One clarification on your claim - are you using the same
operating system (UNIX(tm) - XENIX(tm)) throughout. I
should have clarified my statement by saying 'written
for a PC running MS-DOS(tm), recompile it for the NCR Tower
running UNIX(tm).' Portability is somewhat guaranteed
throughout the UNIX(tm) world, that's its charm. I
say somewhat, because it is possible to write non-portable
'C' code (assuming byte sizes for pointers, for instance,
and not using casting when its called for).
It is possible to write code that will port between MS-DOS(tm)
and UNIX(tm), but only by importing portability functions,
like termcap and terminfo.
To expect portability across different hardware and operating
system architectures, however, just because you write in
'C', stretches the meaning of portability. One shouldn't
expect the programming language to usurp the role of an
operating system, or expect the interface of the language
to the operating system to be the same in all instances.
And thats my objection to getchar w/wout echo.
Dan Mercer
NCR Comten
karl@haddock.ima.isc.com (Karl Heuer) (09/09/88)
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes: >To expect portability across different hardware and operating system >architectures, however, just because you write in 'C', stretches the meaning >of portability. One shouldn't expect the programming language to usurp the >role of an operating system, or expect the interface of the language to the >operating system to be the same in all instances. Why not? That's exactly what stdio does, for example. And several other system functions (rename(), remove()) are now part of the standard library which must be provided with every ANSI C implementation. On the other hand, fork() is not and should not be part of ANSI C. So I think the real question is whether it's *possible* to standardize a reasonable form of raw I/O interface. If so, I don't see any obvious reason not to do it. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
tanner@cdis-1.uucp (Dr. T. Andrews) (09/09/88)
In article <739@ncrcce.StPaul.NCR.COM>, mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes:
) One clarification on your claim - are you using the same
) operating system (UNIX(tm) - XENIX(tm)) throughout.
No, we are not using the same operating system throughout. We are
using ms-dos (or equiv) on the "PC" machine, and unix/xenix on the
bigger machines.
--
...!bikini.cis.ufl.edu!ki4pv!cdis-1!tanner ...!bpa!cdin-1!cdis-1!tanner
or... {allegra killer gatech!uflorida decvax!ucf-cs}!ki4pv!cdis-1!tanner
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) (09/13/88)
In article <7196@haddock.ima.isc.com: karl@haddock.ima.isc.com (Karl Heuer) writes: :mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes: ::To expect portability across different hardware and operating system ::architectures, however, just because you write in 'C', stretches the meaning ::of portability. One shouldn't expect the programming language to usurp the ::role of an operating system, or expect the interface of the language to the ::operating system to be the same in all instances. : :Why not? That's exactly what stdio does, for example. And several other :system functions (rename(), remove()) are now part of the standard library :which must be provided with every ANSI C implementation. : :On the other hand, fork() is not and should not be part of ANSI C. So I think :the real question is whether it's *possible* to standardize a reasonable form :of raw I/O interface. If so, I don't see any obvious reason not to do it. : :Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint Why not? Why not!! Because character echo is a function of the output device, not part of the character stream, and the output device is part of the operating system, not the language. Stdio's job is to format, input and output the character stream, not to control the device. Controlling echo is meaningless to non display input devices (like hard disks). To mutilate stdio to know the type of input device it is getting the stream from is a violation. And in systems with distributed processing (like NCR Towers, where ioctl takes place in the HPSIO processor, or LAN's, where the ioctl may be distributed to the work stations) it isn't practical (what are you going to do, send out change ioctl commands with every character input). Why don't you just find out how on your machine you turn off echo and roll your own programs to do stdio. For your programs to be portable across different hardware schemes, and different operating systems, you'll just have to do what the rest of us do - write code to port them. Dan Mercer NCR Comten
karl@haddock.ima.isc.com (Karl Heuer) (09/14/88)
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes: >karl@haddock.ima.isc.com (Karl Heuer) writes: >>mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) writes: >>>One shouldn't ... expect the interface of the language to the operating >>>system to be the same in all instances. >> >>Why not? That's exactly what stdio does, for example. > >To mutilate stdio to know the type of input device it is getting the stream >from is a violation. On some implementations, where completely different system calls control the terminal and the disk, stdio already needs to know this. (Even on UNIX, it uses isatty() to decide which buffering scheme to use.) >And in systems with distributed processing ... it isn't practical (what are >you going to do, send out change ioctl commands with every character input). If that's the only way to achieve the effect, then yes, that's what the package has to do. (Isn't that what the user would have to do, if he chooses to roll his own?) If there's a more efficient way, but it doesn't jive with the model I proposed (rawenable(), getrawchar(), rawdisable()), then I'd like to change the model to accommodate. That's why I brought it up. >Why don't you just find out how on your machine you turn off echo and roll >your own programs to do stdio. For your programs to be portable across >different hardware schemes, and different operating systems, you'll just have >to do what the rest of us do - write code to port them. That's what I'm doing. On various implementations, I'm finding out how to turn off echo, and I'm encapsulating that information in a package. I port that package to different implementations, and any of my programs that need the feature access it through this package. So what do I end up with? An interface of the language to the operating system which is the same in all instances. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
ok@quintus.uucp (Richard A. O'Keefe) (09/15/88)
In article <628@wsccs.UUCP> terry@wsccs.UUCP (Every system needs one) writes: >In article <313@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes: [about Curses] >No, we're talking curses, not something else. Does AT&T say this package >of which you speak is curses? My understanding is that at least one of the Curses implementations available for the PC is based on source code released into the public domain by AT&T. But may I make a really rather elementary point? * "Curses" is anything which provides the "Curses" interface ><FFFFFFLLLLLAAAAAMMMMMEEEEE GHHHHHOOOOSSSSSSST! (like 'Space Ghost')> > >Urk. "what's wrong?"? Try Copyright AT&T. > I repeat, Curses is an *INTERFACE*. I did not suggest stealing source code; what I suggested was using the same names and interfaces for the operations that were needed, so that on systems where Curses was available you would be able to use the existing implementation. >Besides, curses is seriously buggy in a number of places, like: Quite irrelevant, as I was not advocating swiping source code, but adapting an existing *interface*. In fact (Every system needs one)'s objections are mostly invalid for this reason. (Also, he wasn't describing the current version.) >Internationalization is hard when most implementations use the 8th bit >for their own nefariousness (using a short yields 9 attr bits that way). If you're interested in internationalisation, some of the V.3 utilities are already customisable (se "isort", for example), and V.4 is really taking it seriously. (8 bits just aren't enough.) The Curses interface in V.4 is going to be the only reasonably widespread internationalisable (did I write that?) terminal interface around. I still expect to loathe it, but there just isn't anything else on offer. If people are really worried about the size of programs on 286s, they should be looking forward to OS/2. With shared libraries, it is programs which *don't* use standard interfaces which pay a storage cost!
kpv@ulysses.homer.nj.att.com (Phong Vo[eww]) (09/16/88)
Hi all. I've just been alerted by a friend to this discussion on curses. Following are a few comments on the posting from Terry Lambert. He brought up many relevant points about earlier versions of curses. I sympathize with his frustration. In fact, the same frustration prompted me a few years back to rewrite curses. The following comments are germane to this new version of curses that is currently distributed by the System V folks at Summit. In article <628@wsccs.UUCP>, terry@wsccs.UUCP (Every system needs one) writes: > In article <313@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes: > > In article <65474@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes: > > >>Who _cares_ how much baggage comes with Curses? > > >I care, other people care. Some of us are developing C programs > > >on machines like the Macintosh where you are trying to fit your > > >OS stuff, your C programming tools, and your C project onto two > > >800K floppies. This is comp.lang.c, not comp.lang.c.on.a.big.machine. > > >with.megabytes.of.disk.space.and.maybe.paging. Size is important. > > >And curses is not universally available. > > Bravo, Scott! Even on a big machine, keeping down program size is good. Similarly, even on fast machines, you still want your programs to be efficient. The version of curses that I wrote accomplished both. The library efficiency comes from the following considerations: 1. Consolidating similar functions and reuse code whenever they make sense. For example, wclear and werase are implemented in a single piece of code. This piece of code, in turn, uses wclrtoeol to do the actual clearing. You'll be amazed at how much code duplication there is in older version of curses. This happens both at the user-level functions and at the internal curses functions such as subparts of wrefresh. 2. Structuring code so that an application only has to include what it uses. For example, if an application does not need function key detection for input or using the insert/delete line capabilities for screen update, these pieces of codes are not linked with the a.out. Believe me, these pieces of code are not trivial in size and complexity. 3. The code structuring, in fact, extends to the overall architecture of the library as well. The library conceptually consists of two parts. The top part is what you tend to think of as libcurses.a. The lower part allows access to either the termcap or the terminfo database and to do input/output to the terminal. This means that if you don't like curses windows, you don't have to pay for its code. But you can still do things like time-out reads and function key detections as well as all the ioctl-related functions such as noecho or cbreak. 4. Developing new screen update and cursor movement algorithms. The old algorithms in the original curses from BSD as well as the one in System V.2 curses contain many ad-hoc special case code. The new screen update algorithm is more theoretically sound and handles capabilities such as insert/delete chars and insert/delete lines more gracefully. And yes, magic-cookies terminals such as the HP 26* and the TVI950 are all handled correctly and "optimally". Of course, with the TVI950 and similar terminals where the cookies actually occupy screen space, correctness has to be taken with a grain of salt. > Besides, curses is seriously buggy in a number of places, like: > > XS,XN,AM,SG,UG,GG,tputs(), etc. > The problems with magic-cookies, margin etc. are all taken care of in the new screen update and cursor movement algorithms. > > I can site specific examples; the one you are probably curious about, is, > however, tputs(). > > 1) It doesn't necessarily cause an I/O to occur in a single write > operation. This is BAD as transparent printing gets more > popular, and seriously kills paged-screen multiple sessions. > Tputs itself does not output anything. It calls a user-supplied function to output characters. Since your application supplies this function, it ought to do whatever buffering is necessary to ensure a single write. The window-level <curses> uses a large buffer for this purpose. > > 2) Not all implementations know about pad characters, and instead > print the numbers on the screen. > > The tgetent() does not malloc() the save area; you have to know how big > the maximum area is going to be beforehand when you're coding your own > code; that's bad enough... but if some idiot has a monster termcap/info > entry, curses can't be made happy without kludges. > This is only a problem with termcap-based curses not terminfo-based versions. At the risk of being flamed, I'll add that vi initialization procedure is part of the reason for avoiding malloc-ing when a termcap entry is read. > Curses depends (according to SVID) on the terminfo file. This is a kludge. > > 1) It is not extensible. It depends on a struct compiled into > libcurses. > > 2) It is hard to fix. Most manufacturers do not provide source. > I am not a big fan of terminfo myself but there are advantages in terminfo beyond termcap. Most of these have been mentioned before by others. I only emphasizes here that this conversation started partially with the problem of fat and slow curses. The use of terminfo does speed up an application start-up time considerably and does reduce the size of the application somewhat. As I like the flexibility of termcap, my local version of curses provides support for both termcap and terminfo. In fact, at start-up time, an application can decide on what database to use. > > 3) Many terminal definitions are wrong; specifically, SCO Xenix > is the only system I've seen that has gotten the Wyse-50 and > the Televideo 950 graphics correct, and I had a lot to do with > that. True, it's usually broken in termcap, but at least I > can fix that. > Have you communicated these problems with Tony Hansen (att!pegasus!hansen)? He maintains the most up to date termcap/terminfo source that I know of. I did have a TVI950 and many flavors of the HP26* terminals that I used to test the screen update algorithm. > 4) It will not work with a true VT100 terminal or emualation. > Since VT100's are probably the most emulated terminal, this > is stupid, and obviously a result of poor or no testing. I > expect a company like AT&T to be able to afford one of each > of the terminals they say they support, considering what they > are charging for a liscence. To get it to work, you have to > lie and say you are on a 'vt100-nam' or remove the "AM" attr. > As far as I know, curses work as advertised. In fact, I have programs that people use regularly without problems on their PCs with vt-100 emulation packages. > Curses is brain-damaged with windows. The window implementation is > bad in that it > > 1) Does not understand hardware scrolling (though this is more > a terminfo fault, in that it can not be extended to fix > this deficiency anyway). > The new update algorithm knows about hardware scrolling to all its gory variations. This includes all things such as scrolling regions, memory retained above and below, scroll forward/backward and so on. > 2) Can not move a window in the background while leaving another > in the foreground untouched. This is the fault of the model > used to implement the window and it's memory mapping. Layered > windows were chosen to avoid "excessive memory allocation" for > the save buffer area. The point of diminishing returns, to > correct this misinformation, is when all windows are n x m or > larger where n+1 x m+1 is the virtual screen size. > I only understand the first sentence. With SYSV curses, you can use wnoutrefresh to do a sequence of virtual window refreshes until you get the screen that you want then call doupdate to get the screen changed. Admittedly this is not the same as being able to move windows in the same way that windows on bit-map terminals are moved but it is not hard to implement the bit-map window movement model on top of the curses model. In fact, I know of at least a few such implementations. The basic curses model is very useful in appropriate applications. > There are no field input primitives. > Are you talking about a form-like facility? There are many packages for doing that. They are implemented on top of curses. I developed a language called IFS (Interpretive Frame System) to write form and menu programs. In fact, this work is what got me to rewrite curses. Older versions were just too buggy and fat and slow to do what I wanted to do. > Typical code sizes change from: > > 270k -> 288k > 508k -> 527k > > when libcurses is used instead of libtermcap. While it is true that > disk space is no longer a problem on most systems, space on distribution > media is limited. This is an 18-19k increase, and can force an additional > disk if there are several executables and distribution space is already > tight (it has in 3 cases at our company, due to the target system no > longer supporting termcap). > With the new curses, the size problem will not be as bad. I don't have specific numbers but I was told that the new curses is at least 20% smaller than older ones (except the original BSD version but that does not do much). > > Internationalization is hard when most implementations use the 8th bit > for their own nefariousness (using a short yields 9 attr bits that way). > > It is ridiculous to think that a company would ship a product *HEAVILY* > dependant on it's display without writing their own code or buying > someone elses. > The new library is internationalized. It knows all about the European character sets which are relatively simple. It also knows about Oriental character sets which have multiple-byte and multiple-column characters. Now, I would like to comment on the unnecessary bashing of earlier curses implementations and AT&T. When curses was first built some 10 years ago, machines were small and slow and the international market was non-existent. Every bit and byte counts so the library was implemnted to save as much space as possible. It is unlikely that either Ken Arnold or Mark Horton were thinking of the Japanese market around that time. In fact, they were rather clever in making use of these bits and bytes to get the desired functionality. Only in the past few years that considerations for these other markets become prominent and we begin to see inadequacies in current software. People like myself and others (David Korn, Warren Montgomery, Tony Hansen just to name a few) in AT&T do spend considerable amount of time and effort to improve our software and make them generally applicable. Phong Vo, att!ulysses!kpv, 201-582-4869 AT&T Bell Labs, 600 Mountain Ave, Murray Hill, NJ07974
karl@ddsw1.UUCP (Karl Denninger) (09/17/88)
In article <10608@ulysses.homer.nj.att.com> kpv@ulysses.homer.nj.att.com (Phong Vo[eww]) writes: >Hi all. I've just been alerted by a friend to this discussion on curses. >Following are a few comments on the posting from Terry Lambert...... ..... Question for you curses hackers: Why is it that in a terminfo based implementation that the screen does not redraw on a "refresh()" call if there are characters stacked by type-ahead? I've seen this behavior on three different terminfo implementations, so I assume it's something internal to the design. The worst part about this problem is that there is _no way_ to prevent the gagging of output. I can understand the intent -- to allow type-ahead to be processed, since you might be able to process faster than the output could be sent to the terminal over a serial line. But this behavior makes curses _useless_ for some interactive applications, as anytime you get ahead of the system, the output freezes until the machine catches up! The immediate application is a multiuser game -- which should display the screen contents after each move. With termcap curses I get the desired behavior. With terminfo it's unplayable, as the screen just _sits_ there until type-ahead is exhausted. Since the game regulates input by use of a sleep() call (or nap() in those systems which have it), there is _often_ stacked type-ahead waiting. The result? You can't see what the @#$# you're doing! Is there a work-around for this problem, or a way (other than flushing the input) to get the output to appear _now_ when I call refresh()? I haven't been able to find it. -- Karl Denninger (ddsw1!karl) Data: (312) 566-8912, Voice: (312) 566-8910 Macro Computer Solutions, Inc. "Quality solutions at a fair price"
les@chinet.UUCP (Leslie Mikesell) (09/18/88)
In article <1715@ddsw1.UUCP> karl@ddsw1.UUCP (Karl Denninger) writes: >Why is it that in a terminfo based implementation that the screen does not >redraw on a "refresh()" call if there are characters stacked by type-ahead? >I've seen this behavior on three different terminfo implementations, so I >assume it's something internal to the design. The worst part about this >problem is that there is _no way_ to prevent the gagging of output. The AT&T SysVr3 curses(3X) says that you can use the function typeahead(fildes) to tell curses to perform its type-ahead check on some other file instead of stdin or what you passed to newterm(). If fildes is -1, no typeahead checking is done. The idea is that if you have typed something ahead, you probably aren't interested in the pending display so it is postponed until the next time refresh() is called. In case your version doesn't have the typeahead() function, you might just call refresh() twice every time that it is important to update the display. If it completed on the first call it shouldn't output anything on the second. Les Mikesell
kpv@ulysses.homer.nj.att.com (Phong Vo[eww]) (09/18/88)
In article <1715@ddsw1.UUCP>, karl@ddsw1.UUCP (Karl Denninger) writes: > > Why is it that in a terminfo based implementation that the screen does not > redraw on a "refresh()" call if there are characters stacked by type-ahead? > In many interactive applications (e.g., editors or form/menu systems), users are not always interested in the intermediate screens, only in the final screen after a long sequence of typed inputs. Since these are popular curses applications, type ahead checking was made the default behavior for curses. > Is there a work-around for this problem, or a way (other than flushing the > input) to get the output to appear _now_ when I call refresh()? I haven't > been able to find it. > Yes. After initscr(), call typeahead(-1). This turns off the typeahead checking algorithm (by setting the type ahead file descriptor to -1).