Esempio n. 1
0
/* 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);
}
Esempio n. 2
0
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);