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;
  }
Exemple #2
0
  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);
    }
  }
Exemple #3
0
  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);
    }
  }
Exemple #5
0
 bool monitor::accept_path(const string &path)
 {
   return accept_path(path.c_str());
 }