Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site osu-eddie.UUCP Path: utzoo!watmath!clyde!cbosgd!osu-eddie!karl From: karl@osu-eddie.UUCP (Karl Kleinpaste) Newsgroups: net.flame Subject: Csh cruftiness! Message-ID: <170@osu-eddie.UUCP> Date: Wed, 13-Mar-85 17:00:37 EST Article-I.D.: osu-eddi.170 Posted: Wed Mar 13 17:00:37 1985 Date-Received: Thu, 14-Mar-85 06:14:58 EST Distribution: net Organization: You really don't want to know Lines: 86 [The following will develop to a reasonably high-grade flame. But the flame is not yet lit...] I confess...I like csh. I like it a lot. A whole lot. I do a great deal of really serious csh hacking. I put features into csh that make life more convenient for myself, like a scheduled-event list so that commands that I remember have to be done 2 hours from now get queued up now and I can forget about them later. I put editor front-ends onto csh (and other things, now that it's a library). I maintain no less than 3 separate versions for myself, one for 4.1BSD, one for 4.2BSD, and one that I run on my USG Unix machines at work (one with USG SysIII and two with USG SysV). I'm working very hard at adding nearly-real job control functions to my USG version, without kernel modifications. So you can see that I really like csh in the general case. [Approaching critical flame temperature...] Yesterday I fixed a bug in csh. Gads. It seems that typing `exit' at the csh doesn't REALLY cause csh to exit. No. No such luck for me. I have an editor on the front-end of my csh these days. It makes it act much like ksh, but I think it's a bit nicer. It's also not bound to csh; I can put it on other things. In this editor, I have a nice, simple, almost trivial read routine, which picks up single characters from the terminal with non-canonical input, and runs off to do functions as dispatched by those chars. No sweat so far. This routine detects if it got back a return code <= 0, and if so, simply retries the read. I did this because there are possibilities, such as having SIGALRM go off, which might cause the read to abort early. Seemed obvious enough to me. I made the [fatal] assumption that, if someone asks me to read, there's something out there to read. Reasonable, yes? No. [FLAME ON] Csh doesn't *necessarily* believe this. (I recommend you be near something convenient in which to lose your lunch for the remainder of this paragraph.) When you type the characters e-x-i-t-\n at a csh command prompt, csh calmly parses that to the word `exit,' finds the builtin function exit, calls a routine doexit() attached to that builtin, and...doesn't exit. No. What csh does at this point is to set the status by which it will exit, and then it closes stdin. That's all. It returns to normal command line processing at that point. (If you're up on read(2) intricacies, you are now ill.) In standard csh, this is no problem, because in standard csh, the ensuing attempt at a read (on the now-closed stdin file descriptor) returns -1 bytes with errno == EBADF. Csh detects this as normal (?!) end-of-file, and goes through true exit at that point. But with my editor on the front end of things, I made what *seemed* to be a reasonable assumption, and I personally think still *is* a reasonable assumption, but it led to rapidly- executing infinite loops, because the editor's read routine kept retrying and retrying and retrying the read, and every time it came back with an error because I tried to read on a closed file descriptor. And, of course, csh ignores SIGQUIT and catches SIGINT, so I couldn't stop it... [FLAME UP FULL] This is really crufty, inelegant, and dangerous as a way to program a task. If a function is supposed to perform an exit, then it ought to EXIT, for crying out loud. It most definitely SHOULD NOT go performing mental gymnastics with the file descriptors, counting on the side effect that reading from a closed file manages to return something identifiable. Yes, that's what the man page says it does (I was evidently getting -1 and EBADF), but it's nonetheless poor programming practice to read deliberately a file KNOWN to be closed, especially since fixes to the problem were so obvious. [...flame off...] Oh, yeah, by the way, the fix: in sh.func.c, where doexit() says if (intty) close(SHIN); was changed to if (intty) { close(SHIN); intty = 0; } which is no better, but which merely allows the already-existing braindamage of csh internals to run their normal (?!) course, i.e., it avoids my editor, since use of the editor is conditional upon intty. The bottom line is that it makes it work, but I am not proud of it, either. -- Karl Kleinpaste @ Bell Labs, Columbus 614/860-5107 +==-> _c_b_r_m_a_!_k_k @ Ohio State University 614/422-0915 osu-eddie!karl