Accessing the UNIX file descriptor inside an fstream

Chris Rankin rankinc@pacbell.net
Fri Sep 14 21:20:00 GMT 2001


Hi,

Yes, I am fully aware that this topic has been brought up before. I
have found numerous references in the mailing list going back to
January 2000. However, I doubt that you'll make it go away by ignoring
it, especially since libstdc++-v3 is now part of gcc.

I am (was) trying to port some C++ code from g++-2.95.3 to g++-3.0.1
and the showstopper problem was this single line:

  fcntl(m_file.rdbuf()->fd(), F_SETFD, FD_CLOEXEC);

This line is important - the descriptor MUST NOT BE INHERITED BY CHILD
PROCESSES. Now I am fully aware that the C++ standard cannot specify
anything about file descriptors because they're OS-specific and C++
isn't. Fair enough. However, by denying access to the file-descriptors
you forced me to consider the following options:

a) Hack the library. This wasn't really an option, of course.

b) Customise and extend the existing IO-streams to provide access. I
actually investigated this option quite heavily and unearthed your
non-standard constructor for the basic_filebuf template. Unfortunately
I couldn't use it because my ofstream object is constructed as a
member of another class and is opened later. Nor does the
basic_ofstream template allow its basic_filebuf object to be replaced
once it has been constructed. I would therefore have had to
reimplement a *significant* amount of code in order to access a
descriptor which I know full well is lurking in there somewhere. Nor
do the internal workings of the libstdc++ IO-streams appear to be
documented interfaces, which means that I might have been faced with
repeating this excercise at the *next* compiler upgrade. That was
*definitely not* an option.

c) Don't use IO-streams; use printf() and FILE* instead. This would
have been a less drastic (although still significant) rewrite than
rewriting IO-streams. The amount of testing involved would have been
less too. However, having to use the non-typesafe C interface in an
otherwise perfectly reasonable C++/UNIX program felt as if I was
letting the tail wag the dog...

d) Don't use g++-3.0.1. This is the option I finally went for. Of
course, I couldn't leave the program at g++-2.95.3 either and so I
ported it to a different compiler entirely. (We had another compiled
available for the platform which we have used extensively, and while
it is older we have full confidence in it.) There were a few quirks,
but nothing major. Interestingly enough, *none* of the quirks related
to the descriptor access. The rdbuf()->fd() method compiled just
fine.


I do find your intransigence on the issue of file descriptors strange,
because you have now confined g++ to the highest-common-factor of file
operations on all the various OSs. This has made it unsuitable for any
application which needs to do *anything* non-trivial. Your argument
that you are conforming strictly to the C++ standard is also
specious. C has its own standards for file access in the form of
printf and FILE*. However, UNIX vendors *still* implement fileno() and
fdopen() on every box I have worked on (HP-UX, Solaris,
glibc/Linux). There's also this wonderful quote from the mailing list
archive:

"I need to make this absolutely clear, both here and for the archives:
that filebuf extension is there because we need it ourselves, in order to
make other parts of the library work."

Yes, sometimes people NEED things that are not in any standard because
otherwise things DON'T WORK. Now please apply this principle to
developers OTHER than yourselves.

That's my 2 cents (also for the archive),
Sincerely,
Chris Rankin



More information about the Libstdc++ mailing list