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

Reply via email to