holub@violet.berkeley.edu (Allen Holub) (05/16/91)
Is there an official way to convert from an ostream either to a FILE pointer or file descriptor? I need to use a few C routines that take file-descriptor arguments in a stream-based C++ application compiled under Borland C++ 2.0.
steve@taumet.com (Stephen Clamage) (05/17/91)
holub@violet.berkeley.edu (Allen Holub) writes: >Is there an official way to convert from an ostream either to a FILE pointer >or file descriptor? I need to use a few C routines that take file-descriptor >arguments in a stream-based C++ application compiled under Borland C++ 2.0. You don't say whether you are using AT&T version 1.2-style (old) streams or version 2.x-style (new) iostreams. Old-style streams were built on C Standard I/O, and you can just pick up the FILE pointer. New-style iostreams do not use C Standard I/O at all (except for stdiostream, which is recommended against). So there is no FILE pointer available. Beyond that, an ostream is not necessarily file-based. It uses a streambuf-derived class for its output, and this streambuf-derived class might be a filebuf (using a file), a strstreambuf (using a char array), or some user-defined class. So there is no guarantee that an ostream will have a file associated with it. In the event that an ostream-derived class uses a filebuf (as do cout and cerr), you can use the public member function ios::rdbuf() to get the associated streambuf, then invoke public member function fd() to get the file descriptor. Of course, fd() is not a member of streambuf, but of filebuf, so you need a cast, which is not safe unless you know you are dealing with a filebuf-derived buffer class. Example: #include <fstream.h> main() { cout << "fd for cout is " << ((filebuf*)cout.rdbuf())->fd() // UNSAFE CAST << endl; return 0; } This makes sense on systems which have the Unix-like concept of small integers representing a file as known to the operating system. (DOS is such a system.) -- Steve Clamage, TauMetric Corp, steve@taumet.com
sking@nowhere.uucp (Steven King) (05/17/91)
In article <732@taumet.com> steve@taumet.com (Stephen Clamage) writes: >holub@violet.berkeley.edu (Allen Holub) writes: > >>Is there an official way to convert from an ostream either to a FILE pointer >>or file descriptor? I need to use a few C routines that take file-descriptor >>arguments in a stream-based C++ application compiled under Borland C++ 2.0. > >In the event that an ostream-derived class uses a filebuf (as do >cout and cerr), you can use the public member function ios::rdbuf() >to get the associated streambuf, then invoke public member function >fd() to get the file descriptor. Of course, fd() is not a member >of streambuf, but of filebuf, so you need a cast, which is not >safe unless you know you are dealing with a filebuf-derived >buffer class. Example: > > #include <fstream.h> > main() > { > cout << "fd for cout is " > << ((filebuf*)cout.rdbuf())->fd() // UNSAFE CAST > << endl; > return 0; > } > A few minor quibbles... The library distributed with cfront 2.0 has cin & cout instances of istream_withassign and ostream_withassign, repectively, and neither is defined as derived from filebuf or have a filebuf as member. ( I presume that the actual initialization of cin, etc. uses a filebuf ) Objects derived from fstreambase ( ie. ofstream and ifstream ) have the member function rdbuf() which returns a pointer to a filebuf, rendering the cast unnecessary, ie: ifstream ins ; int fd = ins.rdbuf() -> fd() ; -- If it don't stick, stink, or sting It ain't from Texas. ..!cs.utexas.edu!ut-emx!nowhere!sking