/* Add a new watch to watch-descriptor WD watching FILENAME and using CALLBACK. Returns a cons (DESCRIPTOR . ID) uniquely identifying the new watch. */ static Lisp_Object add_watch (int wd, Lisp_Object filename, Lisp_Object aspect, Lisp_Object callback) { Lisp_Object descriptor = INTEGER_TO_CONS (wd); Lisp_Object tail = assoc_no_quit (descriptor, watch_list); Lisp_Object watch, watch_id; uint32_t imask = aspect_to_inotifymask (aspect); Lisp_Object mask = INTEGER_TO_CONS (imask); EMACS_INT id = 0; if (NILP (tail)) { tail = list1 (descriptor); watch_list = Fcons (tail, watch_list); } else { /* Assign a watch ID that is not already in use, by looking for a gap in the existing sorted list. */ for (; ! NILP (XCDR (tail)); tail = XCDR (tail), id++) if (!EQ (XCAR (XCAR (XCDR (tail))), make_number (id))) break; if (MOST_POSITIVE_FIXNUM < id) emacs_abort (); } /* Insert the newly-assigned ID into the previously-discovered gap, which is possibly at the end of the list. Inserting it there keeps the list sorted. */ watch_id = make_number (id); watch = list4 (watch_id, filename, callback, mask); XSETCDR (tail, Fcons (watch, XCDR (tail))); return Fcons (descriptor, watch_id); }
See inotify(7) and inotify_add_watch(2) for further information. The inotify fd is managed internally and there is no corresponding inotify_init. Use `inotify-rm-watch' to remove a watch. The following inotify bit-masks cannot be used because descriptors are shared across different callers. IN_EXCL_UNLINK IN_MASK_ADD IN_ONESHOT */) (Lisp_Object filename, Lisp_Object aspect, Lisp_Object callback) { Lisp_Object encoded_file_name; int wd = -1; uint32_t imask = aspect_to_inotifymask (aspect); uint32_t mask = imask | IN_MASK_ADD | IN_EXCL_UNLINK; CHECK_STRING (filename); if (inotifyfd < 0) { inotifyfd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC); if (inotifyfd < 0) report_file_notify_error ("File watching is not available", Qnil); watch_list = Qnil; add_read_fd (inotifyfd, &inotify_callback, NULL); } encoded_file_name = ENCODE_FILE (filename); wd = inotify_add_watch (inotifyfd, SSDATA (encoded_file_name), mask);