extern "C" int main(int argc, char* argv[]) { PDirWatch dirWatch1; PDirWatch dirWatch2; DirWatchNotifications notifications; signal(SIGINT, onsig); if (0 != dir_watch_Add("/home/shore/lab/test/c/fam", dirWatch1)) { std::cerr << "dir_watch_Add fail" << std::endl; return EXIT_FAILURE; } std::cout << "dirWatch1 OK" << std::endl; if (0 != dir_watch_Add("/home/shore/lab/test/c", dirWatch2)) { std::cerr << "dir_watch_Add fail" << std::endl; return EXIT_FAILURE; } std::cout << "dirWatch2 OK" << std::endl; std::cout << "dir_watch_Add OK" << std::endl; do { sleep(4); if (0 != dir_watch_Poll(notifications)) { std::cerr << "dir_watch_Poll fail" << std::endl; return EXIT_FAILURE; } for(size_t i = 0; i < notifications.size(); ++i) { std::cout << notifications[i].Pathname() << std::endl; switch(notifications[i].Type()) { case DirWatchNotification::Created: std::cout << "event:Created" << std::endl; break; case DirWatchNotification::Deleted: std::cout << "event:Deleted" << std::endl; break; case DirWatchNotification::Changed: std::cout << "event:Changed" << std::endl; break; } } if (notifications.size() > 0) notifications.clear(); else std::cout << "nothing fetched" << std::endl; } while(true); dirWatch1.reset(); dirWatch2.reset(); return 0; }
Status dir_watch_Poll(DirWatchNotifications& notifications) { if ( g_Stream == NULL ) { g_Stream = CreateEventStream( g_RootPaths ); } else { for ( DirWatchNotifications::iterator it = g_QueuedDirs.begin() ; it != g_QueuedDirs.end(); ++it) notifications.push_back(DirWatchNotification( *it )); g_QueuedDirs.clear(); } return INFO::OK; }
static void fsevent_callback( ConstFSEventStreamRef UNUSED(streamRef), void * UNUSED(clientCallBackInfo), size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId UNUSED(eventIds)[] ) { unsigned long i; char **paths = (char **)eventPaths; for (i=0; i<numEvents; i++) { bool isWatched = false; OsPath eventPath = OsPath(paths[i]); unsigned long eventType = eventFlags[i]; if ( eventPath.Filename().string().c_str()[0] != '.' ) { for ( DirWatchMap::iterator it = g_Paths.begin() ; it != g_Paths.end(); ++it) if ( path_is_subpath( it->path.string().c_str(), eventPath.string().c_str() ) ) isWatched = true; } if ( ! isWatched ) return; OsPath filename = Path( eventPath.string().c_str() ); if ( eventType & kFSEventStreamEventFlagItemIsFile) { if ( eventType & kFSEventStreamEventFlagItemRemoved ) g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Deleted )); else if ( eventType & kFSEventStreamEventFlagItemRenamed ) g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Deleted )); else if ( eventType & kFSEventStreamEventFlagItemCreated ) g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Created )); else if ( eventType & kFSEventStreamEventFlagItemModified ) g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Changed )); } } }
Status dir_watch_Poll(DirWatchNotifications& notifications) { if(initialized == -1) return ERR::FAIL; // NOWARN if(!initialized) // XXX Fix Atlas instead of suppressing the warning return ERR::FAIL; //WARN_RETURN(ERR::LOGIC); std::vector<NotificationEvent> polled_notifications; pthread_mutex_lock(&g_mutex); g_notifications.swap(polled_notifications); pthread_mutex_unlock(&g_mutex); for(size_t i = 0; i < polled_notifications.size(); ++i) { DirWatchNotification::EType type; // TODO: code is actually a bitmask, so this is slightly incorrect switch(polled_notifications[i].code) { case IN_CLOSE_WRITE: type = DirWatchNotification::Changed; break; case IN_CREATE: type = DirWatchNotification::Created; break; case IN_DELETE: type = DirWatchNotification::Deleted; break; default: continue; } DirWatchMap::iterator it = g_paths.find(polled_notifications[i].wd); if(it != g_paths.end()) { OsPath filename = Path(OsString(it->second->path).append(polled_notifications[i].filename)); notifications.push_back(DirWatchNotification(filename, type)); } else { debug_printf("dir_watch_Poll: Notification with invalid watch descriptor wd=%d\n", polled_notifications[i].wd); } } // nothing new; try again later return INFO::OK; }