Ich portiere etwas Code nach Darwin OS X und als Teil der Änderung gehen wir von gcc zum clang Compiler.Wie bekomme ich einen Dateideskriptor von einem std :: basic_ios für den Clam unter OS X?
In dem Code gibt es eine Funktion aus dem Jahr 2005 und veröffentlichte mehrere Stellen im Internet. Es bietet Funktionen für mehrere verschiedene alte Versionen von GCC, ich habe alle bis auf die letzte, die es bietet, v3.4.0 oder später bearbeitet. Der Code hängt von zwei GCC-spezifischen Klassen ab: __gnu_cxx::stdio_filebuf
und __gnu_cxx::stdio_sync_filebuf
.
//! Similar to fileno(3), but taking a C++ stream as argument instead of a
//! FILE*. Note that there is no way for the library to track what you do with
//! the descriptor, so be careful.
//! \return The integer file descriptor associated with the stream, or -1 if
//! that stream is invalid. In the latter case, for the sake of keeping the
//! code as similar to fileno(3), errno is set to EBADF.
//! \see The <A HREF="http://www.ginac.de/~kreckel/fileno/">upstream page at
//! http://www.ginac.de/~kreckel/fileno/</A> of this code provides more
//! detailed information.
template <typename charT, typename traits>
inline int
fileno_hack(const std::basic_ios<charT, traits>& stream)
{
// Some C++ runtime libraries shipped with ancient GCC, Sun Pro,
// Sun WS/Forte 5/6, Compaq C++ supported non-standard file descriptor
// access basic_filebuf<>::fd(). Alas, starting from GCC 3.1, the GNU C++
// runtime removes all non-standard std::filebuf methods and provides an
// extension template class __gnu_cxx::stdio_filebuf on all systems where
// that appears to make sense (i.e. at least all Unix systems). Starting
// from GCC 3.4, there is an __gnu_cxx::stdio_sync_filebuf, in addition.
// Sorry, darling, I must get brutal to fetch the darn file descriptor!
// Please complain to your 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
// This applies to cin, cout and cerr when not synced with 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();
}
// This applies to filestreams:
typedef std::basic_filebuf<charT, traits> filebuf_t;
filebuf_t* bbuf = dynamic_cast<filebuf_t*>(stream.rdbuf());
if (bbuf != NULL) {
// This subclass is only there for accessing the 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();
}
// This applies to cin, cout and cerr when synced with 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 anybody know how to fetch the bloody file descriptor?"
return stream.rdbuf()->fd(); // Maybe a good start?
#endif
errno = EBADF;
return -1;
}
Die Frage ist, für Klirren 5.1 auf OS X Mavericks, wäre das, was die Art und Weise den Dateideskriptor für eine std::basic_ios
zu berechnen?
Ich kann Ihnen sagen, dass die C++ Runtime im Einsatz sehr wahrscheinlich ist es, die LLVM-Projekt sein [libC++] (http://libcxx.llvm.org/index.html), und die 'basic_filebuf' Klasse scheint ein stdio' FILE' zu umhüllen, anstatt direkt Dateideskriptoren auf OS-Ebene zu verwenden. Aber ich sehe keine Möglichkeit, die 'FILE' aus dem' filebuf' zu extrahieren oder ein 'filebuf' aus einer bereits geöffneten' FILE' zu erstellen. Vielleicht kann jemand, der klüger ist als ich, einen kennen. – zwol
Hast du es geschafft? Was haben Sie gemacht? – Paulo1205
@ Paulo1205 Das Problem wurde noch nie gelöst, mein Calling-Code behandelt nur "return -1" und "errno == EBADF". – WilliamKF