New class QTemporaryDir.
As discussed on qt5-feedback / development lists. Change-Id: If1733369d12daa29054776ec2cbd78e63679768e Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
This commit is contained in:
parent
4d696d53b0
commit
e999c543a0
53
doc/src/snippets/code/src_corelib_io_qtemporarydir.cpp
Normal file
53
doc/src/snippets/code/src_corelib_io_qtemporarydir.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
{
|
||||
//! [0]
|
||||
// Within a function/method...
|
||||
|
||||
QTemporaryDir dir;
|
||||
if (dir.isValid()) {
|
||||
// dir.path() returns the unique directory path
|
||||
}
|
||||
|
||||
// The QTemporaryDir destructor removes the temporary directory
|
||||
// as it goes out of scope.
|
||||
//! [0]
|
||||
}
|
@ -20,6 +20,7 @@ HEADERS += \
|
||||
io/qprocess.h \
|
||||
io/qprocess_p.h \
|
||||
io/qtextstream.h \
|
||||
io/qtemporarydir.h \
|
||||
io/qtemporaryfile.h \
|
||||
io/qresource_p.h \
|
||||
io/qresource_iterator_p.h \
|
||||
@ -54,6 +55,7 @@ SOURCES += \
|
||||
io/qnoncontiguousbytedevice.cpp \
|
||||
io/qprocess.cpp \
|
||||
io/qtextstream.cpp \
|
||||
io/qtemporarydir.cpp \
|
||||
io/qtemporaryfile.cpp \
|
||||
io/qresource.cpp \
|
||||
io/qresource_iterator.cpp \
|
||||
|
@ -67,11 +67,11 @@ public:
|
||||
|
||||
static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0);
|
||||
|
||||
inline void setPath(const QString &path);
|
||||
void setPath(const QString &path);
|
||||
|
||||
inline void clearFileLists();
|
||||
void clearFileLists();
|
||||
|
||||
inline void resolveAbsoluteEntry() const;
|
||||
void resolveAbsoluteEntry() const;
|
||||
|
||||
QStringList nameFilters;
|
||||
QDir::SortFlags sort;
|
||||
|
258
src/corelib/io/qtemporarydir.cpp
Normal file
258
src/corelib/io/qtemporarydir.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qtemporarydir.h"
|
||||
|
||||
#ifndef QT_NO_TEMPORARYFILE
|
||||
|
||||
#include "qdiriterator.h"
|
||||
#include "qplatformdefs.h"
|
||||
#include "private/qdir_p.h"
|
||||
#include <QDebug>
|
||||
|
||||
#if defined(QT_BUILD_CORE_LIB)
|
||||
#include "qcoreapplication.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // mkdtemp
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <private/qfsfileengine_p.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
//************* QTemporaryDirPrivate
|
||||
class QTemporaryDirPrivate
|
||||
{
|
||||
public:
|
||||
QTemporaryDirPrivate();
|
||||
~QTemporaryDirPrivate();
|
||||
|
||||
QString defaultTemplateName() const;
|
||||
void create(const QString &templateName);
|
||||
|
||||
QString path;
|
||||
bool autoRemove;
|
||||
bool success;
|
||||
};
|
||||
|
||||
QTemporaryDirPrivate::QTemporaryDirPrivate()
|
||||
: autoRemove(true),
|
||||
success(false)
|
||||
{
|
||||
}
|
||||
|
||||
QTemporaryDirPrivate::~QTemporaryDirPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
QString QTemporaryDirPrivate::defaultTemplateName() const
|
||||
{
|
||||
QString baseName;
|
||||
#if defined(QT_BUILD_CORE_LIB)
|
||||
baseName = QCoreApplication::applicationName();
|
||||
if (baseName.isEmpty())
|
||||
#endif
|
||||
baseName = QLatin1String("qt_temp");
|
||||
|
||||
return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX");
|
||||
}
|
||||
|
||||
void QTemporaryDirPrivate::create(const QString &templateName)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QString buffer = templateName;
|
||||
// Windows' mktemp believes 26 temp files per process ought to be enough for everyone (!)
|
||||
// Let's add a few random chars then, before the XXXXXX template.
|
||||
for (int i = 0 ; i < 4 ; ++i)
|
||||
buffer += QChar((qrand() & 0xffff) % (26) + 'A');
|
||||
if (!buffer.endsWith(QLatin1String("XXXXXX")))
|
||||
buffer += QLatin1String("XXXXXX");
|
||||
QFileSystemEntry baseEntry(buffer);
|
||||
QFileSystemEntry::NativePath basePath = baseEntry.nativeFilePath();
|
||||
wchar_t* array = (wchar_t*)basePath.utf16();
|
||||
if (_wmktemp(array) && ::CreateDirectory(array, 0)) {
|
||||
success = true;
|
||||
QFileSystemEntry entry(QString::fromWCharArray(array), QFileSystemEntry::FromNativePath());
|
||||
path = entry.filePath();
|
||||
}
|
||||
#else
|
||||
QByteArray buffer = QFile::encodeName(templateName);
|
||||
if (!buffer.endsWith("XXXXXX"))
|
||||
buffer += "XXXXXX";
|
||||
if (mkdtemp(buffer.data())) { // modifies buffer
|
||||
success = true;
|
||||
path = QFile::decodeName(buffer.constData());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//************* QTemporaryDir
|
||||
|
||||
/*!
|
||||
\class QTemporaryDir
|
||||
\reentrant
|
||||
\brief The QTemporaryDir class creates a unique directory for temporary use.
|
||||
|
||||
\ingroup io
|
||||
|
||||
|
||||
QTemporaryDir is used to create unique temporary dirs safely.
|
||||
The dir itself is created by the constructor. The name of the
|
||||
temporary directory is guaranteed to be unique (i.e., you are
|
||||
guaranteed to not overwrite an existing dir), and the directory will
|
||||
subsequently be removed upon destruction of the QTemporaryDir
|
||||
object. The directory name is either auto-generated, or created based
|
||||
on a template, which is passed to QTemporaryDir's constructor.
|
||||
|
||||
Example:
|
||||
|
||||
\snippet doc/src/snippets/code/src_corelib_io_qtemporarydir.cpp 0
|
||||
|
||||
It is very important to test that the temporary directory could be
|
||||
created, using isValid(). Do not use exists(), since a default-constructed
|
||||
QDir represents the current directory, which exists.
|
||||
|
||||
The path to the temporary dir can be found by calling path().
|
||||
|
||||
A temporary directory will have some static part of the name and some
|
||||
part that is calculated to be unique. The default path will be
|
||||
determined from QCoreApplication::applicationName() (otherwise \c qt_temp) and will
|
||||
be placed into the temporary path as returned by QDir::tempPath().
|
||||
If you specify your own path, a relative path will not be placed in the
|
||||
temporary directory by default, but be relative to the current working directory.
|
||||
In all cases, a random string will be appended to the path in order to make it unique.
|
||||
|
||||
\sa QDir::tempPath(), QDir, QTemporaryFile
|
||||
*/
|
||||
|
||||
QTemporaryDir::QTemporaryDir()
|
||||
: d_ptr(new QTemporaryDirPrivate)
|
||||
{
|
||||
d_ptr->create(d_ptr->defaultTemplateName());
|
||||
}
|
||||
|
||||
QTemporaryDir::QTemporaryDir(const QString &templateName)
|
||||
: d_ptr(new QTemporaryDirPrivate)
|
||||
{
|
||||
if (templateName.isEmpty())
|
||||
d_ptr->create(d_ptr->defaultTemplateName());
|
||||
else
|
||||
d_ptr->create(templateName);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the temporary directory object.
|
||||
If auto remove mode was set, it will automatically delete the directory
|
||||
including all its contents.
|
||||
|
||||
\sa autoRemove()
|
||||
*/
|
||||
QTemporaryDir::~QTemporaryDir()
|
||||
{
|
||||
if (d_ptr->success && d_ptr->autoRemove)
|
||||
remove();
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the QTemporaryDir was created successfully.
|
||||
*/
|
||||
bool QTemporaryDir::isValid() const
|
||||
{
|
||||
return d_ptr->success;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the path to the temporary directory.
|
||||
Empty if the QTemporaryDir could not be created.
|
||||
*/
|
||||
QString QTemporaryDir::path() const
|
||||
{
|
||||
return d_ptr->path;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the QTemporaryDir is in auto remove
|
||||
mode. Auto-remove mode will automatically delete the directory from
|
||||
disk upon destruction. This makes it very easy to create your
|
||||
QTemporaryDir object on the stack, fill it with files, do something with
|
||||
the files, and finally on function return it will automatically clean up
|
||||
after itself.
|
||||
|
||||
Auto-remove is on by default.
|
||||
|
||||
\sa setAutoRemove(), remove()
|
||||
*/
|
||||
bool QTemporaryDir::autoRemove() const
|
||||
{
|
||||
return d_ptr->autoRemove;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the QTemporaryDir into auto-remove mode if \a b is true.
|
||||
|
||||
Auto-remove is on by default.
|
||||
|
||||
\sa autoRemove(), remove()
|
||||
*/
|
||||
void QTemporaryDir::setAutoRemove(bool b)
|
||||
{
|
||||
d_ptr->autoRemove = b;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes the temporary directory, including all its contents.
|
||||
*/
|
||||
bool QTemporaryDir::remove()
|
||||
{
|
||||
if (!d_ptr->success)
|
||||
return false;
|
||||
Q_ASSERT(!path().isEmpty());
|
||||
Q_ASSERT(path() != QLatin1String("."));
|
||||
|
||||
return QDir(path()).removeRecursively();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_TEMPORARYFILE
|
84
src/corelib/io/qtemporarydir.h
Normal file
84
src/corelib/io/qtemporarydir.h
Normal file
@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTEMPORARYDIR_H
|
||||
#define QTEMPORARYDIR_H
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(Core)
|
||||
|
||||
#ifndef QT_NO_TEMPORARYFILE
|
||||
|
||||
class QTemporaryDirPrivate;
|
||||
|
||||
class Q_CORE_EXPORT QTemporaryDir
|
||||
{
|
||||
public:
|
||||
QTemporaryDir();
|
||||
explicit QTemporaryDir(const QString &templateName);
|
||||
~QTemporaryDir();
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
bool autoRemove() const;
|
||||
void setAutoRemove(bool b);
|
||||
bool remove();
|
||||
|
||||
QString path() const;
|
||||
|
||||
private:
|
||||
QTemporaryDirPrivate* const d_ptr;
|
||||
|
||||
Q_DISABLE_COPY(QTemporaryDir)
|
||||
};
|
||||
|
||||
#endif // QT_NO_TEMPORARYFILE
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QTEMPORARYDIR_H
|
@ -16,6 +16,7 @@ SUBDIRS=\
|
||||
qresourceengine \
|
||||
qsettings \
|
||||
qstandardpaths \
|
||||
qtemporarydir \
|
||||
qtemporaryfile \
|
||||
qtextstream \
|
||||
qurl \
|
||||
|
7
tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro
Normal file
7
tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro
Normal file
@ -0,0 +1,7 @@
|
||||
CONFIG += testcase
|
||||
TARGET = tst_qtemporarydir
|
||||
SOURCES += tst_qtemporarydir.cpp
|
||||
|
||||
QT = core testlib
|
||||
|
||||
CONFIG += parallel_test
|
471
tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
Normal file
471
tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
Normal file
@ -0,0 +1,471 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qstring.h>
|
||||
#include <qtemporarydir.h>
|
||||
#include <qfile.h>
|
||||
#include <qdir.h>
|
||||
#include <qset.h>
|
||||
#ifdef Q_OS_WIN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
//TESTED_CLASS=QTemporaryDir
|
||||
//TESTED_FILES=qtemporarydir.cpp
|
||||
|
||||
class tst_QTemporaryDir : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_QTemporaryDir();
|
||||
virtual ~tst_QTemporaryDir();
|
||||
public slots:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
private slots:
|
||||
void construction();
|
||||
void fileTemplate();
|
||||
void fileTemplate_data();
|
||||
void getSetCheck();
|
||||
void fileName();
|
||||
void autoRemove();
|
||||
void nonWritableCurrentDir();
|
||||
void openOnRootDrives();
|
||||
void stressTest();
|
||||
void rename();
|
||||
void autoRemoveAfterFailedRename();
|
||||
|
||||
void QTBUG_4796_data();
|
||||
void QTBUG_4796();
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
void tst_QTemporaryDir::initTestCase()
|
||||
{
|
||||
QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX"));
|
||||
QCoreApplication::setApplicationName("tst_qtemporarydir");
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::cleanupTestCase()
|
||||
{
|
||||
QVERIFY(QDir().rmdir("test-XXXXXX"));
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::construction()
|
||||
{
|
||||
QTemporaryDir dir;
|
||||
QString tmp = QDir::tempPath();
|
||||
QCOMPARE(dir.path().left(tmp.size()), tmp);
|
||||
QVERIFY(dir.path().contains("tst_qtemporarydir"));
|
||||
QVERIFY(QFileInfo(dir.path()).isDir());
|
||||
}
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QTemporaryDir::getSetCheck()
|
||||
{
|
||||
QTemporaryDir obj1;
|
||||
// bool QTemporaryDir::autoRemove()
|
||||
// void QTemporaryDir::setAutoRemove(bool)
|
||||
obj1.setAutoRemove(false);
|
||||
QCOMPARE(false, obj1.autoRemove());
|
||||
obj1.setAutoRemove(true);
|
||||
QCOMPARE(true, obj1.autoRemove());
|
||||
}
|
||||
|
||||
tst_QTemporaryDir::tst_QTemporaryDir()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QTemporaryDir::~tst_QTemporaryDir()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::init()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::fileTemplate_data()
|
||||
{
|
||||
QTest::addColumn<QString>("constructorTemplate");
|
||||
QTest::addColumn<QString>("prefix");
|
||||
|
||||
QTest::newRow("constructor default") << "" << "tst_qtemporarydir-";
|
||||
|
||||
QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_XXXXXXxxx";
|
||||
QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_XXXXXXxXx";
|
||||
QTest::newRow("constructor with no suffix") << "qt_XXXXXX" << "qt_";
|
||||
QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_XXXX";
|
||||
QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_";
|
||||
QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_XXXX";
|
||||
QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_XXXXX";
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::fileTemplate()
|
||||
{
|
||||
QFETCH(QString, constructorTemplate);
|
||||
QFETCH(QString, prefix);
|
||||
|
||||
QTemporaryDir tempDir(constructorTemplate);
|
||||
|
||||
QVERIFY(tempDir.isValid());
|
||||
|
||||
QString dirName = QDir(tempDir.path()).dirName();
|
||||
if (prefix.length())
|
||||
QCOMPARE(dirName.left(prefix.length()), prefix);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This tests whether the temporary dir really gets placed in QDir::tempPath
|
||||
*/
|
||||
void tst_QTemporaryDir::fileName()
|
||||
{
|
||||
// Get QDir::tempPath and make an absolute path.
|
||||
QString tempPath = QDir::tempPath();
|
||||
QString absoluteTempPath = QDir(tempPath).absolutePath();
|
||||
QTemporaryDir dir;
|
||||
dir.setAutoRemove(true);
|
||||
QString fileName = dir.path();
|
||||
QVERIFY2(fileName.contains("/tst_qtemporarydir-"), qPrintable(fileName));
|
||||
QVERIFY(QFile::exists(fileName));
|
||||
// Get path to the temp dir, without the file name.
|
||||
QString absoluteFilePath = QFileInfo(fileName).absolutePath();
|
||||
#if defined(Q_OS_WIN)
|
||||
absoluteFilePath = absoluteFilePath.toLower();
|
||||
absoluteTempPath = absoluteTempPath.toLower();
|
||||
#endif
|
||||
QCOMPARE(absoluteFilePath, absoluteTempPath);
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::autoRemove()
|
||||
{
|
||||
// Test auto remove
|
||||
QString dirName;
|
||||
{
|
||||
QTemporaryDir dir("tempXXXXXX");
|
||||
dir.setAutoRemove(true);
|
||||
QVERIFY(dir.isValid());
|
||||
dirName = dir.path();
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
// Windows seems unreliable here: sometimes it says the directory still exists,
|
||||
// immediately after we deleted it.
|
||||
QTRY_VERIFY(!QFile::exists(dirName));
|
||||
#else
|
||||
QVERIFY(!QFile::exists(dirName));
|
||||
#endif
|
||||
|
||||
// Test if disabling auto remove works.
|
||||
{
|
||||
QTemporaryDir dir("tempXXXXXX");
|
||||
dir.setAutoRemove(false);
|
||||
QVERIFY(dir.isValid());
|
||||
dirName = dir.path();
|
||||
}
|
||||
QVERIFY(QFile::exists(dirName));
|
||||
QVERIFY(QDir().rmdir(dirName));
|
||||
QVERIFY(!QFile::exists(dirName));
|
||||
|
||||
// Do not explicitly call setAutoRemove (tests if it really is the default as documented)
|
||||
{
|
||||
QTemporaryDir dir("tempXXXXXX");
|
||||
QVERIFY(dir.isValid());
|
||||
dirName = dir.path();
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
QTRY_VERIFY(!QFile::exists(dirName));
|
||||
#else
|
||||
QVERIFY(!QFile::exists(dirName));
|
||||
#endif
|
||||
|
||||
// Test autoremove with files and subdirs in the temp dir
|
||||
{
|
||||
QTemporaryDir tempDir("tempXXXXXX");
|
||||
QVERIFY(tempDir.isValid());
|
||||
dirName = tempDir.path();
|
||||
QDir dir(dirName);
|
||||
QVERIFY(dir.mkdir(QString::fromLatin1("dir1")));
|
||||
QVERIFY(dir.mkdir(QString::fromLatin1("dir2")));
|
||||
QVERIFY(dir.mkdir(QString::fromLatin1("dir2/nested")));
|
||||
QFile file(dirName + "/dir1/file");
|
||||
QVERIFY(file.open(QIODevice::WriteOnly));
|
||||
QCOMPARE(file.write("Hello"), 5LL);
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
QTRY_VERIFY(!QFile::exists(dirName));
|
||||
#else
|
||||
QVERIFY(!QFile::exists(dirName));
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::nonWritableCurrentDir()
|
||||
{
|
||||
#ifdef Q_OS_UNIX
|
||||
QString cwd = QDir::currentPath();
|
||||
QDir::setCurrent("/");
|
||||
// QTemporaryDir("tempXXXXXX") is probably a bad idea in any app
|
||||
// where the current dir could anything...
|
||||
QString fileName;
|
||||
QTemporaryDir dir("tempXXXXXX");
|
||||
dir.setAutoRemove(true);
|
||||
QVERIFY(!dir.isValid());
|
||||
fileName = dir.path();
|
||||
QDir::setCurrent(cwd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::openOnRootDrives()
|
||||
{
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
#endif
|
||||
// If it's possible to create a dir in the root directory, it
|
||||
// must be possible to create a temp dir there too.
|
||||
foreach (const QFileInfo &driveInfo, QDir::drives()) {
|
||||
QFile testFile(driveInfo.filePath() + "XXXXXX.txt");
|
||||
if (testFile.open(QIODevice::ReadWrite)) {
|
||||
testFile.remove();
|
||||
QTemporaryDir dir(driveInfo.filePath() + "XXXXXX.txt");
|
||||
dir.setAutoRemove(true);
|
||||
QVERIFY(dir.isValid());
|
||||
}
|
||||
}
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
SetErrorMode(lastErrorMode);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::stressTest()
|
||||
{
|
||||
const int iterations = 1000;
|
||||
|
||||
QSet<QString> names;
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
QTemporaryDir dir;
|
||||
dir.setAutoRemove(false);
|
||||
QVERIFY2(dir.isValid(), qPrintable(QString::number(i)));
|
||||
QVERIFY(!names.contains(dir.path()));
|
||||
names.insert(dir.path());
|
||||
}
|
||||
for (QSet<QString>::const_iterator it = names.constBegin(); it != names.constEnd(); ++it)
|
||||
QDir(*it).removeRecursively();
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::rename()
|
||||
{
|
||||
// This test checks what happens if the temporary dir is renamed.
|
||||
// Then the autodelete feature can't possibly find it.
|
||||
|
||||
QDir dir;
|
||||
QVERIFY(!dir.exists("temporary-dir.renamed"));
|
||||
|
||||
QString tempname;
|
||||
{
|
||||
QTemporaryDir tempDir(dir.filePath("temporary-dir.XXXXXX"));
|
||||
|
||||
QVERIFY(tempDir.isValid());
|
||||
tempname = tempDir.path();
|
||||
|
||||
QVERIFY(QDir().rename(tempname, "temporary-dir.renamed"));
|
||||
QVERIFY(!QDir(tempname).exists());
|
||||
dir.setPath("temporary-dir.renamed");
|
||||
QCOMPARE(dir.path(), QString("temporary-dir.renamed"));
|
||||
QVERIFY(dir.exists());
|
||||
}
|
||||
|
||||
// Auto-delete couldn't find it
|
||||
QVERIFY(dir.exists());
|
||||
// Clean up by hand
|
||||
QVERIFY(dir.removeRecursively());
|
||||
QVERIFY(!dir.exists());
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::autoRemoveAfterFailedRename()
|
||||
{
|
||||
struct CleanOnReturn
|
||||
{
|
||||
~CleanOnReturn()
|
||||
{
|
||||
if (!tempName.isEmpty())
|
||||
QVERIFY(QDir(tempName).removeRecursively());
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
tempName.clear();
|
||||
}
|
||||
|
||||
QString tempName;
|
||||
};
|
||||
|
||||
CleanOnReturn cleaner;
|
||||
|
||||
{
|
||||
QTemporaryDir dir;
|
||||
QVERIFY(dir.isValid());
|
||||
cleaner.tempName = dir.path();
|
||||
|
||||
QVERIFY(QFile::exists(cleaner.tempName));
|
||||
QVERIFY(!QFileInfo("i-do-not-exist").isDir());
|
||||
QVERIFY(!QDir().rename(cleaner.tempName, "i-do-not-exist/dir.txt"));
|
||||
QVERIFY(QFile::exists(cleaner.tempName));
|
||||
}
|
||||
|
||||
QVERIFY(!QFile::exists(cleaner.tempName));
|
||||
cleaner.reset();
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::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(".") << QString(".") << QString() << true;
|
||||
QTest::newRow("..") << QString("..") << QString() << true;
|
||||
QTest::newRow("blaXXXXXX") << QString("bla") << QString() << 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;
|
||||
}
|
||||
|
||||
void tst_QTemporaryDir::QTBUG_4796()
|
||||
{
|
||||
QVERIFY(QDir("test-XXXXXX").exists());
|
||||
|
||||
struct CleanOnReturn
|
||||
{
|
||||
~CleanOnReturn()
|
||||
{
|
||||
foreach (const QString &tempName, tempNames)
|
||||
QVERIFY(QDir(tempName).removeRecursively());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
QTemporaryDir dir1(fileTemplate1);
|
||||
QTemporaryDir dir2(fileTemplate2);
|
||||
QTemporaryDir dir3(fileTemplate3);
|
||||
QTemporaryDir dir4(fileTemplate4);
|
||||
QTemporaryDir dir5("test-XXXXXX/" + fileTemplate1);
|
||||
QTemporaryDir dir6("test-XXXXXX/" + fileTemplate3);
|
||||
|
||||
QCOMPARE(dir1.isValid(), openResult);
|
||||
QCOMPARE(dir2.isValid(), openResult);
|
||||
QCOMPARE(dir3.isValid(), openResult);
|
||||
QCOMPARE(dir4.isValid(), openResult);
|
||||
QCOMPARE(dir5.isValid(), openResult);
|
||||
QCOMPARE(dir6.isValid(), openResult);
|
||||
|
||||
// make sure the dir exists under the *correct* name
|
||||
if (openResult) {
|
||||
cleaner.tempNames << dir1.path()
|
||||
<< dir2.path()
|
||||
<< dir3.path()
|
||||
<< dir4.path()
|
||||
<< dir5.path()
|
||||
<< dir6.path();
|
||||
|
||||
QDir currentDir;
|
||||
QString fileName1 = currentDir.relativeFilePath(dir1.path());
|
||||
QString fileName2 = currentDir.relativeFilePath(dir2.path());
|
||||
QString fileName3 = currentDir.relativeFilePath(dir3.path());
|
||||
QString fileName4 = currentDir.relativeFilePath(dir4.path());
|
||||
QString fileName5 = currentDir.relativeFilePath(dir5.path());
|
||||
QString fileName6 = currentDir.relativeFilePath(dir6.path());
|
||||
|
||||
QVERIFY(fileName1.startsWith(fileTemplate1));
|
||||
QVERIFY(fileName2.startsWith(fileTemplate2));
|
||||
QVERIFY(fileName5.startsWith("test-XXXXXX/" + fileTemplate1));
|
||||
QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix));
|
||||
|
||||
if (!prefix.isEmpty()) {
|
||||
QVERIFY(fileName3.startsWith(prefix));
|
||||
QVERIFY(fileName4.startsWith(prefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QTest::qWait(20);
|
||||
#endif
|
||||
foreach (const QString &tempName, cleaner.tempNames)
|
||||
QVERIFY2(!QFile::exists(tempName), qPrintable(tempName));
|
||||
|
||||
cleaner.reset();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTemporaryDir)
|
||||
#include "tst_qtemporarydir.moc"
|
Loading…
Reference in New Issue
Block a user