Esempio n. 1
0
Status INotifyEventPublisher::run() {
  // Get a while wrapper for free.
  char buffer[BUFFER_SIZE];
  fd_set set;

  FD_ZERO(&set);
  FD_SET(getHandle(), &set);

  struct timeval timeout = {3, 3000};
  int selector = ::select(getHandle() + 1, &set, nullptr, nullptr, &timeout);
  if (selector == -1) {
    LOG(ERROR) << "Could not read inotify handle";
    return Status(1, "INotify handle failed");
  }

  if (selector == 0) {
    // Read timeout.
    return Status(0, "Continue");
  }
  ssize_t record_num = ::read(getHandle(), buffer, BUFFER_SIZE);
  if (record_num == 0 || record_num == -1) {
    return Status(1, "INotify read failed");
  }

  for (char* p = buffer; p < buffer + record_num;) {
    // Cast the inotify struct, make shared pointer, and append to contexts.
    auto event = reinterpret_cast<struct inotify_event*>(p);
    if (event->mask & IN_Q_OVERFLOW) {
      // The inotify queue was overflown (remove all paths).
      Status stat = restartMonitoring();
      if(!stat.ok()){
        return stat;
      }
    }

    if (event->mask & IN_IGNORED) {
      // This inotify watch was removed.
      removeMonitor(event->wd, false);
    } else if (event->mask & IN_MOVE_SELF) {
      // This inotify path was moved, but is still watched.
      removeMonitor(event->wd, true);
    } else if (event->mask & IN_DELETE_SELF) {
      // A file was moved to replace the watched path.
      removeMonitor(event->wd, false);
    } else {
      auto ec = createEventContextFrom(event);
      if(event->mask & IN_CREATE && isDirectory(ec->path).ok()){
        addMonitor(ec->path, 1);
      }
      fire(ec);
    }
    // Continue to iterate
    p += (sizeof(struct inotify_event)) + event->len;
  }

  osquery::publisherSleep(kINotifyMLatency);
  return Status(0, "Continue");
}
Esempio n. 2
0
Status UdevEventPublisher::run() {
  int fd = 0;

  {
    WriteLock lock(mutex_);
    if (monitor_ == nullptr) {
      return Status(1);
    }
    fd = udev_monitor_get_fd(monitor_);
  }

  struct pollfd fds[1];
  fds[0].fd = fd;
  fds[0].events = POLLIN;

  int selector = ::poll(fds, 1, 1000);
  if (selector == -1 && errno != EINTR && errno != EAGAIN) {
    LOG(ERROR) << "Could not read udev monitor";
    return Status(1, "udev monitor failed.");
  }

  if (selector == 0 || !(fds[0].revents & POLLIN)) {
    // Read timeout.
    return Status(0, "Finished");
  }

  {
    WriteLock lock(mutex_);
    struct udev_device* device = udev_monitor_receive_device(monitor_);
    if (device == nullptr) {
      LOG(ERROR) << "udev monitor returned invalid device";
      return Status(1, "udev monitor failed.");
    }

    auto ec = createEventContextFrom(device);
    fire(ec);

    udev_device_unref(device);
  }

  pauseMilli(kUdevMLatency);
  return Status(0, "OK");
}