c++ - How to get a file descriptor from a std::basic_ios for clang on OS X? -


i'm porting code darwin os x , part of change, go gcc clang compiler.

in code, there function dating 2005 , posted several places on internet. provides functionality several different old versions of gcc, i've edited out last offers, v3.4.0 or later. code depends upon 2 gcc specific classes: __gnu_cxx::stdio_filebuf , __gnu_cxx::stdio_sync_filebuf.

//! similar fileno(3), taking c++ stream argument instead of //! file*.  note there no way library track //! descriptor, careful. //! \return  integer file descriptor associated stream, or -1 if //!   stream invalid.  in latter case, sake of keeping //!   code similar fileno(3), errno set ebadf. //! \see  <a href="http://www.ginac.de/~kreckel/fileno/">upstream page @ //!   http://www.ginac.de/~kreckel/fileno/</a> of code provides more //!   detailed information. template <typename chart, typename traits> inline int fileno_hack(const std::basic_ios<chart, traits>& stream) {   // c++ runtime libraries shipped ancient gcc, sun pro,   // sun ws/forte 5/6, compaq c++ supported non-standard file descriptor   // access basic_filebuf<>::fd().  alas, starting gcc 3.1, gnu c++   // runtime removes non-standard std::filebuf methods , provides   // extension template class __gnu_cxx::stdio_filebuf on systems   // appears make sense (i.e. @ least unix systems).  starting   // gcc 3.4, there __gnu_cxx::stdio_sync_filebuf, in addition.   // sorry, darling, must brutal fetch darn file descriptor!   // please complain compiler/libstdc++ vendor... #if defined(__glibcxx__) || defined(__glibcpp__)   // ok, stop reading here, because it's getting obscene.  cross fingers! # if defined(__glibcxx__)  // >= gcc 3.4.0   // applies cin, cout , cerr when not synced stdio:   typedef __gnu_cxx::stdio_filebuf<chart, traits> unix_filebuf_t;   unix_filebuf_t* fbuf = dynamic_cast<unix_filebuf_t*>(stream.rdbuf());   if (fbuf != null) {     return fbuf->fd();   }    // applies filestreams:   typedef std::basic_filebuf<chart, traits> filebuf_t;   filebuf_t* bbuf = dynamic_cast<filebuf_t*>(stream.rdbuf());   if (bbuf != null) {     // subclass there accessing file*.  ouuwww, sucks!     struct my_filebuf : public std::basic_filebuf<chart, traits> {       int fd() { return this->_m_file.fd(); }     };     return static_cast<my_filebuf*>(bbuf)->fd();   }    // applies cin, cout , cerr when synced stdio:   typedef __gnu_cxx::stdio_sync_filebuf<chart, traits> sync_filebuf_t;   sync_filebuf_t* sbuf = dynamic_cast<sync_filebuf_t*>(stream.rdbuf());   if (sbuf != null) {     return fileno(sbuf->file());   } # endif #else #  error "does know how fetch bloody file descriptor?"   return stream.rdbuf()->fd();  // maybe start? #endif    errno = ebadf;   return -1; } 

the question is, clang 5.1 on os x mavericks, way computed file descriptor std::basic_ios?

if don't mind getting hands dirty poking round in private implementation details following code works:

#include <iostream> #include <fstream>  // generate static data member of type tag::type in store // address of private member. crucial tag not // depend on /value/ of the stored address in way // can access ordinary code without directly touching // private data. template < class tag > struct stowed {   static typename tag::type value; };  template < class tag > typename tag::type stowed< tag >::value;  // generate static data member constructor initializes // stowed< tag >::value. type named in explicit // instantiation, legal pass address of private // member. template < class tag, typename tag::type x > struct stow_private {   stow_private() { stowed< tag >::value = x; }   static stow_private instance; }; template < class tag, typename tag::type x > stow_private< tag, x > stow_private< tag, x >::instance;  struct filebuf_file { typedef file*( std::filebuf::*type ); }; template struct stow_private< filebuf_file, &std::filebuf::__file_ >;  file* c_file( std::filebuf& fb ) {   return fb.*stowed< filebuf_file >::value; }  int main(int argc, const char * argv[]) {   std::ofstream fs("test.txt");   file* file = c_file(*fs.rdbuf());   std::cout << file->_file << "\n";   return 0; } 

Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -