/* 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
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 =
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;
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;
}
/* 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);
/* 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);
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);
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;
/* 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))
;; Return result.
(cdr file-notify--test-remote-enabled-checked))
+(defun file-notify--test-library ()
+ "The used libray for the test, as string.
+In the remote case, it is the process name which runs on the
+remote host, or nil."
+ (if (null (file-remote-p temporary-file-directory))
+ (symbol-name file-notify--library)
+ (and (consp file-notify--test-remote-enabled-checked)
+ (processp (cdr file-notify--test-remote-enabled-checked))
+ (replace-regexp-in-string
+ "<[[:digit:]]+>\\'" ""
+ (process-name (cdr file-notify--test-remote-enabled-checked))))))
+
(defmacro file-notify--deftest-remote (test docstring)
"Define ert `TEST-remote' for remote files."
(declare (indent 1))
"Test availability of `file-notify'."
(skip-unless (file-notify--test-local-enabled))
;; Report the native library which has been used.
- (if (null (file-remote-p temporary-file-directory))
- (message "Local library: `%s'" file-notify--library)
- (message "Remote command: `%s'"
- (replace-regexp-in-string
- "<[[:digit:]]+>\\'" ""
- (process-name (cdr file-notify--test-remote-enabled-checked)))))
+ (message "Library: `%s'" (file-notify--test-library))
(should
(setq file-notify--test-desc
(file-notify-add-watch temporary-file-directory '(change) 'ignore)))
(file-notify--test-with-events '(created changed deleted)
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
+ (read-event nil nil 0.1)
(delete-file file-notify--test-tmpfile))
;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
(let (file-notify--test-events)
;; Check creation, change and deletion. There must be a
;; `stopped' event when deleting the directory. It doesn't
;; work for w32notify.
- (unless (eq file-notify--library 'w32notify)
+ (unless (string-equal (file-notify--test-library) "w32notify")
(make-directory file-notify--test-tmpfile)
(setq file-notify--test-desc
(file-notify-add-watch
'(change) 'file-notify--test-event-handler))
(file-notify--test-with-events
;; There are two `deleted' events, for the file and for
- ;; the directory.
- '(created changed deleted deleted stopped)
+ ;; the directory. Except for kqueue.
+ (if (string-equal (file-notify--test-library) "kqueue")
+ '(created changed deleted stopped)
+ '(created changed deleted deleted stopped))
(write-region
"any text" nil (expand-file-name "foo" file-notify--test-tmpfile)
nil 'no-message)
+ (read-event nil nil 0.1)
(delete-directory file-notify--test-tmpfile 'recursive))
;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
(let (file-notify--test-events)
(file-notify--test-with-events
;; w32notify does not distinguish between `changed' and
;; `attribute-changed'.
- (if (eq file-notify--library 'w32notify)
+ (if (string-equal (file-notify--test-library) "w32notify")
'(created changed changed deleted)
'(created changed deleted))
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
+ (read-event nil nil 0.1)
(copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
;; The next two events shall not be visible.
+ (read-event nil nil 0.1)
(set-file-modes file-notify--test-tmpfile 000)
- (read-event nil nil 0.1) ; In order to distinguish the events.
+ (read-event nil nil 0.1)
(set-file-times file-notify--test-tmpfile '(0 0))
+ (read-event nil nil 0.1)
(delete-file file-notify--test-tmpfile)
+ (read-event nil nil 0.1)
(delete-file file-notify--test-tmpfile1))
;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
(let (file-notify--test-events)
(file-notify--test-with-events '(created changed renamed)
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
+ (read-event nil nil 0.1)
(rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
;; After the rename, we won't get events anymore.
+ (read-event nil nil 0.1)
(delete-file file-notify--test-tmpfile1))
;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
(let (file-notify--test-events)
(file-notify-rm-watch file-notify--test-desc))
- ;; Check attribute change. It doesn't work for w32notify.
- (unless (eq file-notify--library 'w32notify)
+ ;; Check attribute change. It doesn't work for kqueue and w32notify.
+ (unless (or (string-equal (file-notify--test-library) "kqueue")
+ (string-equal (file-notify--test-library) "w32notify"))
(setq file-notify--test-desc
(file-notify-add-watch
file-notify--test-tmpfile
(should (file-notify-valid-p file-notify--test-desc))
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
+ (read-event nil nil 0.1)
(delete-file file-notify--test-tmpfile))
;; After deleting the file, the descriptor is still valid.
(should (file-notify-valid-p file-notify--test-desc))
(unwind-protect
;; The batch-mode operation of w32notify is fragile (there's no
;; input threads to send the message to).
- ;(unless (and noninteractive (eq file-notify--library 'w32notify))
- (unless (eq file-notify--library 'w32notify)
+ (unless (string-equal (file-notify--test-library) "w32notify")
(let ((temporary-file-directory
(make-temp-file "file-notify-test-parent" t)))
(setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
(file-notify-add-watch
file-notify--test-tmpfile
'(change) #'file-notify--test-event-handler))
- (file-notify--test-with-events '(created changed deleted stopped)
+ (file-notify--test-with-events
+ ;; There are two `deleted' events, for the file and for
+ ;; the directory. Except for kqueue.
+ (if (string-equal (file-notify--test-library) "kqueue")
+ '(created changed deleted stopped)
+ '(created changed deleted deleted stopped))
(should (file-notify-valid-p file-notify--test-desc))
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
+ (read-event nil nil 0.1)
(delete-directory temporary-file-directory t))
;; After deleting the parent directory, the descriptor must
;; not be valid anymore.
(unwind-protect
;; The batch-mode operation of w32notify is fragile (there's no
;; input threads to send the message to).
- (unless (and noninteractive (eq file-notify--library 'w32notify))
+ (unless (and noninteractive
+ (string-equal (file-notify--test-library) "w32notify"))
(setq file-notify--test-tmpfile
(file-name-as-directory (file-notify--test-make-temp-name)))
(make-directory file-notify--test-tmpfile)