I'm working on a little hobby project to make my own file explorer. nothing fancy, just view the files in the selected folder and optionally add/edit/rename/delete them.
I'd like for the view I present of the directory to update immediately as the contents change regardless of if those changes were made by my program or not. To that end I discovered inotify() which seems to do exactly what I want. setup a watcher on the currently selected directory and then instead of reading in all the contents again, I can simply read in once and then apply inotify events to my cached copy. For the initial read in there are a few options I'm aware of: nftw(), scandir(), and readdir(). I've currently opted for nftw as I read some concerns about race conditions with readdir, where if the file system is changing while the directory is being read it can produce duplicates or omit things. I'm not sure if the other 2 are safe from that, but I saw nftw used in another open source file manager so I'm assuming it is (correct me if I'm wrong and there is a better mechanism for this).
Now the problem. During initialization of my cache, how can I know what events occurred before, during, and after reading in the contents of the directory? Any events occurring before need to be discarded, any events occurring after need to be applied to my newly created local copy, and anything that happened during is a complete mystery to me.
My naive solution is to do the following:
- setup inotify watcher on selected directory
- read in entire directory
- if inotify has any events, repeat step 2
- otherwise the cached copy is good and can have future events applied to it.
This would ensure that the contents of the directory are coherent as any changes would have appeared as an inotify event, but I really dislike that fact that my program could be stuck in a loop if the directory has a lot of constant activity going on in it.
Is there a better way to resolve this issue, does linux provide a mechanism for it, for example maybe there is a way to lock a directory so that I can read it in, then attach my watchers and during that time that area of the file system is immutable? Would that even be a good idea if it was possible for a file manager to do? Is there a better directory reading function than nftw? I dislike how you need to use a glibc system for the no depth traversal features.