예제 #1
0
파일: inotify.c 프로젝트: 7696122/emacs
/* This callback is called when the FD is available for read.  The inotify
   events are read from FD and converted into input_events.  */
static void
inotify_callback (int fd, void *_)
{
  struct input_event event;
  Lisp_Object watch_object;
  int to_read;
  char *buffer;
  ssize_t n;
  size_t i;

  to_read = 0;
  if (ioctl (fd, FIONREAD, &to_read) == -1)
    report_file_notify_error ("Error while retrieving file system events",
			      Qnil);
  buffer = xmalloc (to_read);
  n = read (fd, buffer, to_read);
  if (n < 0)
    {
      xfree (buffer);
      report_file_notify_error ("Error while reading file system events", Qnil);
    }

  EVENT_INIT (event);
  event.kind = FILE_NOTIFY_EVENT;

  i = 0;
  while (i < (size_t)n)
    {
      struct inotify_event *ev = (struct inotify_event*)&buffer[i];

      watch_object = Fassoc (make_watch_descriptor (ev->wd), watch_list);
      if (!NILP (watch_object))
        {
          event.arg = inotifyevent_to_event (watch_object, ev);

          /* If event was removed automatically: Drop it from watch list.  */
          if (ev->mask & IN_IGNORED)
            watch_list = Fdelete (watch_object, watch_list);

	  if (!NILP (event.arg))
	    kbd_buffer_store_event (&event);
        }

      i += sizeof (*ev) + ev->len;
    }

  xfree (buffer);
}
예제 #2
0
/*  Remove all watches associated with the watch list element after
    PREVTAIL, or after the first element if PREVTAIL is t.  If INVALID_P
    is true, the descriptor is already invalid, i.e., it received a
    IN_IGNORED event.  In this case skip calling inotify_rm_watch.  */
static void
remove_descriptor (Lisp_Object prevtail, bool invalid_p)
{
  Lisp_Object tail = CONSP (prevtail) ? XCDR (prevtail) : watch_list;

  int inotify_errno = 0;
  if (! invalid_p)
    {
      int wd;
      CONS_TO_INTEGER (XCAR (XCAR (tail)), int, wd);
      if (inotify_rm_watch (inotifyfd, wd) != 0)
	inotify_errno = errno;
    }

  if (CONSP (prevtail))
    XSETCDR (prevtail, XCDR (tail));
  else
    {
      watch_list = XCDR (tail);
      if (NILP (watch_list))
	{
	  delete_read_fd (inotifyfd);
	  emacs_close (inotifyfd);
	  inotifyfd = -1;
	}
    }

  if (inotify_errno != 0)
    {
      errno = inotify_errno;
      report_file_notify_error ("Could not rm watch", XCAR (tail));
    }
}
예제 #3
0
/* This callback is called when the FD is available for read.  The inotify
   events are read from FD and converted into input_events.  */
static void
inotify_callback (int fd, void *_)
{
  int to_read;
  if (ioctl (fd, FIONREAD, &to_read) < 0)
    report_file_notify_error ("Error while retrieving file system events",
			      Qnil);
  USE_SAFE_ALLOCA;
  char *buffer = SAFE_ALLOCA (to_read);
  ssize_t n = read (fd, buffer, to_read);
  if (n < 0)
    report_file_notify_error ("Error while reading file system events", Qnil);

  struct input_event event;
  EVENT_INIT (event);
  event.kind = FILE_NOTIFY_EVENT;

  for (ssize_t i = 0; i < n; )
    {
      struct inotify_event *ev = (struct inotify_event *) &buffer[i];
      Lisp_Object descriptor = INTEGER_TO_CONS (ev->wd);
      Lisp_Object prevtail = find_descriptor (descriptor);

      if (! NILP (prevtail))
        {
	  Lisp_Object tail = CONSP (prevtail) ? XCDR (prevtail) : watch_list;
	  for (Lisp_Object watches = XCDR (XCAR (tail)); ! NILP (watches);
	       watches = XCDR (watches))
            {
              event.arg = inotifyevent_to_event (XCAR (watches), ev);
              if (!NILP (event.arg))
                kbd_buffer_store_event (&event);
            }
          /* If event was removed automatically: Drop it from watch list.  */
          if (ev->mask & IN_IGNORED)
	    remove_descriptor (prevtail, true);
        }
      i += sizeof (*ev) + ev->len;
    }

  SAFE_FREE ();
}
예제 #4
0
파일: inotify.c 프로젝트: 7696122/emacs
static uint32_t
symbol_to_inotifymask (Lisp_Object symb)
{
  if (EQ (symb, Qaccess))
    return IN_ACCESS;
  else if (EQ (symb, Qattrib))
    return IN_ATTRIB;
  else if (EQ (symb, Qclose_write))
    return IN_CLOSE_WRITE;
  else if (EQ (symb, Qclose_nowrite))
    return IN_CLOSE_NOWRITE;
  else if (EQ (symb, Qcreate))
    return IN_CREATE;
  else if (EQ (symb, Qdelete))
    return IN_DELETE;
  else if (EQ (symb, Qdelete_self))
    return IN_DELETE_SELF;
  else if (EQ (symb, Qmodify))
    return IN_MODIFY;
  else if (EQ (symb, Qmove_self))
    return IN_MOVE_SELF;
  else if (EQ (symb, Qmoved_from))
    return IN_MOVED_FROM;
  else if (EQ (symb, Qmoved_to))
    return IN_MOVED_TO;
  else if (EQ (symb, Qopen))
    return IN_OPEN;
  else if (EQ (symb, Qmove))
    return IN_MOVE;
  else if (EQ (symb, Qclose))
    return IN_CLOSE;

  else if (EQ (symb, Qdont_follow))
    return IN_DONT_FOLLOW;
  else if (EQ (symb, Qexcl_unlink))
    return IN_EXCL_UNLINK;
  else if (EQ (symb, Qmask_add))
    return IN_MASK_ADD;
  else if (EQ (symb, Qoneshot))
    return IN_ONESHOT;
  else if (EQ (symb, Qonlydir))
    return IN_ONLYDIR;

  else if (EQ (symb, Qt) || EQ (symb, Qall_events))
    return IN_ALL_EVENTS;
  else
    {
      errno = EINVAL;
      report_file_notify_error ("Unknown aspect", symb);
    }
}