This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Accessing the UNIX file descriptor inside an fstream


On Fri, Sep 14, 2001 at 09:20:12PM -0700, Chris Rankin wrote:
> 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.

Sure it can.  It's just that the member function you want is in a base
class, and it's hidden.  Use the scope resolution operator to expose it.

    39% cat f.cc

    #include <fstream>
    #include <stdio.h>

    using namespace std;

    int main()
    {
        ofstream  orig ("original.file");
        FILE*     later = fopen ("newer.file", "w+");

        orig << "This line goes into original.file.\n";

 -->    filebuf buf (later, ios_base::out);
        orig.basic_ios<char>::rdbuf (&buf);

        orig << "And this line, which /would/ have gone into the\n"
             << "original file, goes into the later one instead.\n";
    }

    40% g++ -Wall -W f.cc
    41% ./a.out
    42% ls *file
    newer.file  original.file
    43% cat original.file
    This line goes into original.file.
    44% cat newer.file
    And this line, which /would/ have gone into the
    original file, goes into the later one instead.
    45%

Note the use of the non-standard ctor.  Does this help?

Note also that filebuf member functions tend to behave very strangely
after doing an end-run around the derived rdbuf() like this.  I haven't
tested our implementation lately, but be warned.  The more recent C++ texts
discuss this in some detail; I think Langer & Kreft's text is very good.
I don't have a copy of Josuttis handy, but he probably discusses it also.

The Library Working Group issues list, #194, also brings up this problem
of rdbuf() being hidden.  The issues list is online, too.


> Nor
> do the internal workings of the libstdc++ IO-streams appear to be
> documented interfaces,

Well... yeah.  I don't want to come off as a smartass, but they are
internal workings, not public interfaces.  They will be documented as soon
as somebody volunteers to do so, or pays somebody else who has time to do so.

All we really need are well-written comments, actually, and doxygen will
do the rest.  Got any free time?


> 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.

Yes, the fd() member function seems to be a common extension.


> 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).

Of /course/ fdopen() is implemented.  It's part of the POSIX standard.
Just because one standard doesn't specify an interface doesn't prohibit
another standard from requiring it.  That's not really germane, unless
a newer POSIX requires fdrdbuf() or something.


> 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."

As the author of the wonderful (thank you) quote, let me make some more
things clear:

0)  Nobody is arguing against adding extensions.  But we are trying to
get the library -- the standardized part, mind you -- finished and working
before we start adding cool bits.

1)  Once extensions are in, they are damn hard to get rid of, should they
prove to be a bad idea, or not well thought-out.  The fd() extension,
ironically, is a good example of this.  People have reported bugs with
fd() not working on platforms which don't use integers as "file handles,"
just because they thought it was a standard function.

Personally, since the C++ I/O library talks to the files through a
__basic_file wrapper, I feel we should allow an extension to expose that
member instead.  On "normal" platforms it's a FILE*, which means that
even the results of our extension has well-defined semantics (from the
C standard).  On "unusual" platforms it's whatever handle type has been
ported into the library, and there are no surprises there.

Going straight to file descriptors is a bit gross, since in 3.0 we aren't
even using them directly ourselves anyhow.

2)  I'm accumulating a wish list of GNU extensions to the C++ library.
Allowing access to the "guts" of the OS/filesystem is one of them.
I've already proposed some others, and asked what kind of on/off switch we
should use to permit/deny the extensions, but there wasn't much response
since the 3.0 crunch was upon us.

3)  If you have suggestions, I'd be glad to add a filebuf extension to
expose /something/ to public access.  I'm maintaining a bunch of small
extensions in my local tree, and will check them in as soon as there is
consensus on how we guard such extensions; if you come up with something,
maintaining another isn't a problem.  That's an offer I've made before,
and I reiterate it here.

But fd() is IMO right out:  the library itself isn't even aware of file
descriptors.  How can we pass back something which we don't know exists?

4)  Likewise, constructing a filebuf from a file descriptor is wrong.  Note
how the extra ctor we already have takes a pointer to a __c_file_type, not
a FILE?  That's the wrapper layer.  We shouldn't expose any more than that.


So, if you have a patch which uses __c_file_type or __basic_file or any of
those layers, by all means, send it out.  But not file descriptors directly.
The non-POSIX users would crucify you.  :-)

Phil

-- 
Would I had phrases that are not known, utterances that are strange, in
new language that has not been used, free from repetition, not an utterance
which has grown stale, which men of old have spoken.
                                     - anonymous Egyptian scribe, c.1700 BC


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]