Mercurial > hg > svcore
comparison data/fileio/BZipFileDevice.cpp @ 1381:ce08318aad83
Fixes to usage of fdopen, avoiding double-close in particular
author | Chris Cannam |
---|---|
date | Tue, 21 Feb 2017 21:08:14 +0000 |
parents | b3cb0edc25cd |
children | f204f2fcb15e |
comparison
equal
deleted
inserted
replaced
1380:bd1eb56df8d5 | 1381:ce08318aad83 |
---|---|
19 | 19 |
20 #include <iostream> | 20 #include <iostream> |
21 | 21 |
22 #include "base/Debug.h" | 22 #include "base/Debug.h" |
23 | 23 |
24 #ifdef _MSC_VER | |
25 #include <io.h> | |
26 #endif | |
27 | |
24 BZipFileDevice::BZipFileDevice(QString fileName) : | 28 BZipFileDevice::BZipFileDevice(QString fileName) : |
25 m_fileName(fileName), | 29 m_fileName(fileName), |
26 m_qfile(fileName), | 30 m_qfile(fileName), |
27 m_file(0), | 31 m_file(0), |
28 m_bzFile(0), | 32 m_bzFile(0), |
69 setErrorString(tr("Read and write modes both specified")); | 73 setErrorString(tr("Read and write modes both specified")); |
70 m_ok = false; | 74 m_ok = false; |
71 return false; | 75 return false; |
72 } | 76 } |
73 | 77 |
78 // This is all going to be a bit silly. | |
79 // | |
80 // We open the file with QFile so as not to have to worry about locale | |
81 // support ourselves (especially on Windows). Then we get a fd from | |
82 // QFile and "convert" it to a FILE* using fdopen because that is what | |
83 // the bz2 library needs for reading and writing an already-open file. | |
84 // | |
85 // fdopen takes over the fd it is given, and will close it when fclose | |
86 // is called. (We must call fclose, because it's needed to avoid | |
87 // leaking the file stream structure.) | |
88 // | |
89 // But QFile will also close its fd, either when we call QFile::close | |
90 // or on destruction -- there doesn't seem to be a way to avoid that | |
91 // for a file that QFile opened. | |
92 // | |
93 // So we have to add an extra dup() in to the fdopen to avoid a double | |
94 // close. | |
95 // | |
96 // Note that bz2 will *not* fclose the FILE* it was passed, so we | |
97 // don't have a problem with calling both bzWriteClose and fclose. | |
98 | |
74 if (mode & WriteOnly) { | 99 if (mode & WriteOnly) { |
75 | 100 |
76 if (!m_qfile.open(QIODevice::WriteOnly)) { | 101 if (!m_qfile.open(QIODevice::WriteOnly)) { |
77 setErrorString(tr("Failed to open file for writing")); | 102 setErrorString(tr("Failed to open file for writing")); |
78 m_ok = false; | 103 m_ok = false; |
79 return false; | 104 return false; |
80 } | 105 } |
81 | 106 |
82 m_file = fdopen(m_qfile.handle(), "wb"); | 107 m_file = fdopen(dup(m_qfile.handle()), "wb"); |
83 if (!m_file) { | 108 if (!m_file) { |
84 setErrorString(tr("Failed to open file handle for writing")); | 109 setErrorString(tr("Failed to open file handle for writing")); |
85 m_qfile.close(); | 110 m_qfile.close(); |
86 m_ok = false; | 111 m_ok = false; |
87 return false; | 112 return false; |
112 setErrorString(tr("Failed to open file for reading")); | 137 setErrorString(tr("Failed to open file for reading")); |
113 m_ok = false; | 138 m_ok = false; |
114 return false; | 139 return false; |
115 } | 140 } |
116 | 141 |
117 m_file = fdopen(m_qfile.handle(), "rb"); | 142 m_file = fdopen(dup(m_qfile.handle()), "rb"); |
118 if (!m_file) { | 143 if (!m_file) { |
119 setErrorString(tr("Failed to open file handle for reading")); | 144 setErrorString(tr("Failed to open file handle for reading")); |
120 m_ok = false; | 145 m_ok = false; |
121 return false; | 146 return false; |
122 } | 147 } |
160 | 185 |
161 if (openMode() & WriteOnly) { | 186 if (openMode() & WriteOnly) { |
162 unsigned int in = 0, out = 0; | 187 unsigned int in = 0, out = 0; |
163 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); | 188 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); |
164 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; | 189 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; |
165 if (bzError != BZ_OK) { | 190 if (bzError != BZ_OK) { |
166 setErrorString(tr("bzip2 stream write close error")); | 191 setErrorString(tr("bzip2 stream write close error")); |
167 } | 192 } |
168 fclose(m_file); | 193 fclose(m_file); |
169 m_qfile.close(); | 194 m_qfile.close(); |
170 m_bzFile = 0; | 195 m_bzFile = 0; |
171 m_file = 0; | 196 m_file = 0; |
172 m_ok = false; | 197 m_ok = false; |