FSEvents

shr


Joined
May 2, 2013
Messages
3
Reaction score
0
Points
1
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 
 */
 

Raz0rEdge

Well-known member
Staff member
Moderator
Joined
Jul 17, 2009
Messages
15,762
Reaction score
2,100
Points
113
Location
MA
Your Mac's Specs
2022 Mac Studio M1 Max, 2023 M2 MBA
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..
 
OP
S

shr


Joined
May 2, 2013
Messages
3
Reaction score
0
Points
1
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();
 
OP
S

shr


Joined
May 2, 2013
Messages
3
Reaction score
0
Points
1
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
 

Shop Amazon


Shop for your Apple, Mac, iPhone and other computer products on Amazon.
We are a participant in the Amazon Services LLC Associates Program, an affiliate program designed to provide a means for us to earn fees by linking to Amazon and affiliated sites.
Top