bool kqueue_monitor::scan(const string& path, bool is_root_path) { struct stat fd_stat; if (!lstat_path(path, fd_stat)) return false; if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) { string link_path; if (read_link_path(path, link_path)) return scan(link_path); return false; } bool is_dir = S_ISDIR(fd_stat.st_mode); if (!is_dir && !is_root_path && directory_only) return true; if (!is_dir && !accept_path(path)) return true; if (!add_watch(path, fd_stat)) return false; if (!recursive) return true; if (!is_dir) return true; vector<string> children = get_directory_children(path); for (string& child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; scan(path + "/" + child, false); } return true; }
void poll_monitor::scan(const string &path, poll_monitor_scan_callback fn) { struct stat fd_stat; if (!lstat_path(path, fd_stat)) return; if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) { string link_path; if (read_link_path(path, link_path)) scan(link_path, fn); return; } if (!S_ISDIR(fd_stat.st_mode) && !accept_path(path)) return; if (!add_path(path, fd_stat, fn)) return; if (!recursive) return; if (!S_ISDIR(fd_stat.st_mode)) return; vector<string> children = get_directory_children(path); for (string &child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; scan(path + "/" + child, fn); } }
void monitor::notify_events(const std::vector<event>& events) const { FSW_MONITOR_NOTIFY_GUARD; // Update the last notification timestamp #ifdef HAVE_INACTIVITY_CALLBACK milliseconds now = duration_cast<milliseconds>( system_clock::now().time_since_epoch()); last_notification.store(now); #endif std::vector<event> filtered_events; for (auto const& event : events) { // Filter flags std::vector<fsw_event_flag> filtered_flags = filter_flags(event); if (filtered_flags.empty()) continue; if (!accept_path(event.get_path())) continue; filtered_events.emplace_back(event.get_path(), event.get_time(), filtered_flags); } if (!filtered_events.empty()) { FSW_ELOG(string_utils::string_from_format(_("Notifying events #: %d.\n"), filtered_events.size()).c_str()); callback(filtered_events, context); } }
void inotify_monitor::scan(const string &path, const bool accept_non_dirs) { struct stat fd_stat; if (!stat_path(path, fd_stat)) return; /* * When watching a directory the inotify API will return change events of * first-level children. Therefore, we do not need to manually add a watch * for a child unless it is a directory. By default, accept_non_dirs is * true to allow watching a file when first invoked on a node. */ if (!accept_non_dirs && !S_ISDIR(fd_stat.st_mode)) return; else if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) { string link_path; if (read_link_path(path, link_path)) scan(link_path/*, fn */, accept_non_dirs); return; } if (!S_ISDIR(fd_stat.st_mode) && !accept_path(path)) return; if (!add_watch(path, fd_stat /*, fn */)) return; if (!recursive || !S_ISDIR(fd_stat.st_mode)) return; vector<string> children; get_directory_children(path, children); for (const string &child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; /* * Scan children but only watch directories. */ scan(path + "/" + child /*, fn */, false); } }
bool monitor::accept_path(const string &path) { return accept_path(path.c_str()); }