Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Nov 2000 12:19:59 +0200 (SAST)
From:      Robert Nordier <rnordier@nordier.com>
To:        drosih@rpi.edu (Garance A Drosihn)
Cc:        hackers@FreeBSD.ORG
Subject:   Re: fclose vs ferror (from libc/getcap)
Message-ID:  <200011201020.MAA23349@siri.nordier.com>
In-Reply-To: <p04330101b63e2c0b9192@[128.113.24.47]> from "Garance A Drosihn" at Nov 19, 2000 08:27:56 PM

next in thread | previous in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011201020.MAA23349>