Subject: Re: bug#21435: 25.0.50; file-notify has problems after renames

From: Michael Albinus <[email-masked]>
Date: Wed, 09 Sep 2015 20:41:55 +0200

Eli Zaretskii <[email-masked]> writes:

>> Well, inotify sends then the low-level event `delete-self', which is
>> different from the usual `delete'. filenotify.el translates both to the
>> upper-level event `deleted'. In case of `delete-self', filenotify.el
>> could do something more, like removing the watch. Do we want this?
>
> I don't think filenotify.el should remove the watch on its own, but it
> could send an event that would allow the application do that if it
> wants to.

I will think about. And check also what's possible with gfilenotify.

>> I've tested for inotify, it works (confirmed by that user). The use case
>> of that user was, that a file has been moved outside Emacs from one
>> directory to the other. An he wanted to see it in both dired buffers,
>> immediately.
>> 
>> I couldn't test this for w32notify, but it should behave like this since
>> Sunday.
>
> If you can show some simple test case, I can run it.

Well, something like this:

--8<---------------cut here---------------start------------->8---
(progn
  (require 'filenotify)
  (defalias 'myhandler1 'ignore)
  (defalias 'myhandler2 'ignore)
  (file-notify-add-watch "/tmp" '(change) 'myhandler1)
  (file-notify-add-watch "~/tmp" '(change) 'myhandler2)
  (trace-function 'file-notify-handle-event)
  (trace-function 'myhandler1)
  (trace-function 'myhandler2))
--8<---------------cut here---------------end--------------->8---

Then you do outside Emacs (inotify case):

--8<---------------cut here---------------start------------->8---
# echo xxx >/tmp/xxx

======================================================================
1 -> (file-notify-handle-event (file-notify (1 (create) "xxx" 0) file-notify-callback))
| 2 -> (myhandler1 ((1) created "/tmp/xxx"))
| 2 <- myhandler1: nil
1 <- file-notify-handle-event: nil
======================================================================
1 -> (file-notify-handle-event (file-notify (1 (modify) "xxx" 0) file-notify-callback))
| 2 -> (myhandler1 ((1) changed "/tmp/xxx"))
| 2 <- myhandler1: nil
1 <- file-notify-handle-event: nil

# mv /tmp/xxx ~/tmp/

======================================================================
1 -> (file-notify-handle-event (file-notify (1 (moved-from) "xxx" 49278) file-notify-callback))
1 <- file-notify-handle-event: nil
======================================================================
1 -> (file-notify-handle-event (file-notify (2 (moved-to) "xxx" 49278) file-notify-callback))
| 2 -> (myhandler1 ((1) renamed "/tmp/xxx" "/home/albinus/tmp/xxx"))
| 2 <- myhandler1: nil
| 2 -> (myhandler2 ((2) renamed "/tmp/xxx" "/home/albinus/tmp/xxx"))
| 2 <- myhandler2: nil
1 <- file-notify-handle-event: nil
--8<---------------cut here---------------end--------------->8---

That looks good. The same scenario for gfilenotify needs some improvements:

--8<---------------cut here---------------start------------->8---
# echo xxx >/tmp/xxx

======================================================================
1 -> (file-notify-handle-event (file-notify (3924112 created "/tmp/xxx") file-notify-callback))
| 2 -> (myhandler1 (3924112 created "/tmp/xxx"))
| 2 <- myhandler1: nil
| 2 -> (myhandler1 (3924112 created "/tmp/xxx"))
| 2 <- myhandler1: nil
1 <- file-notify-handle-event: nil
======================================================================
1 -> (file-notify-handle-event (file-notify (3924112 changed "/tmp/xxx") file-notify-callback))
| 2 -> (myhandler1 (3924112 changed "/tmp/xxx"))
| 2 <- myhandler1: nil
| 2 -> (myhandler1 (3924112 changed "/tmp/xxx"))
| 2 <- myhandler1: nil
1 <- file-notify-handle-event: nil
======================================================================
1 -> (file-notify-handle-event (file-notify (3924112 changes-done-hint "/tmp/xxx") file-notify-callback))
1 <- file-notify-handle-event: nil

# mv /tmp/xxx ~/tmp/

======================================================================
1 -> (file-notify-handle-event (file-notify (3924112 moved "/tmp/xxx" "/home/albinus/tmp/xxx") file-notify-callback))
| 2 -> (myhandler1 (3924112 renamed "/tmp/xxx" "/home/albinus/tmp/xxx"))
| 2 <- myhandler1: nil
| 2 -> (myhandler1 (3924112 renamed "/tmp/xxx" "/home/albinus/tmp/xxx"))
| 2 <- myhandler1: nil
1 <- file-notify-handle-event: nil
--8<---------------cut here---------------end--------------->8---

myhandler1 is always called twice (why?). And in the rename case, the
call of myhandler2 is missing.

Best regards, Michael.