Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!sri-unix!quintus!ok From: ok@quintus.UUCP (Richard A. O'Keefe) Newsgroups: comp.lang.c Subject: Re: stdio error detection Message-ID: <290@cresswell.quintus.UUCP> Date: Fri, 27-Nov-87 19:11:18 EST Article-I.D.: cresswel.290 Posted: Fri Nov 27 19:11:18 1987 Date-Received: Mon, 30-Nov-87 00:19:45 EST References: <289@cresswell.quintus.UUCP> <6748@brl-smoke.ARPA> Organization: Quintus Computer Systems, Mountain View, CA Lines: 43 Keywords: errno fclose fopen stdio errors Summary: bad advice In article <6748@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn) replied to my question about stdio error handling. One of the things he said was > Assuming no bugs in your code, fclose() can fail only if the stream had some > unwritten buffered data and an I/O error occurred while writing it out. and I'm very pleased to see this, because I'd never thought of that. But when he says > Again, the simplest thing is to let errno tell you. I was disappointed, because the whole point of my message is that it DOESN'T. He says of this use of errno: > True in general, but if you assume that the stdio function failed because > some system call failed, it is fairly reliable. No way is it reliable. (a) I have no way of telling whether a stdio function failed because some system call failed or for some other reason -- that is what I was ASKING for! (b) There is nothing to stop a valid implementation of stdio calling some other system call after the failed one, and that undefines errno even if the later system call succeeds. > In a UNIX environment, ENOMEM (or, less likely, EAGAIN) are the errno > codes for inability to obtain more memory for the process. If malloc() > cannot obtain enough memory, one of these codes will be set in errno. In SunOS 3.2 the malloc() family is explicitly defined to set errno, and the different cases are clearly distinguished. However, this is NOT in the SVID, and it is NOT in any System V manual I've checked. POSIX (the IEEE 1003.1 standard) inherits malloc() from the C standard, which is silent on this point. (It says that some functions *must* set errno, and that some functions *needn't*, but is silent about most and never says *which* value errno is set to.) Here at Quintus, I don't have to worry about porting my code to MS-DOS, but in general I *do* have to worry about 4.2, 4.3, V.2, V.3, VMS, and SAS Lattice C for MVS and VM/CMS. Modulo the choice of setbuf, setvbuf, or setbuffer, all these implementations of stdio look pretty close, and I was hoping that maybe they had more in common than the manuals said. One of the things that bothers me about fclose() is this: suppose f is a valid pointer to an open output stdio stream, but that fclose(f) returns EOF -- perhaps because of a write error when flushing remaining buffered output, or perhaps because of an unlucky interrupt (check man 2 close). IS f CLOSED? When this is inside a loop processing a couple of hundred files, one after the other, if f is *not* closed I can run out of streams despite having taken care to close everything as soon as possible.