From owner-freebsd-hackers Mon Nov 20 2:18:50 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from siri.nordier.com (c3-dbn-96.dial-up.net [196.33.200.96]) by hub.freebsd.org (Postfix) with ESMTP id 9364337B479 for ; Mon, 20 Nov 2000 02:18:43 -0800 (PST) Received: (from rnordier@localhost) by siri.nordier.com (8.9.3/8.6.12) id MAA23349; Mon, 20 Nov 2000 12:20:05 +0200 (SAST) From: Robert Nordier Message-Id: <200011201020.MAA23349@siri.nordier.com> Subject: Re: fclose vs ferror (from libc/getcap) To: drosih@rpi.edu (Garance A Drosihn) Date: Mon, 20 Nov 2000 12:19:59 +0200 (SAST) Cc: hackers@FreeBSD.ORG In-Reply-To: from "Garance A Drosihn" at Nov 19, 2000 08:27:56 PM X-Mailer: ELM [version 2.5 PL3] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Garance A Drosihn wrote: > As mentioned in pr bin/22965, I stumbled across a bug > in libc/gen/getcap.c when compiling it under other > platforms. The basic problem is some code which does: > > (void)fclose(pfp); > if (ferror(pfp)) { > ...do stuff... > } > > I find it surprising that the above works under FreeBSD. > (not only that, it seems to work OK under several other > OS's too). The fclose is supposed to throw away the > stream, but the ferror (apparently) still works with > that pointer. > > The PR includes a patch for getcap.c (which is just to > use the result from fclose to determine if an error > occurred), but I also wonder if we should do something > so that this combination would ALWAYS fail. It seems > to me that fclose should clear out whatever fields that > ferror is using for sanity-checking, and ferror should > always return an errno of 'bad parameter', or something > like that. > > Or is there some reason that we DO want ferror to work > on streams which have already been closed? Bear in mind that ferror is one of a number of stdio functions that are often implemented as macros. For instance: ferror and (say) getc might look like this: #define ferror(f) ((f)->fl & _FERR) #define getc(f) ((f)->p < (f)->xr ? *(f)->p++ : fgetc(f)) Given the intentionally minimalist way those functions are written, to do any consistent and obligatory sanity-checking on (FILE *) would cause a big change in the actual code generated, and the amount of code generated. I think the best way to do what you want is to create a separate debugging library. The point about (void)fclose(pfp); if (ferror(pfp)) { ...do stuff... } is that it's a silly thing to do deliberately, but if I was porting some hairy old C code I'd tend to expect it to work. C is not a language in which you go out of your way to prevent people making mistakes. -- Robert Nordier rnordier@nordier.com rnordier@FreeBSD.org To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message