[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdepim/akonadi/resources/mbox/libmbox
From: Bertjan Broeksema <b.broeksema () home ! nl>
Date: 2009-04-05 10:29:21
Message-ID: 1238927361.989752.22670.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 949412 by bbroeksema:
Use higher level api's for locking and unlocking.
M +94 -130 mbox.cpp
M +9 -5 mbox.h
M +11 -13 tests/mboxtest.cpp
--- trunk/KDE/kdepim/akonadi/resources/mbox/libmbox/mbox.cpp #949411:949412
@@ -26,36 +26,46 @@
#include "mbox.h"
-#include <errno.h>
-#include <kde_file.h>
#include <kdebug.h>
#include <klocalizedstring.h>
+#include <klockfile.h>
#include <kshell.h>
#include <kstandarddirs.h>
#include <QtCore/QFileInfo>
+#include <QtCore/QReadWriteLock>
+#include <QtCore/QProcess>
class MBox::Private
{
public:
- Private(const QString &mboxFile, bool readOnly)
- : mMboxFile(mboxFile), mReadOnly(readOnly)
- {}
+ Private(const QString &mboxFileName, bool readOnly)
+ : mLock(mboxFileName)
+ , mMboxFile(mboxFileName)
+ , mReadOnly(readOnly)
+
+ { }
~Private()
{
- if (mStream) // shouldn't happen.
- fclose(mStream);
+ if (mMboxFile.isOpen())
+ mMboxFile.close();
}
bool mFileLocked;
- bool mFileOpen;
+ KLockFile mLock;
LockType mLockType;
- QString mMboxFile;
+ QFile mMboxFile;
QString mProcmailLockFileName;
bool mReadOnly;
- FILE* mStream;
};
+/// private static methods.
+
+QByteArray quoteAndEncode(const QString &str)
+{
+ return QFile::encodeName(KShell::quoteArg(str));
+}
+
/// public methods.
MBox::MBox(const QString &mboxFile, bool readOnly)
@@ -63,15 +73,12 @@
{
// Set some sane defaults
d->mFileLocked = false;
- d->mFileOpen = false;
- d->mLockType = FCNTL;
- d->mStream = 0;
+ d->mLockType = KDELockFile;
}
MBox::~MBox()
{
- if (d->mFileOpen)
- close();
+ close();
delete d;
}
@@ -81,12 +88,10 @@
if (d->mFileLocked)
unlock();
- if (d->mStream)
- fclose(d->mStream);
+ if (d->mMboxFile.isOpen())
+ d->mMboxFile.close();
d->mFileLocked = false;
- d->mFileOpen = false;
- d->mStream = 0;
}
QList<MsgInfo> MBox::entryList(const QSet<int> &deletedItems) const
@@ -107,24 +112,24 @@
QFileInfo info(d->mMboxFile);
if (!info.isFile()) {
- errorMsg = i18n("%1 is not a file.").arg(d->mMboxFile);
+ errorMsg = i18n("%1 is not a file.").arg(info.absoluteFilePath());
return false;
}
if (!info.exists()) {
- errorMsg = i18n("%1 does not exist").arg(d->mMboxFile);
+ errorMsg = i18n("%1 does not exist").arg(info.absoluteFilePath());
return false;
}
switch (d->mLockType) {
- case procmail_lockfile:
+ case ProcmailLockfile:
if (KStandardDirs::findExe("lockfile").isEmpty()) {
errorMsg = i18n("Could not find the lockfile executable");
return false;
}
break;
- case mutt_dotlock: // fall through
- case mutt_dotlock_privileged:
+ case MuttDotlock: // fall through
+ case MuttDotlockPrivileged:
if (KStandardDirs::findExe("mutt_dotlock").isEmpty()) {
errorMsg = i18n("Could not find the mutt_dotlock executable");
return false;
@@ -141,35 +146,39 @@
int MBox::open(OpenMode openMode)
{
- if (d->mFileOpen && openMode == Normal) {
+ if (d->mMboxFile.isOpen() && openMode == Normal) {
return 0; // already open
- } else if (d->mFileOpen) {
+ } else if (d->mMboxFile.isOpen()) {
close(); // ReloadMode, so close the file first.
}
d->mFileLocked = false;
- d->mStream = KDE_fopen( QFile::encodeName( d->mMboxFile ), "r+" ); // messages file
- if (!d->mStream) {
- kDebug() << "Cannot open mbox file `" << d->mMboxFile << "':" << strerror(errno);
- d->mFileOpen = false;
- return errno;
- }
- if (int rc = lock() != 0)
+ if (int rc = lock()) {
+ kDebug() << "Locking of the mbox file failed.";
return rc;
+ }
+
+ if (!d->mMboxFile.open(QIODevice::ReadOnly)) { // messages file
+ kDebug() << "Cannot open mbox file `" << d->mMboxFile.fileName() << "' FileError:"
+ << d->mMboxFile.error();
+ return d->mMboxFile.error();
+ }
- fcntl(fileno(d->mStream), F_SETFD, FD_CLOEXEC);
-
- return errno;
+ return 0;
}
QByteArray MBox::readEntryHeaders(int offset)
{
Q_UNUSED(offset);
+ return QByteArray();
}
void MBox::setLockType(LockType ltype)
{
+ if (d->mFileLocked)
+ return; // Don't change the method if the file is currently locked.
+
d->mLockType = ltype;
}
@@ -182,158 +191,113 @@
int MBox::lock()
{
- // TODO: Probably it is better to use QReadWriteLock in stead of the fcnt calls
- // to make the code a bit more portable.
-#ifdef Q_WS_WIN
-# ifdef __GNUC__
-# warning TODO implement mbox locking on Windows
-# else
-# pragma WARNING( TODO implement mbox locking on Windows )
-# endif
- Q_ASSERT(d->mStream != 0);
- d->mFileLocked = true;
- d->mReadOnly = false;
-#else
- Q_ASSERT(d->mStream != 0);
+ if (d->mLockType == None)
+ return 0;
d->mFileLocked = false;
+
+ QStringList args;
int rc = 0;
- QByteArray cmd_str;
switch(d->mLockType)
{
- case FCNTL:
- struct flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = 0;
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_pid = -1;
- // Set the lock, optionally wait until a previous set lock is released.
- rc = fcntl(fileno(d->mStream), F_SETLKW, &fl);
-
- if (rc < 0) {
- kDebug() << "Cannot lock mbox file `" << d->mMboxFile << "':"
- << strerror(errno) << "(" << errno << ")"
- << " switching to read only mode";
- d->mReadOnly = true; // In case the MBox object was created read/write we
- // set it to read only when locking failed.
- return errno;
+ case KDELockFile:
+ if ((rc = d->mLock.lock(KLockFile::ForceFlag))) {
+ kDebug() << "KLockFile lock failed: (" << rc
+ << ") switching to read only mode";
+ d->mReadOnly = true;
+ return rc;
}
- break;
+ break; // We only need to lock the file using the QReadWriteLock
- case procmail_lockfile:
- cmd_str = "lockfile -l20 -r5 ";
-
+ case ProcmailLockfile:
+ args << "-l20" << "-r5";
if (!d->mProcmailLockFileName.isEmpty())
- cmd_str += QFile::encodeName(KShell::quoteArg(d->mProcmailLockFileName));
+ args << quoteAndEncode(d->mProcmailLockFileName);
else
- cmd_str += QFile::encodeName(KShell::quoteArg(d->mMboxFile + ".lock"));
+ args << quoteAndEncode(d->mMboxFile.fileName() + ".lock");
- rc = system(cmd_str.data());
+ rc = QProcess::execute("lockfile", args);
if(rc != 0) {
- kDebug() << "Cannot lock mbox file `" << d->mMboxFile << "':"
- << strerror(rc) << "(" << rc << ")"
- << " switching to read only mode";
+ kDebug() << "lockfile -l20 -r5 " << d->mMboxFile.fileName()
+ << ": Failed ("<< rc << ") switching to read only mode";
d->mReadOnly = true; // In case the MBox object was created read/write we
// set it to read only when locking failed.
return rc;
}
break;
- case mutt_dotlock:
- cmd_str = "mutt_dotlock "
- + QFile::encodeName(KShell::quoteArg(d->mMboxFile));
- rc = system( cmd_str.data() );
+ case MuttDotlock:
+ args << quoteAndEncode(d->mMboxFile.fileName());
+ rc = QProcess::execute("mutt_dotlock", args);
if(rc != 0) {
- kDebug() << "Cannot lock mbox file `" << d->mMboxFile << "':"
- << strerror(rc) << "(" << rc << ")"
- << " switching to read only mode";
+ kDebug() << "mutt_dotlock " << d->mMboxFile.fileName()
+ << ": Failed (" << rc << ") switching to read only mode";
d->mReadOnly = true; // In case the MBox object was created read/write we
// set it to read only when locking failed.
return rc;
}
break;
- case mutt_dotlock_privileged:
- cmd_str = "mutt_dotlock -p "
- + QFile::encodeName(KShell::quoteArg(d->mMboxFile));
- rc = system(cmd_str.data());
+ case MuttDotlockPrivileged:
+ args << "-p" << quoteAndEncode(d->mMboxFile.fileName());
+ rc = QProcess::execute("mutt_dotlock", args);
if(rc != 0) {
- kDebug() << "Cannot lock mbox file `" << d->mMboxFile << "':"
- << strerror(rc) << "(" << rc << ")"
- << " switching to read only mode";
+ kDebug() << "mutt_dotlock -p " << d->mMboxFile.fileName() << ":"
+ << ": Failed (" << rc << ") switching to read only mode";
d->mReadOnly = true;
return rc;
}
break;
- case lock_none: // Fall through
+ case None: // This is never reached because of the check at the
+ return 0; // beginning of the function.
default:
break;
}
d->mFileLocked = true;
-#endif
return 0;
}
int MBox::unlock()
{
- #ifdef Q_WS_WIN
-# ifdef __GNUC__
-# warning TODO implement mbox unlocking on Windows
-# else
-# pragma WARNING( TODO implement mbox unlocking on Windows )
-# endif
- mFilesLocked = false;
- return 0;
-#else
- int rc;
- struct flock fl;
- fl.l_type=F_UNLCK;
- fl.l_whence=0;
- fl.l_start=0;
- fl.l_len=0;
- QByteArray cmd_str;
+ int rc = 0;
+ QStringList args;
- Q_ASSERT(d->mStream != 0);
- d->mFileLocked = false;
-
switch(d->mLockType)
{
- case FCNTL:
- fcntl(fileno(d->mStream), F_SETLK, &fl);
- rc = errno;
+ case KDELockFile:
+ d->mLock.unlock();
break;
- case procmail_lockfile:
- cmd_str = "rm -f ";
+ case ProcmailLockfile:
+ // QFile::remove returns true on succes so negate the result.
if (!d->mProcmailLockFileName.isEmpty())
- cmd_str += QFile::encodeName(KShell::quoteArg(d->mProcmailLockFileName));
+ rc = !QFile(d->mProcmailLockFileName).remove();
else
- cmd_str += QFile::encodeName(KShell::quoteArg(d->mMboxFile + ".lock"));
-
- rc = system(cmd_str.data());
+ rc = !QFile(d->mMboxFile.fileName() + ".lock").remove();
break;
- case mutt_dotlock:
- cmd_str = "mutt_dotlock -u " + QFile::encodeName(KShell::quoteArg(d->mMboxFile));
- rc = system(cmd_str.data());
+ case MuttDotlock:
+ args << "-u" << quoteAndEncode(d->mMboxFile.fileName());
+ rc = QProcess::execute("mutt_dotlock", args);
break;
- case mutt_dotlock_privileged:
- cmd_str = "mutt_dotlock -p -u " + QFile::encodeName(KShell::quoteArg(d->mMboxFile));
- rc = system(cmd_str.data());
+ case MuttDotlockPrivileged:
+ args << "-u" << "-p" << quoteAndEncode(d->mMboxFile.fileName());
+ rc = QProcess::execute("mutt_dotlock", args);
break;
- case lock_none: // Fall through.
+ case None: // Fall through.
default:
- rc = 0;
break;
}
+
+ if (!rc) // Unlocking succeeded
+ d->mFileLocked = false;
+
return rc;
-#endif
}
--- trunk/KDE/kdepim/akonadi/resources/mbox/libmbox/mbox.h #949411:949412
@@ -36,11 +36,11 @@
};
enum LockType {
- FCNTL,
- procmail_lockfile,
- mutt_dotlock,
- mutt_dotlock_privileged,
- lock_none
+ KDELockFile, // Uses KLockFile
+ ProcmailLockfile,
+ MuttDotlock,
+ MuttDotlockPrivileged,
+ None
};
public:
@@ -101,6 +101,10 @@
* Sets the locktype that should be used for locking the mbox file. The
* isValid method will check if the lock method is available when the
* procmail_lockfile or one of the mutt_dotlock variants is set.
+ *
+ * This method will not do anything if the mbox obeject is currently locked
+ * to make sure that it doesn't leave a locked file for one of the lockfile
+ * / mutt_dotlock methods.
*/
void setLockType(LockType ltype);
--- trunk/KDE/kdepim/akonadi/resources/mbox/libmbox/tests/mboxtest.cpp #949411:949412
@@ -36,7 +36,7 @@
QString MboxTest::fileName()
{
- return mTempDir->name() + QDir::separator() + testFile;
+ return mTempDir->name() + testFile;
}
void MboxTest::initTestCase()
@@ -63,26 +63,26 @@
QVERIFY(mbox1.isValid()); // FCNTL is the default lock method.
if (!KStandardDirs::findExe("lockfile").isEmpty()) {
- mbox1.setLockType(MBox::procmail_lockfile);
+ mbox1.setLockType(MBox::ProcmailLockfile);
QVERIFY(mbox1.isValid());
} else {
- mbox1.setLockType(MBox::procmail_lockfile);
+ mbox1.setLockType(MBox::ProcmailLockfile);
QVERIFY(!mbox1.isValid());
}
if (!KStandardDirs::findExe("mutt_dotlock").isEmpty()) {
- mbox1.setLockType(MBox::mutt_dotlock);
+ mbox1.setLockType(MBox::MuttDotlock);
QVERIFY(mbox1.isValid());
- mbox1.setLockType(MBox::mutt_dotlock_privileged);
+ mbox1.setLockType(MBox::MuttDotlockPrivileged);
QVERIFY(mbox1.isValid());
} else {
- mbox1.setLockType(MBox::mutt_dotlock);
+ mbox1.setLockType(MBox::MuttDotlock);
QVERIFY(!mbox1.isValid());
- mbox1.setLockType(MBox::mutt_dotlock_privileged);
+ mbox1.setLockType(MBox::MuttDotlockPrivileged);
QVERIFY(!mbox1.isValid());
}
- mbox1.setLockType(MBox::lock_none);
+ mbox1.setLockType(MBox::None);
QVERIFY(mbox1.isValid());
MBox mbox2(fileName(), false);
@@ -100,14 +100,12 @@
// It really only makes sense to test this if the lockfile executable can be
// found.
MBox mbox(fileName(), true);
- mbox.setLockType(MBox::procmail_lockfile);
+ mbox.setLockType(MBox::ProcmailLockfile);
if (!KStandardDirs::findExe("lockfile").isEmpty()) {
QVERIFY(!QFile(fileName() + ".lock").exists());
- mbox.open();
+ QCOMPARE(mbox.open(), 0);
QVERIFY(QFile(fileName() + ".lock").exists());
- QFile file(fileName());
- QVERIFY(!file.open(QFile::ReadWrite)); // The file should be locked so open
- mbox.close(); // should fail.
+ mbox.close();
QVERIFY(!QFile(fileName() + ".lock").exists());
} else {
QVERIFY(!QFile(fileName() + ".lock").exists());
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic