Commit 1f6d6cfc authored by David Faure's avatar David Faure

Fix KDirWatch to emit dirty on parent dir when watched subdir is deleted

In Inotify mode, there's a special event for the case where a watched
dir is deleted ("IN_DELETESELF"). In the handling of that event, we must
still set the parent directory to dirty, in case another KDirWatch
only cares for the parent.

Excellent unit test by Frank Reininghaus, as usual -- thanks!

BUG: 316016
FIXED-IN: 4.10.2
parent 3ea42bb5
......@@ -331,6 +331,10 @@ void KDirWatchPrivate::inotifyEventReceived()
e->wd = -1;
e->m_ctime = invalid_ctime;
emitEvent(e, Deleted, e->path);
// If the parent dir was already watched, tell it something changed
Entry* parentEntry = entry(e->parentDirectory());
if (parentEntry)
parentEntry->dirty = true;
// Add entry to parent dir to notice if the entry gets recreated
addEntry(0, e->parentDirectory(), e, true /*isDir*/);
}
......@@ -1594,6 +1598,10 @@ void KDirWatchPrivate::checkFAMEvent(FAMEvent* fe)
e->m_status = NonExistent;
e->m_ctime = invalid_ctime;
emitEvent(e, Deleted, e->path);
// If the parent dir was already watched, tell it something changed
Entry* parentEntry = entry(e->parentDirectory());
if (parentEntry)
parentEntry->dirty = true;
// Add entry to parent dir to notice if the entry gets recreated
addEntry(0, e->parentDirectory(), e, true /*isDir*/);
} else {
......
......@@ -1056,6 +1056,48 @@ void KDirListerTest::testWatchingAfterCopyJob() // #331582
QVERIFY(QTest::kWaitForSignal(&m_dirLister, SIGNAL(clear()), 1000));
}
void KDirListerTest::testRemoveWatchedDirectory()
{
m_items.clear();
KTempDir newDir;
const QString path = newDir.name();
// List and watch an empty dir
connect(&m_dirLister, SIGNAL(newItems(KFileItemList)), this, SLOT(slotNewItems(KFileItemList)));
m_dirLister.openUrl(KUrl(path));
QVERIFY(QTest::kWaitForSignal(&m_dirLister, SIGNAL(completed()), 1000));
QVERIFY(m_dirLister.isFinished());
QVERIFY(m_items.isEmpty());
// Create a subfolder.
const QString subDirPath = path + "abc";
QVERIFY(QDir().mkdir(subDirPath));
QVERIFY(QTest::kWaitForSignal(&m_dirLister, SIGNAL(completed()), 1000));
QVERIFY(m_dirLister.isFinished());
QCOMPARE(m_items.count(), 1);
const KFileItem item = m_items.at(0);
// Watch the subfolder for changes, independently.
// This is what triggers the bug.
// (Technically, this could become a KDirWatch unittest, but if one day we use QFSW, good to have the tests here)
KDirWatch watcher;
watcher.addDir(subDirPath);
// Remove the subfolder.
m_items.clear();
QVERIFY(QDir().rmdir(path + "abc"));
// This should trigger an update.
QVERIFY(QTest::kWaitForSignal(&m_dirLister, SIGNAL(completed()), 1000));
QVERIFY(m_dirLister.isFinished());
QCOMPARE(m_items.count(), 0);
QCOMPARE(m_dirLister.spyItemsDeleted.count(), 1);
const KFileItem deletedItem = m_dirLister.spyItemsDeleted.at(0).at(0).value<KFileItemList>().at(0);
QCOMPARE(item, deletedItem);
}
void KDirListerTest::enterLoop(int exitCount)
{
//qDebug("enterLoop");
......
......@@ -110,6 +110,7 @@ private Q_SLOTS:
void testRenameCurrentDir();
void testRedirection();
void testWatchingAfterCopyJob();
void testRemoveWatchedDirectory();
void testDeleteCurrentDir(); // must be last!
protected Q_SLOTS: // 'more private than private slots' - i.e. not seen by qtestlib
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment