Describe FSEvent flag information.
authorRobert Sesek <rsesek@google.com>
Fri, 20 Mar 2015 17:06:03 +0000 (13:06 -0400)
committerRobert Sesek <rsesek@google.com>
Fri, 20 Mar 2015 17:06:03 +0000 (13:06 -0400)
fseventw.c

index 7f8ea3e8451b54bf9102867053eac28e85a134af..e7a33a42dd81eac13b01547e8ecede96b8f16c76 100644 (file)
 #include <dispatch/dispatch.h>
 #include <stdio.h>
 
+typedef char FlagDescription[8];
+
+void LogControlFlagInfo(dispatch_queue_t log_queue,
+                        FSEventStreamEventFlags flags) {
+  if (flags & kFSEventStreamEventFlagUserDropped) {
+    dispatch_async(log_queue, ^{
+        printf("User-side buffer dropped event\n");
+    });
+  } else if (flags & kFSEventStreamEventFlagKernelDropped) {
+    dispatch_async(log_queue, ^{
+        printf("Kernel-side buffer dropped event\n");
+    });
+  } else if (flags & kFSEventStreamEventFlagEventIdsWrapped) {
+    dispatch_async(log_queue, ^{
+        printf("Event IDs have wrapped\n");
+    });
+  }
+}
+
+void DescribeFlags(FSEventStreamEventFlags flags, FlagDescription description) {
+  memset(description, '-', sizeof(FlagDescription));
+  description[sizeof(FlagDescription) - 1] = '\0';
+
+  if (flags & kFSEventStreamEventFlagItemCreated)
+    description[0] = 'C';
+  else if (flags & kFSEventStreamEventFlagItemModified)
+    description[1] = 'M';
+  else if (flags & kFSEventStreamEventFlagItemRemoved)
+    description[2] = 'R';
+  else if (flags & kFSEventStreamEventFlagItemRenamed)
+    description[3] = 'N';
+  else if (flags & (kFSEventStreamEventFlagItemInodeMetaMod |
+                    kFSEventStreamEventFlagItemFinderInfoMod))
+    description[4] = 'M';
+  else if (flags & kFSEventStreamEventFlagItemChangeOwner)
+    description[5] = 'O';
+  else if (flags & kFSEventStreamEventFlagItemXattrMod)
+    description[6] = 'X';
+}
+
 void EventStreamCallback(ConstFSEventStreamRef event_stream,
                          void* callback_info,
                          size_t num_events,
@@ -29,16 +69,23 @@ void EventStreamCallback(ConstFSEventStreamRef event_stream,
     const FSEventStreamEventFlags flags = event_flags[i];
     const FSEventStreamEventId ids = event_ids[i];
 
+    LogControlFlagInfo(log_queue, flags);
+
     char* path = strdup(event_paths[i]);
 
     dispatch_async(log_queue, ^{
-        printf("event %llx %x at %s\n", ids, flags, path);
+        FlagDescription flag_description;
+        DescribeFlags(flags, flag_description);
+        printf("event %llx %s at %s\n", ids, flag_description, path);
         free(path);
     });
   }
 }
 
 int main() {
+  // All logging should happen on a serial queue, so that stdout is not
+  // interleaved, as it could be when handling FSEvents on the concurrent
+  // event queue.
   dispatch_queue_t log_queue = dispatch_queue_create("com.google.fseventw.logq", DISPATCH_QUEUE_SERIAL);
   dispatch_queue_t event_queue = dispatch_queue_create("com.google.fseventw.eventq", DISPATCH_QUEUE_CONCURRENT);