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>
This commit is contained in:
Giuseppe D'Angelo 2014-09-20 16:49:24 +02:00
parent 8f622fef41
commit bc5a1c6d3f

View File

@ -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;
ret = fclose(fh);
} else {
// Close unbuffered file.
ret = QT_CLOSE(fd);
EINTR_LOOP(ret, QT_CLOSE(fd));
}
} while (ret == -1 && errno == EINTR);
// We must reset these guys regardless; calling close again after a
// failed close causes crashes on some systems.