Results 1 to 4 of 4

Thread: FSEvents

  1. #1


    Member Since
    May 02, 2013
    Posts
    3
    FSEvents
    Hi
    I need something like LINUX inotify library (not INotify add in for MAC), I want to monitor a directory in the file system (with sub dirs) to know when any file or dir was changed / added / deleted / moved / renamed from name to another etc. (I need also the names)

    In almost any site I'm looking, it said how fabulous and easy is FSEvents.
    So I've decided to give it a chance, and tried to understand how to work with FSEvents, but I got nothing when I try it... I can run my program but no prints at all.
    I will be very happy if anyone can tell me what is wrong.
    I will be more than very happy if someone have a better idea like if and where I can find a 'real' inotify for mac. (somehow I think I saw it somewhere almost a year ago, but I can't find it when I need it...)

    Thanks for any help!

    I took the example from: here
    ( I guess it hard to give a full working example, so I needed to collect the code fractals)

    here (see below) is my code: it almost the same as example, except some slight changes (c/c++ etc.)

    Code:
    #include <CoreServices/CoreServices.h>
    #include <stdio.h>
    
    void mycallback( ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents,  void *eventPaths,  const FSEventStreamEventFlags eventFlags[],  const FSEventStreamEventId eventIds[])
    {
        int i;
        char **paths = (char**)eventPaths;
        // printf("Callback called\n");
        for (i=0; i<numEvents; i++) {
            /* flags are unsigned long, IDs are uint64_t */
            printf("Change %llu in %s, flags %u\n", eventIds[i], paths[i], eventFlags[i]);
       }
    }
    
    int main(int argc, char** argv)
    {
        if(argc!=2){
            printf("usage:\n %s path/to/dir\n", argv[0]);
            return -1;
        }
    
        const char* rootdir = argv[1];
        CFStringRef mypath = CFStringCreateWithFileSystemRepresentation(NULL,rootdir);
        CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
        FSEventStreamContext* callbackInfo = NULL; // could put stream-specific data here.
        FSEventStreamRef stream;
        CFAbsoluteTime latency = 0; /* Latency in seconds */
    
        /* Create the stream, passing in a callback */
        stream = FSEventStreamCreate(NULL, &mycallback, callbackInfo, pathsToWatch, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNone);
    
        /* HERE I shedule the run loop */
        FSEventStreamScheduleWithRunLoop(stream,CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    
        //guess need to run main loop to handle events
        CFRunLoopRun();
    
        /*** Never reaching here ***/
    
        FSEventStreamStop(stream);
        FSEventStreamInvalidate(stream);
        FSEventStreamRelease(stream);
    
        return 0;
    }
    /*
     * Compile:
     * $ g++ -o test main.cpp -framework CoreServices
     * Run: 
     * $ test /path/to/dir 
     */

  2. #2

    Raz0rEdge's Avatar
    Member Since
    Jul 17, 2009
    Location
    MA
    Posts
    8,550
    Specs:
    27" i7 iMac, 24" iMac, 13" Macbook Air, iPhone 6S, iPod Nano 7th GeniPad 3
    From the reference, note
    Once you have created an event stream, you must schedule it on your application’s run loop. To do this, call FSEventStreamScheduleWithRunLoop, passing in the newly-created stream, a reference to your run loop, and a run loop mode. For more information about run loops, read Run Loops.

    If you don’t already have a run loop, you will need to devote a thread to this task. After creating a thread using your API of choice, call CFRunLoopGetCurrent to allocate an initial run loop for that thread. Any future calls to CFRunLoopGetCurrent will return the same run loop.
    Read more about Run Loops..

    You've created the callback and created the stream, but you need to schedule the stream to run in your own run loop or thread, it doesn't run otherwise and thus won't call your callback with changes..
    --
    Regards
    ...Ashwin



    Be sure to read the Community Guidelines | The more information you provide, the better answers you get, remember GIGO.

  3. #3


    Member Since
    May 02, 2013
    Posts
    3
    Quote Originally Posted by Raz0rEdge View Post
    From the reference, note


    Read more about Run Loops..

    You've created the callback and created the stream, but you need to schedule the stream to run in your own run loop or thread, it doesn't run otherwise and thus won't call your callback with changes..

    Thanks for reply
    But see one line after stream create,it is stream schedule.. (or below the middle row)
    maybe there is a problem with CFRunLoopRun() ?


    Code:
     
     /* Create the stream, passing in a callback */
        stream = FSEventStreamCreate(NULL, &mycallback, callbackInfo, pathsToWatch, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNone);
     /*  ******************************************************* */
        FSEventStreamScheduleWithRunLoop(stream,CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
     /*  ******************************************************** */
        //guess need to run main loop to handle events
        CFRunLoopRun();

  4. #4


    Member Since
    May 02, 2013
    Posts
    3
    I've found a working example in here:

    Type these commands in Terminal.app

    Code:
    cd /tmp
    git clone https://github.com/alandipert/fswatch
    cd fswatch/
    make
    cp fswatch /usr/local/bin/fswatch
    Example usage
    Code:
    /usr/local/bin/fswatch ~/path/to/watch ~/script/to/run/with/changes.sh

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •