c - OSX FSEventStreamEventFlags not working correctly -
i watching directory file system events. seems work fine 1 exception. when create file first time, spits out created. can remove , says removed. when go create same file again, both created , removed flag @ same time. misunderstanding how flags being set when callback being called. happening here?
// // main.c // gofsevents // // created kyle cook on 8/22/13. // copyright (c) 2013 kyle cook. rights reserved. // #include <coreservices/coreservices.h> #include <stdio.h> #include <string.h> void eventcallback(fseventstreamref stream, void* callbackinfo, size_t numevents, void* paths, const fseventstreameventflags eventflags[], const fseventstreameventid eventids[]) { char **pathslist = paths; for(int = 0; i<numevents; i++) { uint32 flag = eventflags[i]; uint32 created = kfseventstreameventflagitemcreated; uint32 removed = kfseventstreameventflagitemremoved; if(flag & removed) { printf("item removed: %s\n", pathslist[i]); } else if(flag & created) { printf("item created: %s\n", pathslist[i]); } } } int main(int argc, const char * argv[]) { cfstringref mypath = cfstr("/path/to/dir"); cfarrayref paths = cfarraycreate(null, (const void **)&mypath, 1, null); cfrunloopref loop = cfrunloopgetmain(); fseventstreamref stream = fseventstreamcreate(null, (fseventstreamcallback)eventcallback, null, paths, kfseventstreameventidsincenow, 1.0, kfseventstreamcreateflagfileevents | kfseventstreamcreateflagnodefer); fseventstreamschedulewithrunloop(stream, loop, kcfrunloopdefaultmode); fseventstreamstart(stream); cfrunlooprun(); fseventstreamstop(stream); fseventstreaminvalidate(stream); fseventstreamrelease(stream); return 0; }
as far can tell, have either kfseventstreameventflagitemremoved
or kfseventstreameventflagitemcreated
, , use stat()
or similar check if file in fact added or deleted. fsevents documentation seems hint such.
it looks api or'ing events bits together... it's or of changes made since fseventslistener created. since seems case, option might create new fseventlistener each time (and use coalesce timer option).
i did googling, didn't find other examples of problem or apple sample code, didn't spend long on it.
i have used kqueue api: https://gist.github.com/nielsbot/5155671 (this gist obj-c wrapper around kqueue)
i changed sample code show flags set each fsevent:
#include <coreservices/coreservices.h> #include <stdio.h> #include <string.h> static int __count = 0 ; void eventcallback(fseventstreamref stream, void* callbackinfo, size_t numevents, void* paths, const fseventstreameventflags eventflags[], const fseventstreameventid eventids[]) { char **pathslist = paths; printf("callback #%u\n", ++__count ) ; const char * flags[] = { "mustscansubdirs", "userdropped", "kerneldropped", "eventidswrapped", "historydone", "rootchanged", "mount", "unmount", "itemcreated", "itemremoved", "iteminodemetamod", "itemrenamed", "itemmodified", "itemfinderinfomod", "itemchangeowner", "itemxattrmod", "itemisfile", "itemisdir", "itemissymlink", "ownevent" } ; for(int = 0; i<numevents; i++) { printf("%u\n", ) ; printf("\tpath %s\n", pathslist[i]) ; printf("\tflags: ") ; long bit = 1 ; for( int index=0, count = sizeof( flags ) / sizeof( flags[0]); index < count; ++index ) { if ( ( eventflags[i] & bit ) != 0 ) { printf("%s ", flags[ index ] ) ; } bit <<= 1 ; } printf("\n") ; } fseventstreamflushsync( stream ) ; } int main(int argc, const char * argv[]) { cfstringref path = cfstringcreatewithcstring( kcfallocatordefault, argv[1], kcfstringencodingutf8 ) ; cfarrayref paths = cfarraycreate(null, (const void **)&path, 1, &kcftypearraycallbacks ); if ( path ) { cfrelease( path ) ; } cfrunloopref loop = cfrunloopgetcurrent() ; fseventstreamref stream = fseventstreamcreate(null, (fseventstreamcallback)eventcallback, null, paths, kfseventstreameventidsincenow, 0, kfseventstreamcreateflagfileevents ); if ( paths ) { cfrelease( paths ) ; } fseventstreamschedulewithrunloop(stream, loop, kcfrunloopdefaultmode); fseventstreamstart(stream); cfrunlooprun() ; fseventstreamstop(stream); fseventstreaminvalidate(stream); fseventstreamrelease(stream); return 0; }
Comments
Post a Comment