Search code examples
tcltk-toolkitinotify

Tcl/Tk: why is file ignored by inotify?


I want to monitor a file by using inotify in tcl/tk. When the content of the file is changed, the proc "say" should be executed. My code works for exact one change. If I open the file (I open it with kwrite) again and change the content the proc isn't executed. "watch info" shows me, that the file still is added to the instance. "watch read" shows that the flag is set to i, which means to me, that the file is ignored by the instance. But I don't know, why the file is ignored, I didn't removed the file or something else. Could you answer, why the file is ignored?

Here's the code with emission:

package require inotify

1.3

proc say {fd} {
   puts "say hello"
}

if {[catch {set fd [inotify create "watch" "say"]} errfd]} {
   puts "$errfd"
   exit
}

puts $fd

7

if {[catch {watch add /home/server/Zwischenablage/pitt_an/pitt_an_dashboard.txt C} errwatch]} {
   puts "$errwatch"
   exit
}

watch info

/home/server/Zwischenablage/pitt_an/pitt_an_dashboard.txt 1 C

(Here I first edited the file)

say hello

watch info

/home/server/Zwischenablage/pitt_an/pitt_an_dashboard.txt 1 C

watch read

{watchid 1 flags i cookie 0 filename {}}


Solution

  • The documentation (tcl-inotify.sourceforge.net) says that the "i" flag means that "The watch was automatically removed, because the file was deleted or its filesystem was unmounted." I looked up kwrite, which you're using to modify the file, and it creates backups on save. This is usually implemented by effectively renaming the old file to a .backup and creating a new file on save.

    If that's the way that kwrite does it, then inotify is operating properly - every time you save your file, you're creating a new file and deleting the old one, and that disables your current watch. To test it, I'd "modify" the file by doing a simple touch to the file and see if it works as expected.

    If that ends up being the case, and you still want your handler to operate on files that have been modified with kwrite, then you'll want to set the handler up with the IN_ONESHOT option to delete itself fully on trigger, then have it set up a new watch on the new file of the same name before exiting.