FSEvents callback makes it hard to properly handle rename events
| Originator: | marco | ||
| Number: | rdar://13461247 | Date Originated: | 20-Mar-2013 12:38 PM |
| Status: | Open | Resolved: | |
| Product: | Mac OS X | Product Version: | Any with FSEvents API |
| Classification: | Enhancement | Reproducible: | Always |
Summary: The official FSEvents API offers a callback that delivers events by passing an array of paths, an array of flags, an array of event IDs and a count of elements in those arrays: typedef void ( *FSEventStreamCallback )( ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]); As a consequence, for a rename event (kFSEventStreamEventFlagItemRenamed) the old and the new paths of the item in question cannot be passed with the same event ID. Instead, two events with separate event IDs are generated: one for the old path and one for the new path. Unfortunately, there's no way to know which two events in the callback belong to the same item. It gets especially tricky if a file or directory is moved into or out of the file system hierarchy that is being watched. After some testing I suspect that the event with the new path always has an event ID that is one greater than the event ID of the event with the old path. But that is just speculation, it is not documented and it sure is not pretty to implement for clients of the API. On the other hand, the (undocumented) output of /dev/fsevents delivers two string arguments for rename events: the old path and the new path. It sure would be nice if the official API would deliver the same kind of information. Steps to Reproduce: • Open the attached Xcode project. It uses an FSEventStream, watches a directory and logs any events delivered (including file events) • Change the path specified by #define DIRECTORY_TO_WATCH if necessary • Run the project • Rename some items within that directory • Move some items out of the directory • Move some items into the directory • Now try to make sense of the FSEvents that are delivered in the callback Expected Results: I'd expect there to be some information in the callback telling me what the new path if for any given rename event. With the current API design, this doesn't seem to be possible. Actual Results: The client of the API has to guess which is the new and which is the old path. Maybe if two events' event IDs differ by exactly 1 and they are delivered in the batch, they can be treated as the source and destination of the rename? But that's not exactly beautiful code to write.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
In case anyone is wondering about the information delivered on /dev/fsevents, I got that from taking a look at this code: https://github.com/binaryage/asepsis/tree/a85d86490454c381c187ff6c6c1fa5d0d27938e4/daemon