2019-03-31

Lots going on (such as blackbook) but I'm only going to focus on one thing today.

I've been giving Rust another go, and one of the projects that I started working on is an inotify(7)-based file watcher. Basically, I wanted to be able to run this program (watchers) in the root directory of a project, something along the lines of

$ watchers -p '\.rs$' -c makers .

What does this do? It watches . for any changed files, and if they match the pattern (-p) \.rs$, it should execute the command (-c) makers.

I'd hoped that I could edit my source code under src or what have you and it would rebuild. I don't want it to run for everything, though - sometimes a file like .gitignore is changed, and you don't want it to pick up on swap files and whatnot.

Anyways, I started working on this, and settled on a hash map that was a mapping of the inotify watch descriptors to a structure that contains the pattern and command. To make a long story short, the inotify events contain the relevant path, but for events under a subdirectory, you only get the directory as the path, which means you can't filter on a file pattern.

I'd written this same program a few years back in Go, and it makes for a good systems programming problem. I'd forgotten this part of inotify, but you have two options:

  1. Watch each directory, add new directories as they are created, and remove the ones that are deleted.
  2. List each subdirectory and build a list of files that match the pattern that should be watched. Watch the directories they're in for new files being created, and watch those that match the pattern.

Funny how these things are never as straightforward as you want...


Tags: