From 303f8a3d8d4d8a0644d90c1fe773abbdd9adea01 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 1 Oct 2012 18:57:06 +0200 Subject: [PATCH] Report only relevant unwatched roots by Mac file watcher --- bin/mac/fsnotifier | Bin 9292 -> 13696 bytes native/fsNotifier/mac/fsnotifier.c | 246 ++++++++++++----------------- native/fsNotifier/mac/make.sh | 3 +- 3 files changed, 106 insertions(+), 143 deletions(-) diff --git a/bin/mac/fsnotifier b/bin/mac/fsnotifier index 3d3428f4c764f770deb1954f58760fd2314b9bec..39b169a7878f07e65c6d0b674a8abfc9049ba384 100755 GIT binary patch literal 13696 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 MkE);sd5jwV4Q?08Z~y=R literal 9292 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 +#include #include -static int ReportMountedFileSystems() - // If fsBuf is too small to account for all volumes, getfsstat will - // silently truncate the returned information. Worse yet, it returns - // the number of volumes it passed back, not the number of volumes present, - // so you can't tell if the list was truncated. - // - // So, in order to get an accurate snapshot of the volume list, I call - // getfsstat with a NULL fsBuf to get a count (fsCountOrig), then allocate a - // buffer that holds (fsCountOrig + 1) items, then call getfsstat again with - // that buffer. If the list was silently truncated, the second count (fsCount) - // will be (fsCountOrig + 1), and we loop to try again. -{ - int err; - int fsCountOrig; - int fsCount; - struct statfs * fsBuf; - bool done; - - - fsBuf = NULL; - fsCount = 0; - - done = false; - do { - // Get the initial count. - err = 0; - fsCountOrig = getfsstat(NULL, 0, MNT_WAIT); - if (fsCountOrig < 0) { - err = errno; - } - - // Allocate a buffer for fsCountOrig + 1 items. - if (err == 0) { - if (fsBuf != NULL) { - free(fsBuf); - } - fsBuf = malloc((fsCountOrig + 1) * sizeof(*fsBuf)); - if (fsBuf == NULL) { - err = ENOMEM; - } - } - - // Get the list. - if (err == 0) { - fsCount = getfsstat(fsBuf, (int) ((fsCountOrig + 1) * sizeof(*fsBuf)), MNT_WAIT); - if (fsCount < 0) { - err = errno; - } - } - - // We got the full list if the number of items returned by the kernel - // is strictly less than the buffer that we allocated (fsCountOrig + 1). - if (err == 0) { - if (fsCount <= fsCountOrig) { - done = true; - } - } - } while ( (err == 0) && ! done ); - - int i; - int mountCounts = 0; - for (i = 0; i < fsCount; i++) { - if ((fsBuf[i].f_flags & MNT_LOCAL) == 0 || (fsBuf[i].f_flags & MNT_JOURNALED) == 0) { - if (mountCounts == 0) { - printf("UNWATCHEABLE\n"); - } - printf("%s\n", fsBuf[i].f_mntonname); - mountCounts++; - } - } - - if (mountCounts > 0) { - printf("#\n"); - fflush(stdout); - } - - free(fsBuf); - fsBuf = NULL; - - return err; -} - -void callback(ConstFSEventStreamRef streamRef, - void *clientCallBackInfo, - size_t numEvents, - void *eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) { +static void callback(ConstFSEventStreamRef streamRef, + void *clientCallBackInfo, + size_t numEvents, + void *eventPaths, + const FSEventStreamEventFlags eventFlags[], + const FSEventStreamEventId eventIds[]) { char **paths = eventPaths; - - int i; - for (i=0; i= mountLen && strncmp(root, mount, mountLen) == 0) { + // root under mount point + if (rootLen == mountLen || root[mountLen] == '/' || strcmp(mount, "/") == 0) { + printf("%s\n", root); + } + } + else if (strncmp(root, mount, rootLen) == 0) { + // root over mount point + if (strcmp(root, "/") == 0 || mount[rootLen] == '/') { + printf("%s\n", mount); + } + } + } + } } - ReportMountedFileSystems(); + printf("#\n"); + fflush(stdout); +} - pthread_t thread_id; - int rc = pthread_create(&thread_id, NULL, event_processing_thread, NULL); +static void ParseRoots() { + CFMutableArrayRef roots = CFArrayCreateMutable(NULL, 0, NULL); - if (rc != 0) { - // Give up if cannot create a thread. - printf("GIVEUP\n"); - exit(1); + while (TRUE) { + fscanf(stdin, "%s", command); + if (strcmp(command, "#") == 0 || feof(stdin)) break; + char* path = command[0] == '|' ? command + 1 : command; + CFArrayAppendValue(roots, strdup(path)); + } + + PrintMountedFileSystems(roots); + + for (int i = 0; i < CFArrayGetCount(roots); i++) { + void *value = (char *)CFArrayGetValueAtIndex(roots, i); + free(value); + } + CFRelease(roots); +} + +int main(const int argc, const char* argv[]) { + // Checking if necessary API is available (need MacOS X 10.5 or later). + if (FSEventStreamCreate == NULL) { + printf("GIVEUP\n"); + return 1; + } + + pthread_t threadId; + if (pthread_create(&threadId, NULL, EventProcessingThread, NULL) != 0) { + // Give up if cannot create a thread. + printf("GIVEUP\n"); + return 2; } while (TRUE) { - fscanf(stdin, "%s", command); - if (strcmp(command, "EXIT") == 0 || feof(stdin)) exit(0); - if (strcmp(command, "ROOTS") == 0) parseRoots(); + fscanf(stdin, "%s", command); + if (strcmp(command, "EXIT") == 0 || feof(stdin)) break; + if (strcmp(command, "ROOTS") == 0) ParseRoots(); } - + return 0; } diff --git a/native/fsNotifier/mac/make.sh b/native/fsNotifier/mac/make.sh index 3122301a098e..1810f1b60efa 100755 --- a/native/fsNotifier/mac/make.sh +++ b/native/fsNotifier/mac/make.sh @@ -1,2 +1,3 @@ #!/bin/sh -gcc -arch i386 -mmacosx-version-min=10.5 -framework CoreServices -o fsnotifier fsnotifier.c +# Clang can be downloaded from from http://llvm.org/releases/download.html or found in XCode 4+ +clang -arch i386 -mmacosx-version-min=10.5 -framework CoreServices -o fsnotifier fsnotifier.c