/* 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); }
/* 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 (); }