int evfilt_socket_knote_create(struct filter *filt, struct knote *kn) { struct epoll_event ev; if (linux_get_descriptor_type(kn) < 0) return (-1); /* TODO: return EBADF? */ if (kn->kn_flags & KNFL_REGULAR_FILE) return (-1); /* Convert the kevent into an epoll_event */ kn->data.events = EPOLLOUT; if (kn->kev.flags & EV_ONESHOT || kn->kev.flags & EV_DISPATCH) kn->data.events |= EPOLLONESHOT; if (kn->kev.flags & EV_CLEAR) kn->data.events |= EPOLLET; memset(&ev, 0, sizeof(ev)); ev.events = kn->data.events; ev.data.ptr = kn; return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev); }
int evfilt_read_knote_create(struct filter *filt, struct knote *kn) { struct epoll_event ev; if (linux_get_descriptor_type(kn) < 0) return (-1); /* Convert the kevent into an epoll_event */ #if defined(HAVE_EPOLLRDHUP) kn->data.events = EPOLLIN | EPOLLRDHUP; #else kn->data.events = EPOLLIN; #endif if (kn->kev.flags & EV_ONESHOT || kn->kev.flags & EV_DISPATCH) kn->data.events |= EPOLLONESHOT; if (kn->kev.flags & EV_CLEAR) kn->data.events |= EPOLLET; memset(&ev, 0, sizeof(ev)); ev.events = kn->data.events; ev.data.ptr = kn; /* Special case: for regular files, add a surrogate eventfd that is always readable */ if (kn->kn_flags & KNFL_FILE) { int evfd; kn->kn_epollfd = filter_epfd(filt); evfd = eventfd(0, 0); if (evfd < 0) { dbg_perror("eventfd(2)"); return (-1); } if (eventfd_write(evfd, 1) < 0) { dbg_perror("eventfd_write(3)"); (void) close(evfd); return (-1); } kn->kdata.kn_eventfd = evfd; if (epoll_ctl(kn->kn_epollfd, EPOLL_CTL_ADD, kn->kdata.kn_eventfd, &ev) < 0) { dbg_printf("epoll_ctl(2): %s", strerror(errno)); return (-1); } kn->kn_registered = 1; return (0); } return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev); }