FSEvents API and sandboxing
FSEvents API and sandboxing
- Subject: FSEvents API and sandboxing
- From: Dragan Milić <email@hidden>
- Date: Wed, 15 May 2019 10:47:45 +0200
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 (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden