Resolved TODO about recursively removing watched files and folders when a
directory is moved outside the watched hierarchy or deleted entirely. It involves another TODO, because the generated notifications are B_ENTRY_REMOVED, while B_ENTRY_MOVED is probably more correct. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37049 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#undef TRACE
|
#undef TRACE
|
||||||
//#define TRACE_PATH_MONITOR
|
//#define TRACE_PATH_MONITOR
|
||||||
@@ -125,6 +126,8 @@ class PathHandler : public BHandler {
|
|||||||
status_t _RemoveFile(const node_ref& nodeRef);
|
status_t _RemoveFile(const node_ref& nodeRef);
|
||||||
status_t _RemoveFile(BEntry& entry);
|
status_t _RemoveFile(BEntry& entry);
|
||||||
|
|
||||||
|
void _RemoveEntriesRecursively(BDirectory& directory);
|
||||||
|
|
||||||
BPath fPath;
|
BPath fPath;
|
||||||
int32 fPathLength;
|
int32 fPathLength;
|
||||||
BMessenger fTarget;
|
BMessenger fTarget;
|
||||||
@@ -771,8 +774,20 @@ PathHandler::_RemoveDirectory(const node_ref& nodeRef, ino_t directoryNode)
|
|||||||
|
|
||||||
fDirectories.erase(iterator);
|
fDirectories.erase(iterator);
|
||||||
|
|
||||||
// TODO: stop watching subdirectories and their files when in recursive
|
// stop watching subdirectories and their files when in recursive mode
|
||||||
// mode!
|
if (_WatchRecursively()) {
|
||||||
|
BDirectory entryDirectory(&nodeRef);
|
||||||
|
if (entryDirectory.InitCheck() == B_OK) {
|
||||||
|
// The directory still exists, but was moved outside our watched
|
||||||
|
// folder hierarchy.
|
||||||
|
_RemoveEntriesRecursively(entryDirectory);
|
||||||
|
} else {
|
||||||
|
// Actually, it shouldn't be possible to remove non-empty
|
||||||
|
// folders so for this case we don't need to do anything. We should
|
||||||
|
// have received remove notifications for all affected files and
|
||||||
|
// folders that used to live in this directory.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -889,6 +904,57 @@ PathHandler::_RemoveFile(BEntry& entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PathHandler::_RemoveEntriesRecursively(BDirectory& directory)
|
||||||
|
{
|
||||||
|
node_ref directoryNode;
|
||||||
|
directory.GetNodeRef(&directoryNode);
|
||||||
|
|
||||||
|
BMessage message(B_PATH_MONITOR);
|
||||||
|
message.AddInt32("opcode", B_ENTRY_REMOVED);
|
||||||
|
// TODO: B_ENTRY_MOVED could be regarded as more correct,
|
||||||
|
// but then we would definitely need more information in this
|
||||||
|
// function.
|
||||||
|
message.AddInt32("device", directoryNode.device);
|
||||||
|
message.AddInt64("directory", directoryNode.node);
|
||||||
|
message.AddInt64("node", 0LL);
|
||||||
|
// dummy node, will be replaced by real node
|
||||||
|
|
||||||
|
// NOTE: The _NotifyTarget() gets the node id, but constructs
|
||||||
|
// the path to the previous location of the entry according to the file
|
||||||
|
// or folder in our sets. This makes it more expensive of course, but
|
||||||
|
// I have no inspiration for improvement at the moment.
|
||||||
|
|
||||||
|
BEntry entry;
|
||||||
|
while (directory.GetNextEntry(&entry) == B_OK) {
|
||||||
|
node_ref nodeRef;
|
||||||
|
if (entry.GetNodeRef(&nodeRef) != B_OK) {
|
||||||
|
fprintf(stderr, "PathHandler::_RemoveEntriesRecursively() - "
|
||||||
|
"failed to get node_ref\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.ReplaceInt64("node", nodeRef.node);
|
||||||
|
|
||||||
|
if (entry.IsDirectory()) {
|
||||||
|
// notification
|
||||||
|
if (!_WatchFilesOnly())
|
||||||
|
_NotifyTarget(&message, nodeRef);
|
||||||
|
|
||||||
|
_RemoveDirectory(nodeRef, directoryNode.node);
|
||||||
|
BDirectory subDirectory(&entry);
|
||||||
|
_RemoveEntriesRecursively(subDirectory);
|
||||||
|
} else {
|
||||||
|
// notification
|
||||||
|
if (!_WatchFoldersOnly())
|
||||||
|
_NotifyTarget(&message, nodeRef);
|
||||||
|
|
||||||
|
_RemoveFile(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user