Another conformance question... This time fputs().

Bruce Evans bde at zeta.org.au
Wed Mar 3 19:22:17 PST 2004


On Wed, 3 Mar 2004, David Schultz wrote:

> On Wed, Mar 03, 2004, Bruce Evans wrote:
> > This is the only failure case.  It bogusly returns EOF instead of boolean
> > true.  We can set errno to EBADF here if we have no idea why __SRW is
> > clear.  But we should know.  I think the cases are:
> > (1) a normal fopen() for reading only.  Then EBADF is correct.
> > (2) funopen() with no writer, or fropen().  I think this can be determined
> >     by checking the function pointer that we write through.  Then write is
> >     just unsupported and an errno like ENOTSUP is better than EBADF.
> > (3) otherwise, we will call the underlying function and there is no problem
> >     here.  The underlying function just needs to set errno if it fails, and
> >     old ones probably don't.
> > So the only immediate problem with returning EBADF in all cases seems to be
> > in case (2) which is not very interesting.
>
> One could argue that EBADF is a perfectly reasonable error code to
> return in case (2) as well.  It is consistent with the way other
> types of stdio streams work.  Specifically, if the stream isn't
> writable (either because it was opened read-only and we don't have
> permission or because it was opened without a writefn and we don't
> support it) then we should get a single error code that reflects
> the fact that the stream isn't writable.  The fputs(3) man page
> even says:
>
> 	[EBADF]		The _stream_ argument is not a writable stream.
>
> It doesn't say anything about why the stream is not writable.
> Thus, there shouldn't be a problem with simply setting errno to
> EBADF in all failure cases in __swsetup().

I would argue that that is a bug in the fputs man page.  It clearly
doesn't consider the case of funopen()'d streams, and fputs() never
actually set errno to EBADF like the man page says.

However, errno is set EBADF is set explicitly in several other places
irrespective of the destination of the output, and its too late too
change all of these and wrong to be inconstent with them:

fclose: EOF/EBADF if the stream is not open
fflush: EOF/EBADF if the stream is not writable
fpurge: EOF/EBADF if the stream is not open
__fvwrite: recently changed
__srefil: EOF/EBADF if the stream is not open for reading.  __srefil is
          similar to the function behind cantwrite(), namely __swsetup,
	  except it is for reading instead of writing and it sets EBADF.

The man page for fflush and fpurge documents EBADF explicitly, but the
man page for fclose only has generalities about errno.

Bruce


More information about the freebsd-standards mailing list