summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2014-09-20 16:49:24 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2014-09-22 18:57:18 +0200
commitbc5a1c6d3fc36d9d48c719895c2061e052ead17e (patch)
tree0da5599b8e458aa1faf2de81948522346f09101d /src
parent8f622fef415cacb50f826268282a276502dcc607 (diff)
QFile: fix undefined behavior when closing a buffered file
C11 ยง7.21.3.4 [Files] says that The value of a pointer to a FILE object is indeterminate after the associated file is closed POSIX.1-2013 reinforces by saying that After the call to fclose(), any use of stream results in undefined behavior. This means we can't call fclose() again on a FILE *, even if fclose() returned EOF and set errno to EINTR. Change-Id: I282f4ff926e3c134729defa290c80d42431e97ce Reviewed-by: Marc Mutz <marc.mutz@kdab.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfsfileengine.cpp22
1 files changed, 9 insertions, 13 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 1ae182a4c1..e198cd6d75 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -168,10 +168,7 @@ QFSFileEngine::~QFSFileEngine()
Q_D(QFSFileEngine);
if (d->closeFileHandle) {
if (d->fh) {
- int ret;
- do {
- ret = fclose(d->fh);
- } while (ret == EOF && errno == EINTR);
+ fclose(d->fh);
} else if (d->fd != -1) {
int ret;
do {
@@ -375,15 +372,14 @@ bool QFSFileEnginePrivate::closeFdFh()
// Close the file if we created the handle.
if (closeFileHandle) {
int ret;
- do {
- if (fh) {
- // Close buffered file.
- ret = fclose(fh) != 0 ? -1 : 0;
- } else {
- // Close unbuffered file.
- ret = QT_CLOSE(fd);
- }
- } while (ret == -1 && errno == EINTR);
+
+ if (fh) {
+ // Close buffered file.
+ ret = fclose(fh);
+ } else {
+ // Close unbuffered file.
+ EINTR_LOOP(ret, QT_CLOSE(fd));
+ }
// We must reset these guys regardless; calling close again after a
// failed close causes crashes on some systems.