:PROPERTIES: :ID: fad57303-ce0c-4ae4-9529-294f70ecfaa5 :mtime: 20220107081819 :ctime: 20220106214423 :END: #+title: Inotify * Présentation Mécanisme du noyan Linux fournissant des notifications concernant le système de fichiers. * Exemples ** C++ #+BEGIN_SRC C++ :tangle "/tmp/dummy.cpp" :results output #include #include #include #include #include #include #include static void onInotify(int fd) { std::cout << "onInotify(" << fd << ")" << std::endl; bool finished = false; while (!finished) { struct inotify_event event; const ssize_t len = read(fd, &event, sizeof(event)); if (len == -1 && errno != EAGAIN) { std::cout << "!read " << strerror(errno); finished = true; } // If the nonblocking read() found no events to read, then // it returns -1 with errno set to EAGAIN. // Nothing to read here, exit the loop. if (len <= 0) { finished = true; } else { // Print event type. if (event.mask & IN_OPEN) { std::cout << "IN_OPEN: "; } if (event.mask & IN_CLOSE_NOWRITE) { std::cout << "IN_CLOSE_NOWRITE: "; } if (event.mask & IN_CLOSE_WRITE) { std::cout << "IN_CLOSE_WRITE: "; } // Print the name of the file. if (event.len) { std::cout << event.name << std::endl; } // Print type of filesystem object. if (event.mask & IN_ISDIR) { std::cout << " [directory]" << std::endl; } else { std::cout << " [file]" << std::endl; } } } } int main(int argc, char** argv) { const std::string filename = "/tmp/dummy"; // Make sure the filename exists. struct stat buffer; if (stat(filename.c_str(), &buffer) != 0) { std::cout << filename << " doesn't exists... create it." << std::endl; std::ofstream dummy(filename); } const int fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); if (fd < 0) { std::cout << "Unable to init inotify: " << strerror(errno) << std::endl; exit(EXIT_FAILURE); } // Trigger on open and close events. const int wd = inotify_add_watch(fd, filename.c_str(), IN_OPEN | IN_CLOSE); if (wd == -1) { std::cout << "Cannot watch '" << filename << "': " << strerror(errno) << std::endl; close(fd); exit(EXIT_FAILURE); } // Prepare for pooling. const nfds_t nfds = 2; struct pollfd fds[2]; // Console input fds[0].fd = STDIN_FILENO; fds[0].events = POLLIN; // Inotify input fds[1].fd = fd; fds[1].events = POLLIN; // Wait for events and/or terminal input. std::cout << "Listening for events." << std::endl; bool stop = false; bool error = false; while (!stop) { const int poll_num = poll(fds, nfds, -1); if (poll_num == -1) { if (errno == EINTR) { continue; } std::cout << "poll" << std::endl; error = stop = true; } else if (poll_num > 0) { if (fds[0].revents & POLLIN) { // Console input is available. Empty stdin and quit. char buf; while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n') { continue; } std::cout << "Stopping resquested..." << std::endl; break; } if (fds[1].revents & POLLIN) { // Inotify events are available. onInotify(fd); } } } std::cout << "Listening for events stopped." << std::endl; /* Close inotify file descriptor. */ close(fd); exit(EXIT_SUCCESS); } #+END_SRC * Références * inotify(7) — Linux manual page]]