Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From a7635e243c06fe5ffc5ce37caf77c994a2eadeeb Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Wed, 10 Nov 2010 11:32:19 +0100
- Subject: [PATCH 1/6] Removing dead code in QTemporaryFile
- The option to create a directory is never used, so let's drop it. There
- are bigger issues with this code.
- Reviewed-by: ? pending
- ---
- src/corelib/io/qtemporaryfile.cpp | 22 ++++------------------
- 1 files changed, 4 insertions(+), 18 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index c34c4a4..f4011ee 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- -static int _gettemp(char *path, int *doopen, int domkdir, int slen)
- +static int _gettemp(char *path, int *doopen, int slen)
- {
- char *start, *trv, *suffp;
- QT_STATBUF sbuf;
- @@ -120,11 +120,6 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
- pid_t pid;
- #endif
- - if (doopen && domkdir) {
- - errno = EINVAL;
- - return 0;
- - }
- -
- for (trv = path; *trv; ++trv)
- ;
- trv -= slen;
- @@ -167,7 +162,7 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
- */
- - if (doopen || domkdir) {
- + if (doopen) {
- for (;; --trv) {
- if (trv <= path)
- break;
- @@ -235,15 +230,6 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
- }
- if (errno != EEXIST)
- return 0;
- - } else if (domkdir) {
- -#ifdef Q_OS_WIN
- - if (QT_MKDIR(path) == 0)
- -#else
- - if (QT_MKDIR(path, 0700) == 0)
- -#endif
- - return 1;
- - if (errno != EEXIST)
- - return 0;
- }
- #ifndef Q_OS_WIN
- else if (QT_LSTAT(path, &sbuf))
- @@ -282,7 +268,7 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
- static int qt_mkstemps(char *path, int slen)
- {
- int fd = 0;
- - return (_gettemp(path, &fd, 0, slen) ? fd : -1);
- + return (_gettemp(path, &fd, slen) ? fd : -1);
- }
- #endif
- @@ -390,7 +376,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- return false;
- #else
- - if (!_gettemp(filename, 0, 0, suffixLength)) {
- + if (!_gettemp(filename, 0, suffixLength)) {
- delete [] filename;
- return false;
- }
- --
- 1.7.3
- From eb55171fb58f7dbbfc8fba99ec137cc5f270b997 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Wed, 10 Nov 2010 18:09:56 +0100
- Subject: [PATCH 2/6] tst_QCompleter: Clean up after one's self
- The utility class FileSystem uses the RAII idiom to clean up directories
- created for the purpose of the test.
- Reviewed-by: ? pending
- ---
- tests/auto/qcompleter/tst_qcompleter.cpp | 31 ++++++++++-------------------
- 1 files changed, 11 insertions(+), 20 deletions(-)
- diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp
- index 650c328..fe71d68 100644
- --- a/tests/auto/qcompleter/tst_qcompleter.cpp
- +++ b/tests/auto/qcompleter/tst_qcompleter.cpp
- @@ -49,6 +49,7 @@
- #include <QPointer>
- #include "../../shared/util.h"
- +#include "../../shared/filesystem.h"
- //TESTED_CLASS=
- //TESTED_FILES=
- @@ -1455,29 +1456,19 @@ void tst_QCompleter::task247560_keyboardNavigation()
- void tst_QCompleter::QTBUG_14292_filesystem()
- {
- - QDir tmpDir = QDir::temp();
- + FileSystem fs;
- +
- qsrand(QTime::currentTime().msec());
- QString d = "tst_QCompleter_" + QString::number(qrand());
- - QVERIFY(tmpDir.mkdir(d));
- -
- -#if 0
- - struct Cleanup {
- - QString dir;
- - ~Cleanup() {
- - qDebug() << dir <<
- - QFile::remove(dir); }
- - } cleanup;
- - cleanup.dir = tmpDir.absolutePath()+"/" +d;
- -#endif
- + QVERIFY(fs.createDirectory(d));
- - QVERIFY(tmpDir.cd(d));
- - QVERIFY(tmpDir.mkdir("hello"));
- - QVERIFY(tmpDir.mkdir("holla"));
- + QVERIFY(fs.createDirectory(d + "/hello"));
- + QVERIFY(fs.createDirectory(d + "/holla"));
- QLineEdit edit;
- QCompleter comp;
- QFileSystemModel model;
- - model.setRootPath(tmpDir.path());
- + model.setRootPath("./");
- comp.setModel(&model);
- edit.setCompleter(&comp);
- @@ -1489,7 +1480,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
- QTRY_VERIFY(edit.hasFocus());
- QVERIFY(!comp.popup()->isVisible());
- - edit.setText(tmpDir.path());
- + edit.setText(d);
- QTest::keyClick(&edit, '/');
- QTRY_VERIFY(comp.popup()->isVisible());
- QCOMPARE(comp.popup()->model()->rowCount(), 2);
- @@ -1500,12 +1491,12 @@ void tst_QCompleter::QTBUG_14292_filesystem()
- QCOMPARE(comp.popup()->model()->rowCount(), 1);
- QTest::keyClick(&edit, 'r');
- QTRY_VERIFY(!comp.popup()->isVisible());
- - QVERIFY(tmpDir.mkdir("hero"));
- + QVERIFY(fs.createDirectory(d + "/hero"));
- QTRY_VERIFY(comp.popup()->isVisible());
- QCOMPARE(comp.popup()->model()->rowCount(), 1);
- QTest::keyClick(comp.popup(), Qt::Key_Escape);
- QTRY_VERIFY(!comp.popup()->isVisible());
- - QVERIFY(tmpDir.mkdir("nothingThere"));
- + QVERIFY(fs.createDirectory(d + "/nothingThere"));
- //there is no reason creating a file should open a popup, it did in Qt 4.7.0
- QTest::qWait(60);
- QVERIFY(!comp.popup()->isVisible());
- @@ -1522,7 +1513,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
- QTest::qWaitForWindowShown(&w);
- QTRY_VERIFY(!edit.hasFocus() && !comp.popup()->hasFocus());
- - QVERIFY(tmpDir.mkdir("hemo"));
- + QVERIFY(fs.createDirectory(d + "/hemo"));
- //there is no reason creating a file should open a popup, it did in Qt 4.7.0
- QTest::qWait(60);
- QVERIFY(!comp.popup()->isVisible());
- --
- 1.7.3
- From 78ed775c1d93f5bbc1deb1c62a4193ae7a014c4e Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Wed, 10 Nov 2010 18:12:13 +0100
- Subject: [PATCH 3/6] QTemporaryFile: use GetCurrentProcessId instead of getpid on Windows
- getpid is deprecated on Windows since VS 2005. Then again, there's no
- reason to use a POSIX function here at all. GetCurrentProcessId, on the
- other hand, is part of the Windows API and has been available since
- Windows 2000.
- Reviewed-by: ? pending
- ---
- src/corelib/io/qtemporaryfile.cpp | 6 +++---
- 1 files changed, 3 insertions(+), 3 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index f4011ee..fd4f96b 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -115,7 +115,7 @@ static int _gettemp(char *path, int *doopen, int slen)
- QT_STATBUF sbuf;
- int rval;
- #if defined(Q_OS_WIN)
- - int pid;
- + DWORD pid;
- #else
- pid_t pid;
- #endif
- @@ -129,8 +129,8 @@ static int _gettemp(char *path, int *doopen, int slen)
- errno = EINVAL;
- return 0;
- }
- -#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
- - pid = _getpid();
- +#if defined(Q_OS_WIN)
- + pid = ::GetCurrentThreadId();
- #elif defined(Q_OS_VXWORKS)
- pid = (pid_t) taskIdCurrent;
- #else
- --
- 1.7.3
- From bff52a075d52da4571b9a2da662abf98eb5e9b4a Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Thu, 11 Nov 2010 15:22:49 +0100
- Subject: [PATCH 4/6] QTemporaryFile: More dead code elimination
- There are exactly 2 uses of the _gettemp function: one for windows
- platforms, one for all others. Windows requests a file name, others
- request a valid file descriptor for that file name.
- Despite the 2 distinct use cases, the code was full of #ifdefs to keep
- never used code paths compiling.
- With this change the qt_mkstemp wrapper is eliminated, together with
- dead code inside if (doopen) {} blocks on Windows platforms. The more
- proper Q_OS_WIN macro is preferred to Q_WS_WIN.
- _gettemp is also changed to return the valid file descriptor on
- non-Windows platforms.
- Reviewed-by: ? pending
- ---
- src/corelib/io/qtemporaryfile.cpp | 110 ++++++++++---------------------------
- 1 files changed, 29 insertions(+), 81 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index fd4f96b..a17566c 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- -static int _gettemp(char *path, int *doopen, int slen)
- +static int _gettemp(char *path, int slen)
- {
- char *start, *trv, *suffp;
- QT_STATBUF sbuf;
- @@ -127,7 +127,7 @@ static int _gettemp(char *path, int *doopen, int slen)
- --trv;
- if (trv < path) {
- errno = EINVAL;
- - return 0;
- + return -1;
- }
- #if defined(Q_OS_WIN)
- pid = ::GetCurrentThreadId();
- @@ -158,82 +158,38 @@ static int _gettemp(char *path, int *doopen, int slen)
- }
- start = trv + 1;
- +#ifndef Q_OS_WIN
- /*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
- */
- - if (doopen) {
- - for (;; --trv) {
- - if (trv <= path)
- - break;
- - if (*trv == '/') {
- - *trv = '\0';
- -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
- - if (trv - path == 2 && path[1] == ':') {
- - // Special case for Windows drives
- - // (e.g., "C:" => "C:\").
- - // ### Better to use a Windows
- - // call for this.
- - char drive[] = "c:\\";
- - drive[0] = path[0];
- - rval = QT_STAT(drive, &sbuf);
- - } else
- -#endif
- - rval = QT_STAT(path, &sbuf);
- - *trv = '/';
- - if (rval != 0)
- - return 0;
- - if (!S_ISDIR(sbuf.st_mode)) {
- - errno = ENOTDIR;
- - return 0;
- - }
- - break;
- + for (;; --trv) {
- + if (trv <= path)
- + break;
- + if (*trv == '/') {
- + *trv = '\0';
- + rval = QT_STAT(path, &sbuf);
- + *trv = '/';
- + if (rval != 0)
- + return -1;
- + if (!S_ISDIR(sbuf.st_mode)) {
- + errno = ENOTDIR;
- + return -1;
- }
- + break;
- }
- }
- +#endif
- for (;;) {
- - if (doopen) {
- -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
- - if (_sopen_s(doopen, path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR|QT_OPEN_BINARY
- -# ifdef QT_LARGEFILE_SUPPORT
- - |QT_OPEN_LARGEFILE
- -# endif
- - , _SH_DENYNO, _S_IREAD | _S_IWRITE)== 0)
- -#else // WIN && !CE
- -# if defined(Q_OS_WINCE)
- - QString targetPath;
- - if (QDir::isAbsolutePath(QString::fromLatin1(path)))
- - targetPath = QLatin1String(path);
- - else
- - targetPath = QDir::currentPath().append(QLatin1Char('/')) + QLatin1String(path);
- -
- - if ((*doopen =
- - QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR
- -# else // CE
- - // this is Unix or older MSVC
- - if ((*doopen =
- - QT_OPEN(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR
- -# endif
- -# ifdef QT_LARGEFILE_SUPPORT
- - |QT_OPEN_LARGEFILE
- -# endif
- -# if defined(Q_OS_WINCE)
- - |_O_BINARY
- -# elif defined(Q_OS_WIN)
- - |O_BINARY
- -# endif
- - , 0600)) >= 0)
- -#endif // WIN && !CE
- - {
- - return 1;
- - }
- +#ifndef Q_OS_WIN
- + {
- + int fd = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
- + if (fd != -1)
- + return fd;
- if (errno != EEXIST)
- - return 0;
- + return -1;
- }
- -#ifndef Q_OS_WIN
- - else if (QT_LSTAT(path, &sbuf))
- - return (errno == ENOENT) ? 1 : 0;
- #else
- if (!QFileInfo(QLatin1String(path)).exists())
- return 1;
- @@ -242,10 +198,10 @@ static int _gettemp(char *path, int *doopen, int slen)
- /* tricky little algorwwithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- - return 0;
- + return -1;
- if (*trv == 'Z') {
- if (trv == suffp)
- - return 0;
- + return -1;
- *trv++ = 'a';
- } else {
- if (isdigit(*trv))
- @@ -254,7 +210,7 @@ static int _gettemp(char *path, int *doopen, int slen)
- *trv = 'A';
- else {
- if (trv == suffp)
- - return 0;
- + return -1;
- ++*trv;
- }
- break;
- @@ -264,14 +220,6 @@ static int _gettemp(char *path, int *doopen, int slen)
- /*NOTREACHED*/
- }
- -#ifndef Q_WS_WIN
- -static int qt_mkstemps(char *path, int slen)
- -{
- - int fd = 0;
- - return (_gettemp(path, &fd, slen) ? fd : -1);
- -}
- -#endif
- -
- //************* QTemporaryFileEngine
- class QTemporaryFileEngine : public QFSFileEngine
- {
- @@ -352,8 +300,8 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- int suffixLength = qfilename.length() - (qfilename.lastIndexOf(QLatin1String("XXXXXX"), -1, Qt::CaseSensitive) + 6);
- char *filename = qstrdup(qfilename.toLocal8Bit());
- -#ifndef Q_WS_WIN
- - int fd = qt_mkstemps(filename, suffixLength);
- +#ifndef Q_OS_WIN
- + int fd = _gettemp(filename, suffixLength);
- if (fd != -1) {
- // First open the fd as an external file descriptor to
- // initialize the engine properly.
- @@ -376,7 +324,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- return false;
- #else
- - if (!_gettemp(filename, 0, suffixLength)) {
- + if (_gettemp(filename, suffixLength) == -1) {
- delete [] filename;
- return false;
- }
- --
- 1.7.3
- From a5a84a1aeeb97de6b7a159cf5b73d3c0af995857 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Mon, 15 Nov 2010 13:47:43 +0100
- Subject: [PATCH 5/6] QTemporaryFile: use QCoreApplication::applicationPid
- ... instead of repeating #ifdef's here.
- Reviewed-by: ? pending
- ---
- src/corelib/io/qtemporaryfile.cpp | 16 ++++------------
- 1 files changed, 4 insertions(+), 12 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index a17566c..9d028fa 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -44,6 +44,7 @@
- #ifndef QT_NO_TEMPORARYFILE
- #include "qplatformdefs.h"
- +#include "qcoreapplication.h"
- #include "qabstractfileengine.h"
- #include "private/qfile_p.h"
- #include "private/qabstractfileengine_p.h"
- @@ -114,11 +115,6 @@ static int _gettemp(char *path, int slen)
- char *start, *trv, *suffp;
- QT_STATBUF sbuf;
- int rval;
- -#if defined(Q_OS_WIN)
- - DWORD pid;
- -#else
- - pid_t pid;
- -#endif
- for (trv = path; *trv; ++trv)
- ;
- @@ -129,13 +125,9 @@ static int _gettemp(char *path, int slen)
- errno = EINVAL;
- return -1;
- }
- -#if defined(Q_OS_WIN)
- - pid = ::GetCurrentThreadId();
- -#elif defined(Q_OS_VXWORKS)
- - pid = (pid_t) taskIdCurrent;
- -#else
- - pid = getpid();
- -#endif
- +
- + qint64 pid = QCoreApplication::applicationPid();
- +
- while (trv >= path && *trv == 'X' && pid != 0) {
- *trv-- = (pid % 10) + '0';
- pid /= 10;
- --
- 1.7.3
- From 69cef964a5df5d5f95970bd0d2a39c37262451d7 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 19 Nov 2010 14:27:45 +0100
- Subject: [PATCH 6/6] QTemporaryFile: work in progress
- Reviewed-by: ! Not up for review !
- ---
- src/corelib/io/qtemporaryfile.cpp | 250 +++++++++++-----------
- tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp | 101 +++++++++-
- 2 files changed, 224 insertions(+), 127 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 9d028fa..b567287 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -82,6 +82,16 @@
- QT_BEGIN_NAMESPACE
- +#ifdef Q_OS_WIN
- +typedef QChar Char;
- +typedef QLatin1Char Latin1Char;
- +typedef HANDLE FileDescriptor;
- +#else
- +typedef char Char;
- +typedef char Latin1Char;
- +typedef int FileDescriptor;
- +#endif
- +
- /*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- @@ -110,103 +120,74 @@ QT_BEGIN_NAMESPACE
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- -static int _gettemp(char *path, int slen)
- +static FileDescriptor _gettemp(Char *const path, int placeholderPosition, int placeholderLength)
- {
- - char *start, *trv, *suffp;
- - QT_STATBUF sbuf;
- - int rval;
- -
- - for (trv = path; *trv; ++trv)
- - ;
- - trv -= slen;
- - suffp = trv;
- - --trv;
- - if (trv < path) {
- - errno = EINVAL;
- - return -1;
- - }
- -
- - qint64 pid = QCoreApplication::applicationPid();
- + Q_ASSERT(path);
- + Q_ASSERT(placeholderPosition >= 0);
- + Q_ASSERT(placeholderLength > 0);
- - while (trv >= path && *trv == 'X' && pid != 0) {
- - *trv-- = (pid % 10) + '0';
- - pid /= 10;
- - }
- -
- -#ifndef S_ISDIR
- -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
- -#endif
- -
- - while (trv >= path && *trv == 'X') {
- - char c;
- -
- - // CHANGE arc4random() -> random()
- - pid = (qrand() & 0xffff) % (26+26);
- - if (pid < 26)
- - c = pid + 'A';
- - else
- - c = (pid - 26) + 'a';
- - *trv-- = c;
- - }
- - start = trv + 1;
- + Char *const placeholderStart = path + placeholderPosition;
- + Char *const placeholderEnd = placeholderStart + placeholderLength;
- -#ifndef Q_OS_WIN
- - /*
- - * check the target directory; if you have six X's and it
- - * doesn't exist this runs for a *very* long time.
- - */
- - for (;; --trv) {
- - if (trv <= path)
- - break;
- - if (*trv == '/') {
- - *trv = '\0';
- - rval = QT_STAT(path, &sbuf);
- - *trv = '/';
- - if (rval != 0)
- - return -1;
- - if (!S_ISDIR(sbuf.st_mode)) {
- - errno = ENOTDIR;
- - return -1;
- - }
- - break;
- + {
- + static const qint64 constPid = QCoreApplication::applicationPid();
- + qint64 pid = constPid;
- +
- + Char *rIter = placeholderEnd;
- + do {
- + *--rIter = Latin1Char((pid % 10) + '0');
- + pid /= 10;
- + } while (rIter != placeholderStart && pid != 0);
- +
- + while (rIter != placeholderStart) {
- + int r = (qrand() & 0xffff) % (26 + 26);
- + if (r < 26)
- + *--rIter = Latin1Char(r + 'A');
- + else
- + *--rIter = Latin1Char(r - 26 + 'a');
- }
- }
- -#endif
- - for (;;) {
- + forever {
- #ifndef Q_OS_WIN
- - {
- - int fd = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
- - if (fd != -1)
- - return fd;
- - if (errno != EEXIST)
- - return -1;
- - }
- + int file = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
- + if (file != -1
- + || errno != EEXIST)
- + return file;
- #else
- - if (!QFileInfo(QLatin1String(path)).exists())
- - return 1;
- + HANDLE file = CreateFile((const wchar_t *)path,
- + GENERIC_READ | GENERIC_WRITE,
- + FILE_SHARE_READ | FILE_SHARE_WRITE,
- + NULL,
- + CREATE_NEW,
- + FILE_ATTRIBUTE_NORMAL,
- + NULL);
- + if (file != INVALID_HANDLE_VALUE
- + || GetLastError() != ERROR_FILE_EXISTS)
- + return file;
- #endif
- /* tricky little algorwwithm for backward compatibility */
- - for (trv = start;;) {
- - if (!*trv)
- - return -1;
- - if (*trv == 'Z') {
- - if (trv == suffp)
- - return -1;
- - *trv++ = 'a';
- - } else {
- - if (isdigit(*trv))
- - *trv = 'a';
- - else if (*trv == 'z') /* inc from z to A */
- - *trv = 'A';
- - else {
- - if (trv == suffp)
- - return -1;
- - ++*trv;
- - }
- - break;
- + for (Char *iter = placeholderStart; iter != placeholderEnd; ++iter) {
- + switch (char(*iter)) {
- + case 'Z':
- + *iter = Latin1Char('a');
- + continue;
- +
- + case '0': case '1': case '2': case '3': case '4':
- + case '5': case '6': case '7': case '8': case '9':
- + *iter = Latin1Char('a');
- + break;
- +
- + case 'z':
- + *iter = Latin1Char('A');
- + break;
- +
- + default:
- + ++*iter;
- + break;
- }
- + break;
- }
- }
- /*NOTREACHED*/
- @@ -285,56 +266,79 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (!filePathIsTemplate)
- return QFSFileEngine::open(openMode);
- - QString qfilename = d->filePath;
- - if(!qfilename.contains(QLatin1String("XXXXXX")))
- - qfilename += QLatin1String(".XXXXXX");
- + QString filePath = d->filePath;
- - int suffixLength = qfilename.length() - (qfilename.lastIndexOf(QLatin1String("XXXXXX"), -1, Qt::CaseSensitive) + 6);
- - char *filename = qstrdup(qfilename.toLocal8Bit());
- + // Find placeholder string.
- + int placeholderLength = 0;
- + int placeholderPosition = filePath.length();
- -#ifndef Q_OS_WIN
- - int fd = _gettemp(filename, suffixLength);
- - if (fd != -1) {
- - // First open the fd as an external file descriptor to
- - // initialize the engine properly.
- - if (QFSFileEngine::open(openMode, fd)) {
- -
- - // Allow the engine to close the handle even if it's "external".
- - d->closeFileHandle = true;
- -
- - // Restore the file names (open() resets them).
- - d->filePath = QString::fromLocal8Bit(filename); //changed now!
- - filePathIsTemplate = false;
- - d->nativeInitFileName();
- - delete [] filename;
- - return true;
- + while (--placeholderPosition != -1) {
- + if (filePath[placeholderPosition] == QLatin1Char('X')) {
- + ++placeholderLength;
- + continue;
- }
- - QT_CLOSE(fd);
- + if (placeholderLength >= 6
- + || filePath[placeholderPosition] == QLatin1Char('/'))
- + break;
- +
- + placeholderLength = 0;
- }
- - delete [] filename;
- - setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- - return false;
- + ++placeholderPosition;
- +
- + QStringRef prefix, suffix;
- + if (placeholderLength < 6) {
- + filePath += QLatin1Char('.');
- + prefix = QStringRef(&filePath);
- + placeholderLength = 6;
- + } else {
- + if (placeholderPosition)
- + prefix = filePath.leftRef(placeholderPosition);
- + suffix = filePath.midRef(placeholderPosition + placeholderLength);
- + }
- +
- +#ifdef Q_OS_WIN
- + QString nativeFilePath = prefix % QString(placeholderLength, QLatin1Char('X')) % suffix;
- + placeholderPosition = prefix.length();
- #else
- - if (_gettemp(filename, suffixLength) == -1) {
- - delete [] filename;
- + QByteArray nativeFilePath = prefix.toLocal8Bit();
- + placeholderPosition = nativeFilePath.length();
- +
- + nativeFilePath.resize(placeholderPosition + placeholderLength);
- + nativeFilePath += suffix.toLocal8Bit();
- +#endif
- +
- + Char *fileName = nativeFilePath.data();
- + FileDescriptor file = _gettemp(fileName, placeholderPosition, placeholderLength);
- +
- +#ifdef Q_OS_WIN
- + if (file == INVALID_HANDLE_VALUE) {
- + setError(QFile::OpenError, qt_error_string());
- return false;
- }
- - QString template_ = d->filePath;
- - d->filePath = QString::fromLocal8Bit(filename);
- - d->nativeInitFileName();
- - delete [] filename;
- -
- - if (QFSFileEngine::open(openMode)) {
- - filePathIsTemplate = false;
- - return true;
- + d->filePath = nativeFilePath();
- + d->fileHandle = file;
- +#else
- + if (file == -1) {
- + setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- + return false;
- }
- - d->filePath = template_;
- - d->nativeFilePath.clear();
- - return false;
- + d->filePath = QString::fromLocal8Bit(fileName);
- + d->fd = file;
- + d->closeFileHandle = true;
- #endif
- +
- + filePathIsTemplate = false;
- +
- + d->openMode = openMode;
- + d->lastFlushFailed = false;
- + d->tried_stat = 0;
- +
- + d->nativeInitFileName();
- +
- + return true;
- }
- bool QTemporaryFileEngine::remove()
- diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
- index 1304f4e..30d543d 100644
- --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
- +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
- @@ -97,6 +97,9 @@ private slots:
- void setTemplateAfterOpen();
- void autoRemoveAfterFailedRename();
- + void qtbug_4796_data();
- + void qtbug_4796();
- +
- public:
- };
- @@ -359,10 +362,7 @@ void tst_QTemporaryFile::stressTest()
- for (int i = 0; i < iterations; ++i) {
- QTemporaryFile file;
- file.setAutoRemove(false);
- - if (!file.open()) {
- - qDebug() << "Could not open File:" << file.fileName();
- - continue;
- - }
- + QVERIFY(file.open());
- QVERIFY(!names.contains(file.fileName()));
- names.insert(file.fileName());
- }
- @@ -594,5 +594,98 @@ void tst_QTemporaryFile::autoRemoveAfterFailedRename()
- cleaner.reset();
- }
- +void tst_QTemporaryFile::qtbug_4796_data()
- +{
- + QTest::addColumn<QString>("prefix");
- + QTest::addColumn<QString>("suffix");
- + QTest::addColumn<bool>("openResult");
- +
- + QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
- +
- + QTest::newRow("<empty>") << QString() << QString() << true;
- + QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
- + QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true;
- + QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
- + QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true;
- + QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
- + QTest::newRow("<unicode>XXXXXX<unicode>") << unicode << unicode << true;
- +}
- +
- +void tst_QTemporaryFile::qtbug_4796()
- +{
- + struct CleanOnReturn
- + {
- + ~CleanOnReturn()
- + {
- + Q_FOREACH(QString tempName, tempNames)
- + QFile::remove(tempName);
- + }
- +
- + void reset()
- + {
- + tempNames.clear();
- + }
- +
- + QStringList tempNames;
- + };
- +
- + CleanOnReturn cleaner;
- +
- + QFETCH(QString, prefix);
- + QFETCH(QString, suffix);
- + QFETCH(bool, openResult);
- +
- + {
- + QString fileTemplate1 = prefix + QString("XX") + suffix;
- + QString fileTemplate2 = prefix + QString("XXXX") + suffix;
- + QString fileTemplate3 = prefix + QString("XXXXXX") + suffix;
- + QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix;
- +
- + QTemporaryFile file1(fileTemplate1);
- + QTemporaryFile file2(fileTemplate2);
- + QTemporaryFile file3(fileTemplate3);
- + QTemporaryFile file4(fileTemplate4);
- +
- + QCOMPARE(file1.open(), openResult);
- + QCOMPARE(file2.open(), openResult);
- + QCOMPARE(file3.open(), openResult);
- + QCOMPARE(file4.open(), openResult);
- +
- + QCOMPARE(file1.exists(), openResult);
- + QCOMPARE(file2.exists(), openResult);
- + QCOMPARE(file3.exists(), openResult);
- + QCOMPARE(file4.exists(), openResult);
- +
- + // make sure the file exists under the *correct* name
- + if (openResult) {
- + cleaner.tempNames << file1.fileName()
- + << file2.fileName()
- + << file3.fileName()
- + << file4.fileName();
- +
- + if (suffix.isEmpty()) {
- + QVERIFY(file1.fileName().startsWith(prefix));
- + QVERIFY(file2.fileName().startsWith(prefix));
- + } else {
- + QVERIFY(file1.fileName().startsWith(fileTemplate1));
- + QVERIFY(file2.fileName().startsWith(fileTemplate2));
- +
- + QVERIFY(file3.fileName().endsWith(suffix));
- + QVERIFY(file4.fileName().endsWith(suffix));
- + }
- +
- + if (!prefix.isEmpty()) {
- + QVERIFY(file3.fileName().startsWith(prefix));
- + QVERIFY(file4.fileName().startsWith(prefix));
- + }
- + }
- + }
- +
- + Q_FOREACH(QString tempName, cleaner.tempNames)
- + QVERIFY( !QFile::exists(tempName) );
- +
- + cleaner.reset();
- +}
- +
- QTEST_MAIN(tst_QTemporaryFile)
- #include "tst_qtemporaryfile.moc"
- --
- 1.7.3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement