# HG changeset patch # User Chris Cannam # Date 1487711294 0 # Node ID ce08318aad83e4be3b6f2898f87cca2d9aaabdb8 # Parent bd1eb56df8d5a7d9d66eaeeb9be485ee9a4876db Fixes to usage of fdopen, avoiding double-close in particular diff -r bd1eb56df8d5 -r ce08318aad83 data/fileio/BZipFileDevice.cpp --- a/data/fileio/BZipFileDevice.cpp Tue Feb 21 21:07:54 2017 +0000 +++ b/data/fileio/BZipFileDevice.cpp Tue Feb 21 21:08:14 2017 +0000 @@ -21,6 +21,10 @@ #include "base/Debug.h" +#ifdef _MSC_VER +#include +#endif + BZipFileDevice::BZipFileDevice(QString fileName) : m_fileName(fileName), m_qfile(fileName), @@ -71,6 +75,27 @@ return false; } + // This is all going to be a bit silly. + // + // We open the file with QFile so as not to have to worry about locale + // support ourselves (especially on Windows). Then we get a fd from + // QFile and "convert" it to a FILE* using fdopen because that is what + // the bz2 library needs for reading and writing an already-open file. + // + // fdopen takes over the fd it is given, and will close it when fclose + // is called. (We must call fclose, because it's needed to avoid + // leaking the file stream structure.) + // + // But QFile will also close its fd, either when we call QFile::close + // or on destruction -- there doesn't seem to be a way to avoid that + // for a file that QFile opened. + // + // So we have to add an extra dup() in to the fdopen to avoid a double + // close. + // + // Note that bz2 will *not* fclose the FILE* it was passed, so we + // don't have a problem with calling both bzWriteClose and fclose. + if (mode & WriteOnly) { if (!m_qfile.open(QIODevice::WriteOnly)) { @@ -79,7 +104,7 @@ return false; } - m_file = fdopen(m_qfile.handle(), "wb"); + m_file = fdopen(dup(m_qfile.handle()), "wb"); if (!m_file) { setErrorString(tr("Failed to open file handle for writing")); m_qfile.close(); @@ -114,7 +139,7 @@ return false; } - m_file = fdopen(m_qfile.handle(), "rb"); + m_file = fdopen(dup(m_qfile.handle()), "rb"); if (!m_file) { setErrorString(tr("Failed to open file handle for reading")); m_ok = false; @@ -162,9 +187,9 @@ unsigned int in = 0, out = 0; BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; - if (bzError != BZ_OK) { - setErrorString(tr("bzip2 stream write close error")); - } + if (bzError != BZ_OK) { + setErrorString(tr("bzip2 stream write close error")); + } fclose(m_file); m_qfile.close(); m_bzFile = 0; diff -r bd1eb56df8d5 -r ce08318aad83 data/fileio/OggVorbisFileReader.cpp --- a/data/fileio/OggVorbisFileReader.cpp Tue Feb 21 21:07:54 2017 +0000 +++ b/data/fileio/OggVorbisFileReader.cpp Tue Feb 21 21:08:14 2017 +0000 @@ -78,7 +78,7 @@ m_fileSize = m_qfile->size(); - m_ffile = fdopen(dup(m_qfile->handle()), "r"); + m_ffile = fdopen(dup(m_qfile->handle()), "rb"); if (!m_ffile) { m_error = QString("Failed to open file pointer for file %1").arg(m_path); SVDEBUG << "OggVorbisFileReader: " << m_error << endl;