From 612f5cf9a1c708a18d6488f2b25d85716a899d99 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 31 May 2022 12:07:43 -0700 Subject: QTemporaryFile: document rename() differences from QFile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will not do a copy+delete if the destination is on another mount point (in fact, QFile uses QTemporaryFile for the latter). In my opinion, that's a misfeature in QFile, because such an operation may need to display a progress bar to the user so they won't think the application has frozen. But it's too late to change now. I don't know why QTemporaryFile is different. It might be because it was used for the atomic materialization of a file before QSaveFile existed (5.1) but I didn't research to confirm. It's still useful even in the presence of that class if the file is really temporary (meant to be removed when the QTemporaryFile is destroyed). Pick-to: 5.15 6.2 6.3 Fixes: QTBUG-103740 Change-Id: Iba16e8ea451b444ab213fffd16f4461f3f972d8c Reviewed-by: MÃ¥rten Nordheim --- src/corelib/io/qtemporaryfile.cpp | 40 +++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index a0238eeeb8..44c45a1cad 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -586,6 +586,9 @@ QString QTemporaryFilePrivate::defaultTemplateName() be placed into the temporary path as returned by QDir::tempPath(). If you specify your own filename, a relative file path will not be placed in the temporary directory by default, but be relative to the current working directory. + It is important to specify the correct directory if the rename() function will be + called, as QTemporaryFile can only rename files within the same volume / filesystem + as the temporary file itself was created on. Specified filenames can contain the following template \c XXXXXX (six upper case "X" characters), which will be replaced by the @@ -637,7 +640,11 @@ QTemporaryFile::QTemporaryFile() If \a templateName is a relative path, the path will be relative to the current working directory. You can use QDir::tempPath() to construct \a - templateName if you want use the system's temporary directory. + templateName if you want use the system's temporary directory. It is + important to specify the correct directory if the rename() function will be + called, as QTemporaryFile can only rename files within the same volume / + filesystem as the temporary file itself was created on. + \sa open(), fileTemplate() */ @@ -670,7 +677,10 @@ QTemporaryFile::QTemporaryFile(QObject *parent) If \a templateName is a relative path, the path will be relative to the current working directory. You can use QDir::tempPath() to construct \a - templateName if you want use the system's temporary directory. + templateName if you want use the system's temporary directory. It is + important to specify the correct directory if the rename() function will be + called, as QTemporaryFile can only rename files within the same volume / + filesystem as the temporary file itself was created on. \sa open(), fileTemplate() */ @@ -789,7 +799,10 @@ QString QTemporaryFile::fileTemplate() const If \a name contains a relative file path, the path will be relative to the current working directory. You can use QDir::tempPath() to construct \a - name if you want use the system's temporary directory. + name if you want use the system's temporary directory. It is important to + specify the correct directory if the rename() function will be called, as + QTemporaryFile can only rename files within the same volume / filesystem as + the temporary file itself was created on. \sa fileTemplate() */ @@ -800,11 +813,22 @@ void QTemporaryFile::setFileTemplate(const QString &name) } /*! - \internal - - This is just a simplified version of QFile::rename() because we know a few - extra details about what kind of file we have. The documentation is hidden - from the user because QFile::rename() should be enough. + Renames the current temporary file to \a newName and returns true if it + succeeded. + + This function has an important difference compared to QFile::rename(): it + will not perform a copy+delete if the low-level system call to rename the + file fails, something that could happen if \a newName specifies a file in a + different volume or filesystem than the temporary file was created on. In + other words, QTemporaryFile only supports atomic file renaming. + + This functionality is intended to support materializing the destination + file with all contents already present, so another process cannot see an + incomplete file in the process of being written. The \l QSaveFile class can + be used for a similar purpose too, particularly if the destination file is + not temporary. + + \sa QSaveFile, QSaveFile::commit(), QFile::rename() */ bool QTemporaryFile::rename(const QString &newName) { -- cgit v1.2.3