[haiku-commits] r37049 - haiku/trunk/src/kits/storage

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 7 Jun 2010 19:37:33 +0200 (CEST)

Author: stippi
Date: 2010-06-07 19:37:33 +0200 (Mon, 07 Jun 2010)
New Revision: 37049
Changeset: http://dev.haiku-os.org/changeset/37049/haiku

Modified:
   haiku/trunk/src/kits/storage/PathMonitor.cpp
Log:
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.


Modified: haiku/trunk/src/kits/storage/PathMonitor.cpp
===================================================================
--- haiku/trunk/src/kits/storage/PathMonitor.cpp        2010-06-07 17:12:56 UTC 
(rev 37048)
+++ haiku/trunk/src/kits/storage/PathMonitor.cpp        2010-06-07 17:37:33 UTC 
(rev 37049)
@@ -24,6 +24,7 @@
 #include <map>
 #include <new>
 #include <set>
+#include <stdio.h>
 
 #undef TRACE
 //#define TRACE_PATH_MONITOR
@@ -125,6 +126,8 @@
                status_t _RemoveFile(const node_ref& nodeRef);
                status_t _RemoveFile(BEntry& entry);
 
+               void _RemoveEntriesRecursively(BDirectory& directory);
+
                BPath                   fPath;
                int32                   fPathLength;
                BMessenger              fTarget;
@@ -771,8 +774,20 @@
 
        fDirectories.erase(iterator);
 
-       // TODO: stop watching subdirectories and their files when in recursive
-       // mode!
+       // stop watching subdirectories and their files when in recursive 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;
 }
@@ -889,6 +904,57 @@
 }
 
 
+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 -
 
 


Other related posts:

  • » [haiku-commits] r37049 - haiku/trunk/src/kits/storage - superstippi