Commit 7bf54d01 authored by Michael Albinus's avatar Michael Albinus

Backport kqueue integration from master

* configure.ac (--with-file-notification): Add kqueue.
(top): Remove special test for "${HAVE_NS}" and
${with_file_notification}, this is handled inside gfilenotify
tests.  Add kqueue tests.  Use NOTIFY_CFLAGS and NOTIFY_LIBS
instead of library specific variables.  Add error message for
gfile on Nextstep.

* doc/lispref/os.texi (File Notifications): Add kqueue as backend.
Fix some glitches in the example.

* etc/NEWS: Mention kqueue.

* lisp/filenotify.el (file-notify--library)
(file-notify-descriptors, file-notify-callback)
(file-notify-add-watch, file-notify-rm-watch)
(file-notify-valid-p): Add kqueue support.
(file-notify--rm-descriptor): Remove WHAT arg.

* src/Makefile.in: Use NOTIFY_CFLAGS and NOTIFY_LIBS.

* src/emacs.c (main): Call globals_of_kqueue and syms_of_kqueue.

* src/inotify.c (inotifyevent_to_event): Extract file name from
watch_object if the event doesn't provide it.
(Finotify_add_watch): Add file name to watch_object.

* src/keyboard.c (make_lispy_event): Check also for HAVE_KQUEUE.

* src/kqueue.c: New file.

* src/lisp.h: Declare extern globals_of_kqueue and syms_of_kqueue.

* test/automated/file-notify-tests.el
(file-notify--test-expected-events): Remove.
(file-notify--test-cleanup): Do not set that variable.
(file-notify--test-timeout) Use different timeouts for
different libraries.
(file-notify--test-library): New defun.
(file-notify--test-event-test): Make stronger checks.
(file-notify--test-with-events): EVENTS can also be a list of
lists.  Flush outstanding events before running the body.
Make timeout heuristically depend on the number of events.
(file-notify-test01-add-watch, file-notify-test02-events)
(file-notify-test04-file-validity, file-notify-test05-dir-validity):
Rewrite in order to call file monitors but directory monitors.
(file-notify-test02-events, file-notify-test04-file-validity): Do
not skip cygwin tests.  Add additional test for file creation.
Adapt expected result for different backends.
(file-notify-test03-autorevert): Some of the tests don't work for
w32notify.
(file-notify-test06-many-events): New test.
parent f7dc6d8b
......@@ -356,17 +356,18 @@ OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support])
OPTION_DEFAULT_OFF([modules],[compile with dynamic modules support])
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
[use a file notification library (LIB one of: yes, gfile, inotify, w32, no)])],
[use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])],
[ case "${withval}" in
y | ye | yes ) val=yes ;;
n | no ) val=no ;;
g | gf | gfi | gfil | gfile ) val=gfile ;;
i | in | ino | inot | inoti | inotif | inotify ) val=inotify ;;
k | kq | kqu | kque | kqueu | kqueue ) val=kqueue ;;
g | gf | gfi | gfil | gfile ) val=gfile ;;
w | w3 | w32 ) val=w32 ;;
* ) AC_MSG_ERROR(['--with-file-notification=$withval' is invalid;
this option's value should be 'yes', 'no', 'gfile', 'inotify' or 'w32'.
this option's value should be 'yes', 'no', 'inotify', 'kqueue', 'gfile' or 'w32'.
'yes' is a synonym for 'w32' on MS-Windows, for 'no' on Nextstep,
otherwise for the first of 'inotify' or 'gfile' that is usable.])
otherwise for the first of 'inotify', 'kqueue' or 'gfile' that is usable.])
;;
esac
with_file_notification=$val
......@@ -2712,12 +2713,6 @@ AC_SUBST(LIBGNUTLS_CFLAGS)
NOTIFY_OBJ=
NOTIFY_SUMMARY=no
dnl FIXME? Don't auto-detect on NS, but do allow someone to specify
dnl a particular library. This doesn't make much sense?
if test "${HAVE_NS}" = yes && test ${with_file_notification} = yes; then
with_file_notification=no
fi
dnl MS Windows native file monitor is available for mingw32 only.
case $with_file_notification,$opsys in
w32,cygwin)
......@@ -2748,16 +2743,44 @@ case $with_file_notification,$NOTIFY_OBJ in
fi ;;
esac
dnl kqueue is available on BSD-like systems.
case $with_file_notification,$NOTIFY_OBJ in
kqueue,* | yes,)
EMACS_CHECK_MODULES([KQUEUE], [libkqueue])
if test "$HAVE_KQUEUE" = "yes"; then
AC_DEFINE(HAVE_KQUEUE, 1, [Define to 1 to use kqueue.])
CPPFLAGS="$CPPFLAGS -I/usr/include/kqueue"
NOTIFY_CFLAGS=$KQUEUE_CFLAGS
NOTIFY_LIBS=$KQUEUE_LIBS
NOTIFY_OBJ=kqueue.o
NOTIFY_SUMMARY="yes -lkqueue"
else
AC_SEARCH_LIBS(kqueue, [])
if test "$ac_cv_search_kqueue" != no; then
AC_DEFINE(HAVE_KQUEUE, 1, [Define to 1 to use kqueue.])
NOTIFY_OBJ=kqueue.o
NOTIFY_SUMMARY="yes (kqueue)"
fi
fi ;;
esac
dnl g_file_monitor exists since glib 2.18. G_FILE_MONITOR_EVENT_MOVED
dnl has been added in glib 2.24. It has been tested under
dnl GNU/Linux only.
case $with_file_notification,$NOTIFY_OBJ in
gfile,* | yes,)
EMACS_CHECK_MODULES([GFILENOTIFY], [gio-2.0 >= 2.24])
if test "$HAVE_GFILENOTIFY" = "yes"; then
AC_DEFINE(HAVE_GFILENOTIFY, 1, [Define to 1 if using GFile.])
NOTIFY_OBJ=gfilenotify.o
NOTIFY_SUMMARY="yes -lgio (gfile)"
if test "${HAVE_NS}" = yes; then
AC_MSG_ERROR(['--with-file-notification=gfile' is not supported in NextStep builds.
Consider kqueue instead.])
else
EMACS_CHECK_MODULES([GFILENOTIFY], [gio-2.0 >= 2.24])
if test "$HAVE_GFILENOTIFY" = "yes"; then
AC_DEFINE(HAVE_GFILENOTIFY, 1, [Define to 1 if using GFile.])
NOTIFY_CFLAGS=$GFILENOTIFY_CFLAGS
NOTIFY_LIBS=$GFILENOTIFY_LIBS
NOTIFY_OBJ=gfilenotify.o
NOTIFY_SUMMARY="yes -lgio (gfile)"
fi
fi ;;
esac
......@@ -2769,9 +2792,9 @@ esac
if test -n "$NOTIFY_OBJ"; then
AC_DEFINE(USE_FILE_NOTIFY, 1, [Define to 1 if using file notifications.])
fi
AC_SUBST(NOTIFY_CFLAGS)
AC_SUBST(NOTIFY_LIBS)
AC_SUBST(NOTIFY_OBJ)
AC_SUBST(GFILENOTIFY_CFLAGS)
AC_SUBST(GFILENOTIFY_LIBS)
dnl Do not put whitespace before the #include statements below.
dnl Older compilers (eg sunos4 cc) choke on it.
......@@ -4141,8 +4164,8 @@ OLDCFLAGS="$CFLAGS"
OLDLIBS="$LIBS"
CFLAGS="$CFLAGS $GTK_CFLAGS $RSVG_CFLAGS $DBUS_CFLAGS $SETTINGS_CFLAGS"
LIBS="$LIBS $GTK_LIBS $RSVG_LIBS $DBUS_LIBS $SETTINGS_LIBS"
CFLAGS="$CFLAGS $GFILENOTIFY_CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $GFILENOTIFY_LIBS $CAIRO_LIBS"
CFLAGS="$CFLAGS $NOTIFY_CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $NOTIFY_LIBS $CAIRO_LIBS"
AC_MSG_CHECKING([whether GLib is linked in])
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[#include <glib.h>
......
......@@ -2653,9 +2653,9 @@ This function removes the tray notification given by its unique
Several operating systems support watching of filesystems for changes
of files. If configured properly, Emacs links a respective library
like @file{gfilenotify}, @file{inotify}, or @file{w32notify}
statically. These libraries enable watching of filesystems on the
local machine.
like @file{inotify}, @file{kqueue}, @file{gfilenotify}, or
@file{w32notify} statically. These libraries enable watching of
filesystems on the local machine.
It is also possible to watch filesystems on remote machines,
@pxref{Remote Files,, Remote Files, emacs, The GNU Emacs Manual}
......@@ -2726,7 +2726,8 @@ watching @var{file} has been stopped
Note that the @file{w32notify} library does not report
@code{attribute-changed} events. When some file's attribute, like
permissions or modification time, has changed, this library reports a
@code{changed} event.
@code{changed} event. Likewise, the @file{kqueue} library does not
report reliably file attribute changes when watching a directory.
The @code{stopped} event reports, that watching the file has been
stopped. This could be because @code{file-notify-rm-watch} was called
......@@ -2765,7 +2766,7 @@ being reported. For example:
@group
(write-region "bla" nil "/tmp/foo")
@result{} Event (35025468 created "/tmp/.#foo")
Event (35025468 changed "/tmp/foo") [2 times]
Event (35025468 changed "/tmp/foo")
Event (35025468 deleted "/tmp/.#foo")
@end group
......@@ -2811,14 +2812,14 @@ also makes it invalid.
@example
@group
(make-directory "/tmp/foo")
@result{} nil
@result{} Event (35025468 created "/tmp/foo")
@end group
@group
(setq desc
(file-notify-add-watch
"/tmp/foo" '(change) 'my-notify-callback))
@result{} 35025468
@result{} 11359632
@end group
@group
......@@ -2828,32 +2829,34 @@ also makes it invalid.
@group
(write-region "bla" nil "/tmp/foo/bla")
@result{} Event (35025468 created "/tmp/foo/.#bla")
Event (35025468 created "/tmp/foo/bla")
Event (35025468 changed "/tmp/foo/bla")
Event (35025468 changed "/tmp/foo/.#bla")
@result{} Event (11359632 created "/tmp/foo/.#bla")
Event (11359632 created "/tmp/foo/bla")
Event (11359632 changed "/tmp/foo/bla")
Event (11359632 deleted "/tmp/foo/.#bla")
@end group
@group
;; Deleting a file in the directory doesn't invalidate the watch.
(delete-file "/tmp/foo/bla")
@result{} Event (35025468 deleted "/tmp/foo/bla")
@result{} Event (11359632 deleted "/tmp/foo/bla")
@end group
@group
(write-region "bla" nil "/tmp/foo/bla")
@result{} Event (35025468 created "/tmp/foo/.#bla")
Event (35025468 created "/tmp/foo/bla")
Event (35025468 changed "/tmp/foo/bla")
Event (35025468 changed "/tmp/foo/.#bla")
@result{} Event (11359632 created "/tmp/foo/.#bla")
Event (11359632 created "/tmp/foo/bla")
Event (11359632 changed "/tmp/foo/bla")
Event (11359632 deleted "/tmp/foo/.#bla")
@end group
@group
;; Deleting the directory invalidates the watch.
;; Events arrive for different watch descriptors.
(delete-directory "/tmp/foo" 'recursive)
@result{} Event (35025468 deleted "/tmp/foo/bla")
Event (35025468 deleted "/tmp/foo")
Event (35025468 stopped "/tmp/foo")
@result{} Event (35025468 deleted "/tmp/foo")
Event (11359632 deleted "/tmp/foo/bla")
Event (11359632 deleted "/tmp/foo")
Event (11359632 stopped "/tmp/foo")
@end group
@group
......
......@@ -63,6 +63,10 @@ If gnustep-config is not available, the old heuristics are used.
** 'configure' now prefers inotify to gfile for file notification,
unless gfile is explicitly requested via --with-file-notification='gfile'.
---
** 'configure' detects the kqueue file notification library on *BSD
and Mac OS X machines.
---
** The configure option '--with-pkg-config-prog' has been removed.
Use './configure PKG_CONFIG=/full/name/of/pkg-config' if you need to.
......@@ -1120,6 +1124,9 @@ notifications, if Emacs is compiled with file notification support.
** File Notifications
+++
*** The kqueue library is integrated for *BSD and Mac OS X machines.
+++
*** The new event `stopped' signals, that a file notification watch is
not active any longer.
......
......@@ -22,15 +22,16 @@
;;; Commentary
;; This package is an abstraction layer from the different low-level
;; file notification packages `gfilenotify', `inotify' and
;; file notification packages `inotify', `kqueue', `gfilenotify' and
;; `w32notify'.
;;; Code:
(defconst file-notify--library
(cond
((featurep 'gfilenotify) 'gfilenotify)
((featurep 'inotify) 'inotify)
((featurep 'kqueue) 'kqueue)
((featurep 'gfilenotify) 'gfilenotify)
((featurep 'w32notify) 'w32notify))
"Non-nil when Emacs has been compiled with file notification support.
The value is the name of the low-level file notification package
......@@ -40,25 +41,24 @@ could use another implementation.")
(defvar file-notify-descriptors (make-hash-table :test 'equal)
"Hash table for registered file notification descriptors.
A key in this hash table is the descriptor as returned from
`gfilenotify', `inotify', `w32notify' or a file name handler.
The value in the hash table is a list
`inotify', `kqueue', `gfilenotify', `w32notify' or a file name
handler. The value in the hash table is a list
(DIR (FILE . CALLBACK) (FILE . CALLBACK) ...)
Several values for a given DIR happen only for `inotify', when
different files from the same directory are watched.")
(defun file-notify--rm-descriptor (descriptor &optional what)
(defun file-notify--rm-descriptor (descriptor)
"Remove DESCRIPTOR from `file-notify-descriptors'.
DESCRIPTOR should be an object returned by `file-notify-add-watch'.
If it is registered in `file-notify-descriptors', a stopped event is sent.
WHAT is a file or directory name to be removed, needed just for `inotify'."
If it is registered in `file-notify-descriptors', a stopped event is sent."
(let* ((desc (if (consp descriptor) (car descriptor) descriptor))
(file (if (consp descriptor) (cdr descriptor)))
(registered (gethash desc file-notify-descriptors))
(dir (car registered)))
(when (and (consp registered) (or (null what) (string-equal dir what)))
(when (consp registered)
;; Send `stopped' event.
(dolist (entry (cdr registered))
(funcall (cdr entry)
......@@ -76,7 +76,8 @@ WHAT is a file or directory name to be removed, needed just for `inotify'."
(remhash desc file-notify-descriptors)
(puthash desc registered file-notify-descriptors))))))
;; This function is used by `gfilenotify', `inotify' and `w32notify' events.
;; This function is used by `inotify', `kqueue', `gfilenotify' and
;; `w32notify' events.
;;;###autoload
(defun file-notify-handle-event (event)
"Handle file system monitoring event.
......@@ -159,7 +160,7 @@ EVENT is the cadr of the event in `file-notify-handle-event'
(setq actions nil))
;; Loop over actions. In fact, more than one action happens only
;; for `inotify'.
;; for `inotify' and `kqueue'.
(dolist (action actions)
;; Send pending event, if it doesn't match.
......@@ -184,19 +185,17 @@ EVENT is the cadr of the event in `file-notify-handle-event'
;; Map action. We ignore all events which cannot be mapped.
(setq action
(cond
;; gfilenotify.
((memq action '(attribute-changed changed created deleted))
((memq action
'(attribute-changed changed created deleted renamed))
action)
((eq action 'moved)
((memq action '(moved rename))
(setq file1 (file-notify--event-file1-name event))
'renamed)
;; inotify, w32notify.
((eq action 'ignored)
(setq stopped t actions nil))
((eq action 'attrib) 'attribute-changed)
((memq action '(attrib link)) 'attribute-changed)
((memq action '(create added)) 'created)
((memq action '(modify modified)) 'changed)
((memq action '(modify modified write)) 'changed)
((memq action '(delete delete-self move-self removed)) 'deleted)
;; Make the event pending.
((memq action '(moved-from renamed-from))
......@@ -236,7 +235,6 @@ EVENT is the cadr of the event in `file-notify-handle-event'
(setq pending-event nil))
;; Check for stopped.
;;(message "file-notify-callback %S %S" file registered)
(setq
stopped
(or
......@@ -244,10 +242,13 @@ EVENT is the cadr of the event in `file-notify-handle-event'
(and
(memq action '(deleted renamed))
(= (length (cdr registered)) 1)
(string-equal
(file-name-nondirectory file)
(or (file-name-nondirectory (car registered))
(car (cadr registered)))))))
(or
(string-equal
(file-name-nondirectory file)
(file-name-nondirectory (car registered)))
(string-equal
(file-name-nondirectory file)
(car (cadr registered)))))))
;; Apply callback.
(when (and action
......@@ -258,10 +259,17 @@ EVENT is the cadr of the event in `file-notify-handle-event'
;; File matches.
(string-equal
(nth 0 entry) (file-name-nondirectory file))
;; Directory matches.
(string-equal
(file-name-nondirectory file)
(file-name-nondirectory (car registered)))
;; File1 matches.
(and (stringp file1)
(string-equal
(nth 0 entry) (file-name-nondirectory file1)))))
;;(message
;;"file-notify-callback %S %S %S %S %S"
;;(file-notify--descriptor desc file) action file file1 registered)
(if file1
(funcall
callback
......@@ -272,11 +280,10 @@ EVENT is the cadr of the event in `file-notify-handle-event'
;; Modify `file-notify-descriptors'.
(when stopped
(file-notify--rm-descriptor
(file-notify--descriptor desc file) file)))))
(file-notify-rm-watch (file-notify--descriptor desc file))))))
;; `gfilenotify' and `w32notify' return a unique descriptor for every
;; `file-notify-add-watch', while `inotify' returns a unique
;; `kqueue', `gfilenotify' and `w32notify' return a unique descriptor
;; for every `file-notify-add-watch', while `inotify' returns a unique
;; descriptor per inode only.
(defun file-notify-add-watch (file flags callback)
"Add a watch for filesystem events pertaining to FILE.
......@@ -329,7 +336,7 @@ FILE is the name of the file whose event is being reported."
(if (file-directory-p file)
file
(file-name-directory file))))
desc func l-flags registered)
desc func l-flags registered entry)
(unless (file-directory-p dir)
(signal 'file-notify-error `("Directory does not exist" ,dir)))
......@@ -338,7 +345,12 @@ FILE is the name of the file whose event is being reported."
;; A file name handler could exist even if there is no local
;; file notification support.
(setq desc (funcall
handler 'file-notify-add-watch dir flags callback))
handler 'file-notify-add-watch
;; kqueue does not report file changes in
;; directory monitor. So we must watch the file
;; itself.
(if (eq file-notify--library 'kqueue) file dir)
flags callback))
;; Check, whether Emacs has been compiled with file notification
;; support.
......@@ -349,8 +361,9 @@ FILE is the name of the file whose event is being reported."
;; Determine low-level function to be called.
(setq func
(cond
((eq file-notify--library 'gfilenotify) 'gfile-add-watch)
((eq file-notify--library 'inotify) 'inotify-add-watch)
((eq file-notify--library 'kqueue) 'kqueue-add-watch)
((eq file-notify--library 'gfilenotify) 'gfile-add-watch)
((eq file-notify--library 'w32notify) 'w32notify-add-watch)))
;; Determine respective flags.
......@@ -362,30 +375,32 @@ FILE is the name of the file whose event is being reported."
(cond
((eq file-notify--library 'inotify)
'(create delete delete-self modify move-self move))
((eq file-notify--library 'kqueue)
'(create delete write extend rename))
((eq file-notify--library 'w32notify)
'(file-name directory-name size last-write-time)))))
(when (memq 'attribute-change flags)
(push (cond
((eq file-notify--library 'inotify) 'attrib)
((eq file-notify--library 'kqueue) 'attrib)
((eq file-notify--library 'w32notify) 'attributes))
l-flags)))
;; Call low-level function.
(setq desc (funcall func dir l-flags 'file-notify-callback)))
(setq desc (funcall
func (if (eq file-notify--library 'kqueue) file dir)
l-flags 'file-notify-callback)))
;; Modify `file-notify-descriptors'.
(setq registered (gethash desc file-notify-descriptors))
(puthash
desc
`(,dir
(,(unless (file-directory-p file) (file-name-nondirectory file))
. ,callback)
. ,(cdr registered))
file-notify-descriptors)
(setq file (unless (file-directory-p file) (file-name-nondirectory file))
desc (if (consp desc) (car desc) desc)
registered (gethash desc file-notify-descriptors)
entry `(,file . ,callback))
(unless (member entry (cdr registered))
(puthash desc `(,dir ,entry . ,(cdr registered)) file-notify-descriptors))
;; Return descriptor.
(file-notify--descriptor
desc (unless (file-directory-p file) (file-name-nondirectory file)))))
(file-notify--descriptor desc file)))
(defun file-notify-rm-watch (descriptor)
"Remove an existing watch specified by its DESCRIPTOR.
......@@ -410,8 +425,9 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
(funcall
(cond
((eq file-notify--library 'gfilenotify) 'gfile-rm-watch)
((eq file-notify--library 'inotify) 'inotify-rm-watch)
((eq file-notify--library 'kqueue) 'kqueue-rm-watch)
((eq file-notify--library 'gfilenotify) 'gfile-rm-watch)
((eq file-notify--library 'w32notify) 'w32notify-rm-watch))
desc))
(file-notify-error nil)))
......@@ -441,8 +457,9 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
(funcall handler 'file-notify-valid-p descriptor)
(funcall
(cond
((eq file-notify--library 'gfilenotify) 'gfile-valid-p)
((eq file-notify--library 'inotify) 'inotify-valid-p)
((eq file-notify--library 'kqueue) 'kqueue-valid-p)
((eq file-notify--library 'gfilenotify) 'gfile-valid-p)
((eq file-notify--library 'w32notify) 'w32notify-valid-p))
desc))
t))))
......
......@@ -163,12 +163,13 @@ SETTINGS_LIBS = @SETTINGS_LIBS@
## gtkutil.o if USE_GTK, else empty.
GTK_OBJ=@GTK_OBJ@
## gfilenotify.o if HAVE_GFILENOTIFY.
## inotify.o if HAVE_INOTIFY.
## kqueue.o if HAVE_KQUEUE.
## gfilenotify.o if HAVE_GFILENOTIFY.
## w32notify.o if HAVE_W32NOTIFY.
NOTIFY_OBJ = @NOTIFY_OBJ@
GFILENOTIFY_CFLAGS = @GFILENOTIFY_CFLAGS@
GFILENOTIFY_LIBS = @GFILENOTIFY_LIBS@
NOTIFY_CFLAGS = @NOTIFY_CFLAGS@
NOTIFY_LIBS = @NOTIFY_LIBS@
## -ltermcap, or -lncurses, or -lcurses, or "".
LIBS_TERMCAP=@LIBS_TERMCAP@
......@@ -367,7 +368,7 @@ ALL_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
$(WEBKIT_CFLAGS) \
$(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
$(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
$(LIBGNUTLS_CFLAGS) $(GFILENOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
$(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS)
ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
......@@ -482,7 +483,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) \
$(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES)
$(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES)
$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
$(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)"
......
......@@ -1360,6 +1360,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
tzset ();
#endif /* MSDOS */
#ifdef HAVE_KQUEUE
globals_of_kqueue ();
#endif
#ifdef HAVE_GFILENOTIFY
globals_of_gfilenotify ();
#endif
......@@ -1538,14 +1542,18 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_gnutls ();
#ifdef HAVE_GFILENOTIFY
syms_of_gfilenotify ();
#endif /* HAVE_GFILENOTIFY */
#ifdef HAVE_INOTIFY
syms_of_inotify ();
#endif /* HAVE_INOTIFY */
#ifdef HAVE_KQUEUE
syms_of_kqueue ();
#endif /* HAVE_KQUEUE */
#ifdef HAVE_GFILENOTIFY
syms_of_gfilenotify ();
#endif /* HAVE_GFILENOTIFY */
#ifdef HAVE_DBUS
syms_of_dbusbind ();
#endif /* HAVE_DBUS */
......
......@@ -46,8 +46,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
static int inotifyfd = -1;
/* Assoc list of files being watched.
Format:
(watch-descriptor . callback)
Format: (watch-descriptor name callback)
*/
static Lisp_Object watch_list;
......@@ -106,12 +105,14 @@ inotifyevent_to_event (Lisp_Object watch_object, struct inotify_event const *ev)
name = make_unibyte_string (ev->name, min (len, ev->len));
name = DECODE_FILE (name);
}
else
name = XCAR (XCDR (watch_object));
return list2 (list4 (make_watch_descriptor (ev->wd),
mask_to_aspects (ev->mask),
name,
make_number (ev->cookie)),
XCDR (watch_object));
Fnth (make_number (2), watch_object));
}
/* This callback is called when the FD is available for read. The inotify
......@@ -325,7 +326,7 @@ is managed internally and there is no corresponding inotify_init. Use
watch_list = Fdelete (watch_object, watch_list);
/* Store watch object in watch list. */
watch_object = Fcons (watch_descriptor, callback);
watch_object = list3 (watch_descriptor, encoded_file_name, callback);
watch_list = Fcons (watch_object, watch_list);
return watch_descriptor;
......
......@@ -5965,12 +5965,12 @@ make_lispy_event (struct input_event *event)
#endif
#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
#if defined HAVE_INOTIFY || defined HAVE_KQUEUE || defined HAVE_GFILENOTIFY
case FILE_NOTIFY_EVENT:
{
return Fcons (Qfile_notify, event->arg);
}
#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
#endif /* HAVE_INOTIFY || HAVE_KQUEUE || HAVE_GFILENOTIFY */
case CONFIG_CHANGED_EVENT:
return list3 (Qconfig_changed_event,
......
/* Filesystem notifications support with kqueue API.
Copyright (C) 2015-2016 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#ifdef HAVE_KQUEUE
#include <stdio.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/file.h>
#include "lisp.h"
#include "keyboard.h"
#include "process.h"
/* File handle for kqueue. */
static int kqueuefd = -1;
/* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]). */
static Lisp_Object watch_list;
/* Generate a list from the directory_files_internal output.
Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */
Lisp_Object
kqueue_directory_listing (Lisp_Object directory_files)
{
Lisp_Object dl, result = Qnil;
for (dl = directory_files; ! NILP (dl); dl = XCDR (dl)) {
/* We ignore "." and "..". */
if ((strcmp (".", SSDATA (XCAR (XCAR (dl)))) == 0) ||
(strcmp ("..", SSDATA (XCAR (XCAR (dl)))) == 0))