diff options
| author | Michael Albinus <michael.albinus@gmx.de> | 2015-11-18 13:47:25 +0000 |
|---|---|---|
| committer | Michael Albinus <michael.albinus@gmx.de> | 2015-11-25 15:07:11 +0100 |
| commit | 65ba5a98d47f4305f95f960efdf424684754a11d (patch) | |
| tree | 644b229abb093a6024446bf4655d1aa0b460b453 /src/kqueue.c | |
| parent | 13f3508443e4f5c48d40e4dbb11eaf875a5b2042 (diff) | |
| download | emacs-65ba5a98d47f4305f95f960efdf424684754a11d.tar.gz | |
Further fixes for kqueue.
* lisp/filenotify.el (file-notify-callback): Raise also event if
directory name matches.
(file-notify-add-watch): Add `create' to the flags for `kqueue'.
* src/kqueue.c (kqueue_generate_event): Use watch_object as
argument instead of ident. Remove callback argument. Adapt
callees. Check actions whether they are monitored flags.
* test/automated/file-notify-tests.el (file-notify--test-library):
New defun.
(file-notify-test00-availability, file-notify-test02-events)
(file-notify-test04-file-validity)
(file-notify-test05-dir-validity): Use it.
(file-notify-test02-events, file-notify-test04-file-validity): Add
`read-event' calls between different file actions, in order to
give the backends a chance to rais an event. Needed especially
for kqueue. In case of deleting a directory, there are two
`deleted' events.
Diffstat (limited to 'src/kqueue.c')
| -rw-r--r-- | src/kqueue.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/src/kqueue.c b/src/kqueue.c index 5caef67b92a..e2c9dabcb20 100644 --- a/src/kqueue.c +++ b/src/kqueue.c @@ -67,21 +67,39 @@ kqueue_directory_listing (Lisp_Object directory_files) /* Generate a file notification event. */ static void kqueue_generate_event -(Lisp_Object ident, Lisp_Object actions, Lisp_Object file, Lisp_Object file1, - Lisp_Object callback) +(Lisp_Object watch_object, Lisp_Object actions, + Lisp_Object file, Lisp_Object file1) { + Lisp_Object flags, action, entry; struct input_event event; - EVENT_INIT (event); - event.kind = FILE_NOTIFY_EVENT; - event.frame_or_window = Qnil; - event.arg = list2 (Fcons (ident, Fcons (actions, - NILP (file1) - ? Fcons (file, Qnil) - : list2 (file, file1))), - callback); + + /* Check, whether all actions shall be monitored. */ + flags = Fnth (make_number (2), watch_object); + action = actions; + do { + if (NILP (action)) + break; + entry = XCAR (action); + if (NILP (Fmember (entry, flags))) { + action = XCDR (action); + actions = Fdelq (entry, actions); + } else + action = XCDR (action); + } while (1); /* Store it into the input event queue. */ - kbd_buffer_store_event (&event); + if (! NILP (actions)) { + EVENT_INIT (event); + event.kind = FILE_NOTIFY_EVENT; + event.frame_or_window = Qnil; + event.arg = list2 (Fcons (XCAR (watch_object), + Fcons (actions, + NILP (file1) + ? Fcons (file, Qnil) + : list2 (file, file1))), + Fnth (make_number (3), watch_object)); + kbd_buffer_store_event (&event); + } } /* This compares two directory listings in case of a `write' event for @@ -93,19 +111,16 @@ static void kqueue_compare_dir_list (Lisp_Object watch_object) { - Lisp_Object dir, callback; - Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl; + Lisp_Object dir, old_directory_files, old_dl, new_directory_files, new_dl, dl; dir = XCAR (XCDR (watch_object)); - callback = Fnth (make_number (3), watch_object); old_directory_files = Fnth (make_number (4), watch_object); old_dl = kqueue_directory_listing (old_directory_files); /* When the directory is not accessible anymore, it has been deleted. */ if (NILP (Ffile_directory_p (dir))) { - kqueue_generate_event - (XCAR (watch_object), Fcons (Qdelete, Qnil), dir, Qnil, callback); + kqueue_generate_event (watch_object, Fcons (Qdelete, Qnil), dir, Qnil); return; } new_directory_files = @@ -137,21 +152,20 @@ kqueue_compare_dir_list if (NILP (Fequal (Fnth (make_number (2), old_entry), Fnth (make_number (2), new_entry)))) kqueue_generate_event - (XCAR (watch_object), Fcons (Qwrite, Qnil), - XCAR (XCDR (old_entry)), Qnil, callback); + (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil); /* Status change time has been changed, the file attributes have changed. */ if (NILP (Fequal (Fnth (make_number (3), old_entry), Fnth (make_number (3), new_entry)))) kqueue_generate_event - (XCAR (watch_object), Fcons (Qattrib, Qnil), - XCAR (XCDR (old_entry)), Qnil, callback); + (watch_object, Fcons (Qattrib, Qnil), + XCAR (XCDR (old_entry)), Qnil); } else { /* The file has been renamed. */ kqueue_generate_event - (XCAR (watch_object), Fcons (Qrename, Qnil), - XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry)), callback); + (watch_object, Fcons (Qrename, Qnil), + XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); } new_dl = Fdelq (new_entry, new_dl); goto the_end; @@ -164,8 +178,7 @@ kqueue_compare_dir_list if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { kqueue_generate_event - (XCAR (watch_object), Fcons (Qwrite, Qnil), - XCAR (XCDR (old_entry)), Qnil, callback); + (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil); new_dl = Fdelq (new_entry, new_dl); goto the_end; } @@ -173,8 +186,7 @@ kqueue_compare_dir_list /* The file has been deleted. */ kqueue_generate_event - (XCAR (watch_object), Fcons (Qdelete, Qnil), - XCAR (XCDR (old_entry)), Qnil, callback); + (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil); the_end: dl = XCDR (dl); @@ -191,15 +203,13 @@ kqueue_compare_dir_list /* A new file has appeared. */ new_entry = XCAR (dl); kqueue_generate_event - (XCAR (watch_object), Fcons (Qcreate, Qnil), - XCAR (XCDR (new_entry)), Qnil, callback); + (watch_object, Fcons (Qcreate, Qnil), XCAR (XCDR (new_entry)), Qnil); /* Check size of that file. */ Lisp_Object size = Fnth (make_number (4), new_entry); if (FLOATP (size) || (XINT (size) > 0)) kqueue_generate_event - (XCAR (watch_object), Fcons (Qwrite, Qnil), - XCAR (XCDR (new_entry)), Qnil, callback); + (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (new_entry)), Qnil); dl = XCDR (dl); new_dl = Fdelq (new_entry, new_dl); @@ -226,7 +236,7 @@ kqueue_callback (int fd, void *data) for (;;) { struct kevent kev; static const struct timespec nullts = { 0, 0 }; - Lisp_Object descriptor, watch_object, file, callback, actions; + Lisp_Object descriptor, watch_object, file, actions; /* Read one event. */ int ret = kevent (kqueuefd, NULL, 0, &kev, 1, &nullts); @@ -235,14 +245,11 @@ kqueue_callback (int fd, void *data) return; } - /* Determine descriptor, file name and callback function. */ + /* Determine descriptor and file name. */ descriptor = make_number (kev.ident); watch_object = assq_no_quit (descriptor, watch_list); - - if (CONSP (watch_object)) { + if (CONSP (watch_object)) file = XCAR (XCDR (watch_object)); - callback = Fnth (make_number (3), watch_object); - } else continue; @@ -271,7 +278,7 @@ kqueue_callback (int fd, void *data) /* Create the event. */ if (! NILP (actions)) - kqueue_generate_event (descriptor, actions, file, Qnil, callback); + kqueue_generate_event (watch_object, actions, file, Qnil); /* Cancel monitor if file or directory is deleted or renamed. */ if (kev.fflags & (NOTE_DELETE | NOTE_RENAME)) |
