john@basser.oz (John Mackin) (08/26/87)
In article <209@ho7cad.ATT.COM> nuucp@ho7cad.ATT.COM (UUCP) writes: > In article <339@cbstr1.att.com> Karl.Kleinpaste@cbstr1.att.com writes: > > >> Not a typewriter > > Well, I agree. This is pretty funny. But don't blame compress. A lot > of programs give you this. Seems to be what you get on some machines > when you call "perror()" when there ain't been no error (of its genre) > [or maybe when the error number is bigger than the secret message > array]. Consider this example code: main() { perror("foo"); } On many UNIX systems (I'm sure there are many exceptions, please don't send me mail (or worse, post!) pointing out that yours is one of them) this will indeed print ``foo: Not a typewriter'', if its output has been redirected onto a file. Why? It certainly isn't because there hasn't been an error. The reason is that the standard I/O library (on many, but by no means all, systems) makes the buffering of stdout behave differently if it is attached to a terminal. On some systems, it then becomes unbuffered by default; others (e.g., 4.3BSD) have line-buffering, which is used by default on stdout if it is a terminal. Now, to determine if the standard output is a terminal or not, the stdio initialization typically uses isatty(). And isatty() works by applying a system call that only works on terminals (typically, gtty()) to the supplied file descriptor and seeing whether it fails or not. Hence, any time isatty() is applied to a file descriptor that is not a terminal, it has the side-effect of setting errno to ENOTTY, "Not a typewriter". Mr. Kleinpaste is indeed entitled to blame compress. The real problem here is that perror() is being used in an inappropriate manner. Seventh Edition intro(2) clearly states: Errno is not cleared on successful calls, so it should be tested only after an error has occurred. The only time errno is valid is immediately after a system call (or library routine whose manual states that it sets errno on error) has returned an error indication. In this case it would seem that that is not the case. Many programs are quite cavalier about their use of errno, both directly and indirectly (e.g. via perror()), and this can sometimes lead to very subtle bugs, as well as annoying and confusing inappropriate error messages. John Mackin, Basser Department of Computer Science, University of Sydney, Sydney, Australia john@basser.oz.AU (john%basser.oz@SEISMO.CSS.GOV) {seismo,hplabs,mcvax,ukc,nttlab}!munnari!basser.oz!john Copyright 1987 John J. Mackin. Restricted redistribution prohibited.
domo@riddle.UUCP (Dominic Dunlop) (09/08/87)
Nobody seems to have posted anything quite like this (although some are quite close), so stand back while I demonstrate my prowess (you might just get bored to death)... An unexpected ``Not a typewriter'' message is usually the result of perror() being called after some standard I/O operation which the caller deems to have failed, but which has not actually made a failing system call. The reason is that, any time standard I/O opens an output file, it tries a terminal-specific ioctl(). If the call succeeds, stdio knows that it should send the output to the file without (much) buffering. If it fails, buffering is desirable for efficiency. A failed ioctl() leaves ENOTTY in errno, the location used by perror() to index into the table of error messages. As the errno value hangs around until the programmer explicitly clears it (and most programmers don't bother), it's liable to get picked up if perror() is called much later following an operation which the programmer considers to be a failure, but which the kernel doesn't. If the programmer clears errno before such an operation, and calls perror() afterwards, another helpful message such as ``(null)'' may well result. The moral of this story is that the only time it's safe to use perror() to report problems is when a failure's so obvious that even the kernel's noticed. Why compress fails in this way on encountering the ulimit (boo, hiss), rather than primly reporting an EFBIG error is beyond me. Can I be bothered to look at the source? No (the pubs are open). Dominic Dunlop domo@riddle.uucp domo@sphinx.co.uk