]> code.delx.au - gnu-emacs/commitdiff
Handle more complex rename operation in kqueue
authorMichael Albinus <michael.albinus@gmx.de>
Thu, 19 Nov 2015 09:58:08 +0000 (09:58 +0000)
committerMichael Albinus <michael.albinus@gmx.de>
Wed, 25 Nov 2015 14:07:12 +0000 (15:07 +0100)
* src/kqueue.c (pending_events): New variable.
(kqueue_compare_dir_list): Handle more complex rename operation.
(globals_of_kqueue): Initialize pending_events.

* test/automated/file-notify-tests.el (file-notify-test06-many-events):
Adapt expected events in the `rename-file' case.
(file-notify-test06-many-events-remote): Declare.

src/kqueue.c
test/automated/file-notify-tests.el

index e2c9dabcb20a04401af5d6c68e74a5d32cde8db1..fa541764169e85adf1a6492158a09079c28d2530 100644 (file)
@@ -35,6 +35,10 @@ static int kqueuefd = -1;
 /* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]).  */
 static Lisp_Object watch_list;
 
+/* Pending events, being the target of a rename operation.
+   Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE).  */
+static Lisp_Object pending_events;
+
 /* Generate a list from the directory_files_internal output.
    Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE).  */
 Lisp_Object
@@ -136,7 +140,7 @@ kqueue_compare_dir_list
 
     /* Search for an entry with the same inode.  */
     old_entry = XCAR (dl);
-    new_entry = Fassoc (XCAR (old_entry), new_dl);
+    new_entry = assq_no_quit (XCAR (old_entry), new_dl);
     if (! NILP (Fequal (old_entry, new_entry))) {
       /* Both entries are identical.  Nothing to do.  */
       new_dl = Fdelq (new_entry, new_dl);
@@ -177,16 +181,24 @@ kqueue_compare_dir_list
       new_entry = XCAR (dl1);
       if (strcmp (SSDATA (XCAR (XCDR (old_entry))),
                  SSDATA (XCAR (XCDR (new_entry)))) == 0) {
-       kqueue_generate_event
-         (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil);
+       pending_events = Fcons (new_entry, pending_events);
        new_dl = Fdelq (new_entry, new_dl);
        goto the_end;
       }
     }
 
-    /* The file has been deleted.  */
-    kqueue_generate_event
-      (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil);
+    new_entry = assq_no_quit (XCAR (old_entry), pending_events);
+    if (NILP (new_entry))
+      /* The file has been deleted.  */
+      kqueue_generate_event
+       (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil);
+    else {
+      /* The file has been renamed.  */
+      kqueue_generate_event
+       (watch_object, Fcons (Qrename, Qnil),
+        XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry)));
+      new_dl = Fdelq (new_entry, new_dl);
+    }
 
   the_end:
     dl = XCDR (dl);
@@ -444,6 +456,7 @@ void
 globals_of_kqueue (void)
 {
   watch_list = Qnil;
+  pending_events = Qnil;
 }
 
 void
index f0068c547a5e2379f4c6e86ca8e2193da21b1c1e..b9cd192dd19bc15ab4501c55bfcfa0b03b0ce717 100644 (file)
@@ -661,12 +661,7 @@ Don't wait longer than timeout seconds for the events to be delivered."
             (write-region "" nil file nil 'no-message))
           (dolist (file y-file-list)
             (write-region "" nil file nil 'no-message)))
-        (file-notify--test-with-events (cond
-                                        ;; XXX Different results?
-                                        ((featurep 'kqueue)
-                                         (append (make-list n 'changed)
-                                                 (make-list n 'deleted)))
-                                        (t (make-list n 'renamed)))
+        (file-notify--test-with-events (make-list n 'renamed)
           (let ((x-file-list x-file-list)
                 (y-file-list y-file-list))
             (while (and x-file-list y-file-list)
@@ -676,6 +671,9 @@ Don't wait longer than timeout seconds for the events to be delivered."
             (delete-file file))))
     (file-notify--test-cleanup)))
 
+(file-notify--deftest-remote file-notify-test06-many-events
+   "Check that events are not dropped remote directories.")
+
 (defun file-notify-test-all (&optional interactive)
   "Run all tests for \\[file-notify]."
   (interactive "p")