Hi all, I have a certain questions and doubts regarding using FSEvents API in an application I'm working on and I hope this is the most suiting list to raise them. The message will probably be a bit longer, for I want to describe my case in details on a possibly broken English.
During its lifetime, the application creates a certain number of objects (from only a couple to around hundreds, depending on what a user does with the application), for the sake of this discussion I'll call them model objects. Each model object has to monitor a few (1 - 6, depending on an object) files for changes and in case any monitored file changes the object has to update its properties. File changes of interest are creation, deletion, data/content change and renaming. Renaming implies not only renaming of file's name, but also changes along the full file path, that is, if any directory along the full file path is renamed, a model object has to react on that too. For those requirements I use FSEvents API. Each model object creates its dedicated FSEventStream, watching only file paths of interest for that object. Event stream is created with kFSEventStreamCreateFlagFileEvents (receiving events about individual files) and kFSEventStreamCreateFlagWatchRoot flags. The latter is required to watch file path changes along the full file path and when that happens the application receives event with kFSEventStreamEventFlagRootChanged flag and event ID of zero. Since the object's event stream watches only files of interest, no additional filtering of received event paths is done in stream's callback function. This all works like a charm and I was satisfied with the overall design and performance. Now the new requirement came and that is for the application to be sandboxed. When I started playing with it, I discovered a bit surprising (at least to me) behaviour of FSEvents API in an sandboxed environment. I expected that in order to monitor changes of a certain file, that file would have to be included in the sandbox, either by specifying it in app sandbox temporary exception entitlements, or by obtaining read access to in some other way, like using Powerbox API (NSOpenPanel). It turned out that isn't necessary. Even without any entitlements or access right granted, file changes can be monitored just fine - with exception of kFSEventStreamEventFlagRootChanged. It turned out the kFSEventStreamCreateFlagWatchRoot creation flag is completely ignored in sandboxed environment and the only way to make it work is to obtain read access to the root path of the volume where watched paths are located, either by specifying it in temporary exception entitlements or in some other sandbox-friendly way. This all means I can't detect full file path changes along the path with my current implementation. After playing around and trying different approaches, the only solution I came up with is summarized as: -- each event stream has to watch only one path and that is, unfortunately, the root path of the volume, e.g. "/" -- since the stream will flood us with many events I'm not interested in, additional event paths filtering is required in stream's callback function -- conditions, which need to be met in order to process a certain path of interest for an model object are: -- the event path has to completely match the path of interest (monitored path) and the event flags have to include kFSEventStreamEventFlagItemIsFile OR -- OR the event path has to be the prefix of a dirname() of the path of interest (that is, path of interest reduced for its last path component) and event flags have to include kFSEventStreamEventFlagItemIsDir The second condition will effectively do what kFSEventStreamCreateFlagWatchRoot flag did before. So finally, my first question is actually asking for an advice or suggestion if there's a better way to achieve what is required than what I've described above. And then, I'd appreciate some more thoughts on eventual design and performance issues. For example, since now EVERY event stream has to monitor the whole of the file system, it's probably an overkill to create more streams. So, I was thinking of having just one event stream, monitoring the root path of the file system, which would post notifications every time an event happens. Interested model object would register for those notifications and then filter and process out received changed paths in their respective notification observer methods. I'm interested to hear about potential issues and drawbacks of this approach. Finally, I'd also be interested to hear if there's anything else more suitable for the job than FSEvents API. I looked at BSD kqueue API as well, but I don't think it'd give me any benefits over FSEvents. Additional note: just to save us some time eventually going into unrelated discussion, I've mentioned obtaining read access for files of interest in sandboxed environment and that is eventually required in order to read files and update object model's properties. But how it's done in this particular application is completely unrelated topic, so there's no need to go into that, unless you really think that discussion would help my case. Thanks in advance, -- Dragan _______________________________________________ Do not post admin requests to the list. They will be ignored. Filesystem-dev mailing list (Filesystem-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/filesystem-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com