static int add_watch(struct filter *filt, struct knote *kn) { char path[PATH_MAX]; uint32_t mask; /* Convert the fd to a pathname */ if (fd_to_path(&path[0], sizeof(path), kn->kev.ident) < 0) return (-1); /* Convert the fflags to the inotify mask */ mask = 0; if (kn->kev.fflags & NOTE_DELETE) mask |= IN_ATTRIB | IN_DELETE_SELF; if (kn->kev.fflags & NOTE_WRITE) mask |= IN_MODIFY | IN_ATTRIB; if (kn->kev.fflags & NOTE_EXTEND) mask |= IN_MODIFY | IN_ATTRIB; if ((kn->kev.fflags & NOTE_ATTRIB) || (kn->kev.fflags & NOTE_LINK)) mask |= IN_ATTRIB; if (kn->kev.fflags & NOTE_RENAME) mask |= IN_MOVE_SELF; if (kn->kev.flags & EV_ONESHOT) mask |= IN_ONESHOT; dbg_printf("inotify_add_watch(2); inofd=%d, %s, path=%s", filt->kf_pfd, inotify_mask_dump(mask), path); kn->kev.data = inotify_add_watch(filt->kf_pfd, path, mask); if (kn->kev.data < 0) { dbg_printf("inotify_add_watch(2): %s", strerror(errno)); return (-1); } return (0); }
static char * inotify_event_dump(struct inotify_event *evt) { static __thread char buf[1024]; snprintf(buf, sizeof(buf), "wd=%d mask=%s", evt->wd, inotify_mask_dump(evt->mask)); return (buf); }
static int add_watch(struct filter *filt, struct knote *kn) { struct epoll_event ev; int ifd; char path[PATH_MAX]; uint32_t mask; /* Convert the fd to a pathname */ if (linux_fd_to_path(&path[0], sizeof(path), kn->kev.ident) < 0) return (-1); /* Convert the fflags to the inotify mask */ mask = IN_CLOSE; if (kn->kev.fflags & NOTE_DELETE) mask |= IN_ATTRIB | IN_DELETE_SELF; if (kn->kev.fflags & NOTE_WRITE) mask |= IN_MODIFY | IN_ATTRIB; if (kn->kev.fflags & NOTE_EXTEND) mask |= IN_MODIFY | IN_ATTRIB; if ((kn->kev.fflags & NOTE_ATTRIB) || (kn->kev.fflags & NOTE_LINK)) mask |= IN_ATTRIB; if (kn->kev.fflags & NOTE_RENAME) mask |= IN_MOVE_SELF; if (kn->kev.flags & EV_ONESHOT) mask |= IN_ONESHOT; /* Create an inotify descriptor */ ifd = inotify_init(); if (ifd < 0) { dbg_perror("inotify_init(2)"); return (-1); } /* Add the watch */ dbg_printf("inotify_add_watch(2); inofd=%d, %s, path=%s", ifd, inotify_mask_dump(mask), path); kn->kev.data = inotify_add_watch(ifd, path, mask); if (kn->kev.data < 0) { dbg_perror("inotify_add_watch(2)"); goto errout; } /* Add the inotify fd to the epoll set */ memset(&ev, 0, sizeof(ev)); ev.events = EPOLLIN; ev.data.ptr = kn; if (epoll_ctl(filter_epfd(filt), EPOLL_CTL_ADD, ifd, &ev) < 0) { dbg_perror("epoll_ctl(2)"); goto errout; } kn->kdata.kn_inotifyfd = ifd; return (0); errout: kn->kdata.kn_inotifyfd = -1; (void) close(ifd); return (-1); }