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"); }
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"); }