=== modified file 'lisp/ChangeLog'
*** lisp/ChangeLog 2013-06-27 09:26:54 +0000
--- lisp/ChangeLog 2013-06-27 12:03:14 +0000
***************
*** 1,3 ****
--- 1,15 ----
+ 2013-06-27 Michael Albinus
+
+ * filenotify.el: New package.
+
+ * autorevert.el (top): Require filenotify.el.
+ (auto-revert-notify-enabled): Remove. Use `file-notify-support'
+ instead.
+ (auto-revert-notify-rm-watch, auto-revert-notify-add-watch)
+ (auto-revert-notify-handler): Use `file-notify-*' functions.
+
+ * subr.el (file-notify-handle-event): Move function to filenotify.el.
+
2013-06-27 Dmitry Gutov
* emacs-lisp/package-x.el (package-upload-buffer-internal): Adapt
***************
*** 153,164 ****
2013-06-25 Rüdiger Sonderfeld
! * lisp/textmodes/bibtex.el (bibtex-generate-url-list): Add support
for DOI URLs.
2013-06-25 Rüdiger Sonderfeld
! * lisp/textmodes/bibtex.el (bibtex-mode, bibtex-set-dialect):
Update imenu-support when dialect changes.
2013-06-25 Leo Liu
--- 165,176 ----
2013-06-25 Rüdiger Sonderfeld
! * textmodes/bibtex.el (bibtex-generate-url-list): Add support
for DOI URLs.
2013-06-25 Rüdiger Sonderfeld
! * textmodes/bibtex.el (bibtex-mode, bibtex-set-dialect):
Update imenu-support when dialect changes.
2013-06-25 Leo Liu
=== modified file 'lisp/autorevert.el'
*** lisp/autorevert.el 2013-06-05 19:57:10 +0000
--- lisp/autorevert.el 2013-06-27 09:00:44 +0000
***************
*** 103,108 ****
--- 103,109 ----
(eval-when-compile (require 'cl-lib))
(require 'timer)
+ (require 'filenotify)
;; Custom Group:
;;
***************
*** 270,290 ****
:type 'boolean
:version "24.4")
! (defconst auto-revert-notify-enabled
! (or (featurep 'gfilenotify) (featurep 'inotify) (featurep 'w32notify))
! "Non-nil when Emacs has been compiled with file notification support.")
!
! (defcustom auto-revert-use-notify auto-revert-notify-enabled
"If non-nil Auto Revert Mode uses file notification functions.
This requires Emacs being compiled with file notification
! support (see `auto-revert-notify-enabled'). You should set this
! variable through Custom."
:group 'auto-revert
:type 'boolean
:set (lambda (variable value)
! (set-default variable (and auto-revert-notify-enabled value))
(unless (symbol-value variable)
! (when auto-revert-notify-enabled
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (symbol-value 'auto-revert-notify-watch-descriptor)
--- 271,287 ----
:type 'boolean
:version "24.4")
! (defcustom auto-revert-use-notify (and file-notify-support t)
"If non-nil Auto Revert Mode uses file notification functions.
This requires Emacs being compiled with file notification
! support (see `file-notify-support'). You should set this variable
! through Custom."
:group 'auto-revert
:type 'boolean
:set (lambda (variable value)
! (set-default variable (and file-notify-support value))
(unless (symbol-value variable)
! (when file-notify-support
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (symbol-value 'auto-revert-notify-watch-descriptor)
***************
*** 502,513 ****
(puthash key value auto-revert-notify-watch-descriptor-hash-list)
(remhash key auto-revert-notify-watch-descriptor-hash-list)
(ignore-errors
! (funcall
! (cond
! ((fboundp 'gfile-rm-watch) 'gfile-rm-watch)
! ((fboundp 'inotify-rm-watch) 'inotify-rm-watch)
! ((fboundp 'w32notify-rm-watch) 'w32notify-rm-watch))
! auto-revert-notify-watch-descriptor)))))
auto-revert-notify-watch-descriptor-hash-list)
(remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch))
(setq auto-revert-notify-watch-descriptor nil
--- 499,505 ----
(puthash key value auto-revert-notify-watch-descriptor-hash-list)
(remhash key auto-revert-notify-watch-descriptor-hash-list)
(ignore-errors
! (file-notify-rm-watch auto-revert-notify-watch-descriptor)))))
auto-revert-notify-watch-descriptor-hash-list)
(remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch))
(setq auto-revert-notify-watch-descriptor nil
***************
*** 522,621 ****
(when (and buffer-file-name auto-revert-use-notify
(not auto-revert-notify-watch-descriptor))
! (let ((func
! (cond
! ((fboundp 'gfile-add-watch) 'gfile-add-watch)
! ((fboundp 'inotify-add-watch) 'inotify-add-watch)
! ((fboundp 'w32notify-add-watch) 'w32notify-add-watch)))
! (aspect
! (cond
! ((fboundp 'gfile-add-watch) '(watch-mounts))
! ;; `attrib' is needed for file modification time.
! ((fboundp 'inotify-add-watch) '(attrib create modify moved-to))
! ((fboundp 'w32notify-add-watch) '(size last-write-time))))
! (file (if (or (fboundp 'gfile-add-watch) (fboundp 'inotify-add-watch))
! (directory-file-name (expand-file-name default-directory))
! (buffer-file-name))))
! (setq auto-revert-notify-watch-descriptor
! (ignore-errors
! (funcall func file aspect 'auto-revert-notify-handler)))
! (if auto-revert-notify-watch-descriptor
! (progn
! (puthash
! auto-revert-notify-watch-descriptor
! (cons (current-buffer)
! (gethash auto-revert-notify-watch-descriptor
! auto-revert-notify-watch-descriptor-hash-list))
! auto-revert-notify-watch-descriptor-hash-list)
! (add-hook (make-local-variable 'kill-buffer-hook)
! 'auto-revert-notify-rm-watch))
! ;; Fallback to file checks.
! (set (make-local-variable 'auto-revert-use-notify) nil)))))
!
! (defun auto-revert-notify-event-p (event)
! "Check that event is a file notification event."
! (and (listp event)
! (cond ((featurep 'gfilenotify)
! (and (>= (length event) 3) (stringp (nth 2 event))))
! ((featurep 'inotify)
! (= (length event) 4))
! ((featurep 'w32notify)
! (and (= (length event) 3) (stringp (nth 2 event)))))))
!
! (defun auto-revert-notify-event-descriptor (event)
! "Return watch descriptor of file notification event, or nil."
! (and (auto-revert-notify-event-p event) (car event)))
!
! (defun auto-revert-notify-event-action (event)
! "Return action of file notification event, or nil."
! (and (auto-revert-notify-event-p event) (nth 1 event)))
!
! (defun auto-revert-notify-event-file-name (event)
! "Return file name of file notification event, or nil."
! (and (auto-revert-notify-event-p event)
! (cond ((featurep 'gfilenotify) (nth 2 event))
! ((featurep 'inotify) (nth 3 event))
! ((featurep 'w32notify) (nth 2 event)))))
(defun auto-revert-notify-handler (event)
"Handle an EVENT returned from file notification."
! (when (auto-revert-notify-event-p event)
! (let* ((descriptor (auto-revert-notify-event-descriptor event))
! (action (auto-revert-notify-event-action event))
! (file (auto-revert-notify-event-file-name event))
(buffers (gethash descriptor
auto-revert-notify-watch-descriptor-hash-list)))
! (ignore-errors
! ;; Check, that event is meant for us.
! ;; TODO: Filter events which stop watching, like `move' or `removed'.
! (cl-assert descriptor)
! (cond
! ((featurep 'gfilenotify)
! (cl-assert (memq action '(attribute-changed changed created deleted
! ;; FIXME: I keep getting this action, so I
! ;; added it here, but I have no idea what
! ;; I'm doing. --Stef
! changes-done-hint))
! t))
! ((featurep 'inotify)
! (cl-assert (or (memq 'attrib action)
! (memq 'create action)
! (memq 'modify action)
! (memq 'moved-to action))))
! ((featurep 'w32notify) (cl-assert (eq 'modified action))))
! ;; Since we watch a directory, a file name must be returned.
! (cl-assert (stringp file))
! (dolist (buffer buffers)
! (when (buffer-live-p buffer)
! (with-current-buffer buffer
! (when (and (stringp buffer-file-name)
! (string-equal
! (file-name-nondirectory file)
! (file-name-nondirectory buffer-file-name)))
! ;; Mark buffer modified.
! (setq auto-revert-notify-modified-p t)
! ;; No need to check other buffers.
! (cl-return)))))))))
(defun auto-revert-active-p ()
"Check if auto-revert is active (in current buffer or globally)."
--- 514,571 ----
(when (and buffer-file-name auto-revert-use-notify
(not auto-revert-notify-watch-descriptor))
! (setq auto-revert-notify-watch-descriptor
! (ignore-errors
! (file-notify-add-watch
! (directory-file-name (expand-file-name default-directory))
! '(change attribute-change) 'auto-revert-notify-handler)))
! (if auto-revert-notify-watch-descriptor
! (progn
! (puthash
! auto-revert-notify-watch-descriptor
! (cons (current-buffer)
! (gethash auto-revert-notify-watch-descriptor
! auto-revert-notify-watch-descriptor-hash-list))
! auto-revert-notify-watch-descriptor-hash-list)
! (add-hook (make-local-variable 'kill-buffer-hook)
! 'auto-revert-notify-rm-watch))
! ;; Fallback to file checks.
! (set (make-local-variable 'auto-revert-use-notify) nil))))
(defun auto-revert-notify-handler (event)
"Handle an EVENT returned from file notification."
! (ignore-errors
! (let* ((descriptor (car event))
! (action (nth 1 event))
! (file (nth 2 event))
! (file1 (nth 3 event)) ;; Target of `renamed'.
(buffers (gethash descriptor
auto-revert-notify-watch-descriptor-hash-list)))
! ;; Check, that event is meant for us.
! (cl-assert descriptor)
! ;; We do not handle `deleted', because nothing has to be refreshed.
! (cl-assert (memq action '(attribute-changed changed created renamed)) t)
! ;; Since we watch a directory, a file name must be returned.
! (cl-assert (stringp file))
! (when (eq action 'renamed) (cl-assert (stringp file1)))
! ;; Loop over all buffers, in order to find the intended one.
! (dolist (buffer buffers)
! (when (buffer-live-p buffer)
! (with-current-buffer buffer
! (when (and (stringp buffer-file-name)
! (or
! (and (memq action '(attribute-changed changed created))
! (string-equal
! (file-name-nondirectory file)
! (file-name-nondirectory buffer-file-name)))
! (and (eq action 'renamed)
! (string-equal
! (file-name-nondirectory file1)
! (file-name-nondirectory buffer-file-name)))))
! ;; Mark buffer modified.
! (setq auto-revert-notify-modified-p t)
! ;; No need to check other buffers.
! (cl-return))))))))
(defun auto-revert-active-p ()
"Check if auto-revert is active (in current buffer or globally)."
=== added file 'lisp/filenotify.el'
*** lisp/filenotify.el 1970-01-01 00:00:00 +0000
--- lisp/filenotify.el 2013-06-27 06:49:24 +0000
***************
*** 0 ****
--- 1,292 ----
+ ;;; filenotify.el --- watch files for changes on disk
+
+ ;; Copyright (C) 2013 Free Software Foundation, Inc.
+
+ ;; Author: Michael Albinus
+
+ ;; 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 .
+
+ ;;; Commentary
+
+ ;; This package is an abstraction layer from the different low-level
+ ;; file notification packages `gfilenotify', `inotify' and
+ ;; `w32notify'.
+
+ ;;; Code:
+
+ ;;;###autoload
+ (defconst file-notify-support
+ (cond
+ ((featurep 'gfilenotify) 'gfilenotify)
+ ((featurep 'inotify) 'inotify)
+ ((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
+ to be used for local file systems. Remote file notifications
+ 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 a
+ `gfilenotify', `inotify' or `w32notify'. The value in the hash
+ table is the cons cell (FILE . CALLBACK).")
+
+ ;; This function is used by `gfilenotify', `inotify' and `w32notify' events.
+ ;;;###autoload
+ (defun file-notify-handle-event (event)
+ "Handle file system monitoring event.
+ If EVENT is a filewatch event, call its callback.
+ Otherwise, signal a `file-notify-error'."
+ (interactive "e")
+ (if (and (eq (car event) 'file-notify)
+ (>= (length event) 3))
+ (funcall (nth 2 event) (nth 1 event))
+ (signal 'file-notify-error
+ (cons "Not a valid file-notify event" event))))
+
+ (defvar file-notify--pending-event nil
+ "Pending file notification event for a future `renamed' action.
+ This is a list (DESCRIPTOR ACTION COOKIE FILE), or nil. ACTION
+ is either `moved-from' or `renamed-from'.")
+
+ (defun file-notify--event-file-name (event)
+ "Return file name of file notification event, or nil."
+ (cond ((eq file-notify-support 'gfilenotify) (nth 2 event))
+ ((eq file-notify-support 'inotify) (nth 3 event))
+ ((eq file-notify-support 'w32notify) (nth 2 event))))
+
+ ;; Only `gfilenotify' could return two file names.
+ (defun file-notify--event-file1-name (event)
+ "Return second file name of file notification event, or nil.
+ This is available in case a file has been moved."
+ (and (eq file-notify-support 'gfilenotify) (nth 3 event)))
+
+ ;; Cookies are offered by `inotify' only.
+ (defun file-notify--event-cookie (event)
+ "Return cookie of file notification event, or nil.
+ This is available in case a file has been moved."
+ (and (eq file-notify-support 'inotify) (nth 2 event)))
+
+ ;; The callback function used to map between specific flags of the
+ ;; respective file notifications, and the ones we return.
+ (defun file-notify-callback (event)
+ "Handle an EVENT returned from file notification.
+ EVENT is the same one as in `file-notify-handle-event' except the
+ car of that event, which is the symbol `file-notify'."
+ (let ((descriptor (car event))
+ (actions (nth 1 event))
+ (file (file-notify--event-file-name event))
+ file1 cookie callback tmp)
+ ;; Check, that event is meant for us.
+ (unless (setq callback (cdr (gethash descriptor file-notify-descriptors)))
+ (signal 'file-notify-error (list "Not a valid descriptor" descriptor)))
+
+ ;; Make actions a list.
+ (unless (consp actions) (setq actions (cons actions nil)))
+
+ ;; Loop over actions. In fact, more than one action happens only
+ ;; for `inotify'.
+ (dolist (action actions)
+
+ ;; Send pending event, if it doesn't match.
+ (when (and file-notify--pending-event
+ ;; The cookie doesn't match.
+ (not (eq (nth 2 file-notify--pending-event)
+ (file-notify--event-cookie event)))
+ (or
+ ;; inotify.
+ (and (eq (nth 1 file-notify--pending-event) 'moved-from)
+ (not (eq action 'moved-to)))
+ ;; w32notify.
+ (and (eq (nth 1 file-notify--pending-event) 'renamed-from)
+ (not (eq action 'renamed-to)))))
+ (funcall callback
+ (list (nth 0 file-notify--pending-event)
+ 'deleted (nth 3 file-notify--pending-event)))
+ (setq file-notify--pending-event nil))
+
+ ;; Map action. We ignore all events which cannot be mapped.
+ (setq action
+ (cond
+ ;; gfilenotify.
+ ((memq action '(attribute-changed changed created deleted)) action)
+ ((eq action 'moved)
+ (setq file1 (file-notify--event-file1-name event))
+ 'renamed)
+
+ ;; inotify.
+ ((eq action 'attrib) 'attribute-changed)
+ ((eq action 'create) 'created)
+ ((eq action 'modify) 'changed)
+ ((memq action '(delete 'delete-self move-self)) 'deleted)
+ ;; Make the event pending.
+ ((eq action 'moved-from)
+ (setq file-notify--pending-event
+ (list descriptor action
+ (file-notify--event-cookie event) file))
+ nil)
+ ;; Look for pending event.
+ ((eq action 'moved-to)
+ (if (null file-notify--pending-event)
+ 'created
+ (setq file1 file
+ file (nth 3 file-notify--pending-event)
+ file-notify--pending-event nil)
+ 'renamed))
+
+ ;; w32notify.
+ ((eq action 'added) 'created)
+ ((eq action 'modified) 'changed)
+ ((eq action 'removed) 'deleted)
+ ;; Make the event pending.
+ ((eq 'renamed-from action)
+ (setq file-notify--pending-event
+ (list descriptor action nil file))
+ nil)
+ ;; Look for pending event.
+ ((eq 'renamed-to action)
+ (if (null file-notify--pending-event)
+ 'created
+ (setq file1 file
+ file (nth 3 file-notify--pending-event)
+ file-notify--pending-event nil)
+ 'renamed))))
+
+ ;; Apply callback.
+ (when action
+ (if file1
+ (funcall callback (list descriptor action file file1))
+ (funcall callback (list descriptor action file)))))))
+
+ (defun file-notify-add-watch (file flags callback)
+ "Add a watch for filesystem events pertaining to FILE.
+ This arranges for filesystem events pertaining to FILE to be reported
+ to Emacs. Use `file-notify-rm-watch' to cancel the watch.
+
+ The returned value is a descriptor for the added watch. If the
+ file cannot be watched for some reason, this function signals a
+ `file-error' error.
+
+ FLAGS is a list of conditions to set what will be watched for. It can
+ include the following symbols:
+
+ `change' -- watch for file changes
+ `attribute-change' -- watch for file attributes changes, like
+ permissions or modification time
+
+ If FILE is a directory, 'change' watches for file creation or
+ deletion in that directory.
+
+ When any event happens, Emacs will call the CALLBACK function passing
+ it a single argument EVENT, which is of the form
+
+ (DESCRIPTOR ACTION FILE [FILE1])
+
+ DESCRIPTOR is the same object as the one returned by this function.
+ ACTION is the description of the event. It could be any one of the
+ following:
+
+ `created' -- FILE was created
+ `deleted' -- FILE was deleted
+ `changed' -- FILE has changed
+ `renamed' -- FILE has been renamed to FILE1
+ `attribute-changed' -- a FILE attribute was changed
+
+ FILE is the name of the file whose event is being reported."
+ ;; Check arguments.
+ (unless (stringp file)
+ (signal 'wrong-type-argument (list file)))
+ (setq file (expand-file-name file))
+ (unless (and (consp flags)
+ (null (delq 'change (delq 'attribute-change (copy-tree flags)))))
+ (signal 'wrong-type-argument (list flags)))
+ (unless (functionp callback)
+ (signal 'wrong-type-argument (list callback)))
+
+ (let ((handler (find-file-name-handler file 'file-notify-add-watch))
+ func fl desc)
+
+ ;; Check, whether this has been registered already.
+ (maphash
+ (lambda (key value)
+ (when (equal (cons file callback) value) (setq desc key)))
+ file-notify-descriptors)
+
+ (unless desc
+ (if handler
+ ;; A file name handler could exist even if there is no local
+ ;; file notification support.
+ (setq desc
+ (funcall handler 'file-notify-add-watch file flags callback))
+
+ ;; Check, whether Emacs has been compiled with file
+ ;; notification support.
+ (unless file-notify-support
+ (signal 'file-notify-error
+ '("No file notification package available")))
+
+ ;; Determine local function to be called.
+ (setq func (cond
+ ((eq file-notify-support 'gfilenotify) 'gfile-add-watch)
+ ((eq file-notify-support 'inotify) 'inotify-add-watch)
+ ((eq file-notify-support 'w32notify) 'w32notify-add-watch)))
+
+ ;; Determine respective flags.
+ (if (eq file-notify-support 'gfilenotify)
+ (setq fl '(watch-mounts send-moved))
+ (when (memq 'change flags)
+ (setq
+ fl
+ (cond
+ ((eq file-notify-support 'inotify) '(create modify move delete))
+ ((eq file-notify-support 'w32notify) '(size last-write-time)))))
+ (when (memq 'attribute-change flags)
+ (add-to-list
+ 'fl
+ (cond
+ ((eq file-notify-support 'inotify) 'attrib)
+ ((eq file-notify-support 'w32notify) 'attributes)))))
+
+ ;; Call low-level function.
+ (setq desc (funcall func file fl 'file-notify-callback))))
+
+ ;; Return descriptor.
+ (puthash desc (cons file callback) file-notify-descriptors)
+ desc))
+
+ (defun file-notify-rm-watch (descriptor)
+ "Remove an existing watch specified by its DESCRIPTOR.
+ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
+ (let ((file (car (gethash descriptor file-notify-descriptors)))
+ handler)
+
+ (when (stringp file)
+ (setq handler (find-file-name-handler file 'file-notify-rm-watch))
+ (if handler
+ (funcall handler 'file-notify-rm-watch descriptor)
+ (funcall
+ (cond
+ ((eq file-notify-support 'gfilenotify) 'gfile-rm-watch)
+ ((eq file-notify-support 'inotify) 'inotify-rm-watch)
+ ((eq file-notify-support 'w32notify) 'w32notify-rm-watch))
+ descriptor)))
+
+ (remhash descriptor file-notify-descriptors)))
+
+ ;; The end:
+ (provide 'filenotify)
+
+ ;;; filenotify.el ends here
=== modified file 'lisp/subr.el'
*** lisp/subr.el 2013-06-20 14:15:42 +0000
--- lisp/subr.el 2013-06-24 07:49:32 +0000
***************
*** 4494,4513 ****
nil ,@(cdr (cdr spec)))))
- ;;;; Support for watching filesystem events.
-
- (defun file-notify-handle-event (event)
- "Handle file system monitoring event.
- If EVENT is a filewatch event, call its callback.
- Otherwise, signal a `filewatch-error'."
- (interactive "e")
- (if (and (eq (car event) 'file-notify)
- (>= (length event) 3))
- (funcall (nth 2 event) (nth 1 event))
- (signal 'filewatch-error
- (cons "Not a valid file-notify event" event))))
-
-
;;;; Comparing version strings.
(defconst version-separator "."
--- 4494,4499 ----
=== modified file 'src/ChangeLog'
*** src/ChangeLog 2013-06-24 00:31:31 +0000
--- src/ChangeLog 2013-06-27 11:56:19 +0000
***************
*** 1,3 ****
--- 1,13 ----
+ 2013-06-27 Michael Albinus
+
+ * fileio.c (Qfile_notify_error): New error symbol.
+
+ * gfilenotify.c (Fgfile_add_watch, Fgfile_rm_watch):
+ * inotify.c (inotify_callback, symbol_to_inotifymask)
+ (Finotify_add_watch, Finotify_rm_watch): Use it.
+
+ * lisp.h (Qfile_notify_error): Declare.
+
2013-06-23 Paul Eggert
A more-conservative workaround for Cygwin SIGCHLD issues (Bug#14569).
=== modified file 'src/fileio.c'
*** src/fileio.c 2013-06-18 07:42:37 +0000
--- src/fileio.c 2013-06-26 07:56:12 +0000
***************
*** 148,154 ****
#ifdef WINDOWSNT
#endif
! Lisp_Object Qfile_error;
static Lisp_Object Qfile_already_exists, Qfile_date_error;
static Lisp_Object Qexcl;
Lisp_Object Qfile_name_history;
--- 148,154 ----
#ifdef WINDOWSNT
#endif
! Lisp_Object Qfile_error, Qfile_notify_error;
static Lisp_Object Qfile_already_exists, Qfile_date_error;
static Lisp_Object Qexcl;
Lisp_Object Qfile_name_history;
***************
*** 5887,5892 ****
--- 5887,5893 ----
DEFSYM (Qfile_error, "file-error");
DEFSYM (Qfile_already_exists, "file-already-exists");
DEFSYM (Qfile_date_error, "file-date-error");
+ DEFSYM (Qfile_notify_error, "file-notify-error");
DEFSYM (Qexcl, "excl");
DEFVAR_LISP ("file-name-coding-system", Vfile_name_coding_system,
***************
*** 5925,5930 ****
--- 5926,5936 ----
Fput (Qfile_date_error, Qerror_message,
build_pure_c_string ("Cannot set file date"));
+ Fput (Qfile_notify_error, Qerror_conditions,
+ Fpurecopy (list3 (Qfile_notify_error, Qfile_error, Qerror)));
+ Fput (Qfile_notify_error, Qerror_message,
+ build_pure_c_string ("File notification error"));
+
DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist,
doc: /* Alist of elements (REGEXP . HANDLER) for file names handled specially.
If a file name matches REGEXP, all I/O on that file is done by calling
=== modified file 'src/gfilenotify.c'
*** src/gfilenotify.c 2013-06-06 07:04:35 +0000
--- src/gfilenotify.c 2013-06-27 11:47:42 +0000
***************
*** 132,146 ****
to Emacs. Use `gfile-rm-watch' to cancel the watch.
Value is a descriptor for the added watch. If the file cannot be
! watched for some reason, this function signals a `file-error' error.
FLAGS is a list of conditions to set what will be watched for. It can
include the following symbols:
'watch-mounts' -- watch for mount events
'send-moved' -- pair 'deleted' and 'created' events caused by file
! renames (moves) and send a single 'event-moved'
! event instead
When any event happens, Emacs will call the CALLBACK function passing
it a single argument EVENT, which is of the form
--- 132,145 ----
to Emacs. Use `gfile-rm-watch' to cancel the watch.
Value is a descriptor for the added watch. If the file cannot be
! watched for some reason, this function signals a `file-notify-error' error.
FLAGS is a list of conditions to set what will be watched for. It can
include the following symbols:
'watch-mounts' -- watch for mount events
'send-moved' -- pair 'deleted' and 'created' events caused by file
! renames and send a single 'renamed' event instead
When any event happens, Emacs will call the CALLBACK function passing
it a single argument EVENT, which is of the form
***************
*** 193,199 ****
/* Enable watch. */
monitor = g_file_monitor (gfile, gflags, NULL, NULL);
if (! monitor)
! xsignal2 (Qfile_error, build_string ("Cannot watch file"), file);
/* On all known glib platforms, converting MONITOR directly to a
Lisp_Object value results is a Lisp integer, which is safe. This
--- 192,198 ----
/* Enable watch. */
monitor = g_file_monitor (gfile, gflags, NULL, NULL);
if (! monitor)
! xsignal2 (Qfile_notify_error, build_string ("Cannot watch file"), file);
/* On all known glib platforms, converting MONITOR directly to a
Lisp_Object value results is a Lisp integer, which is safe. This
***************
*** 202,208 ****
if (! INTEGERP (watch_descriptor))
{
g_object_unref (monitor);
! xsignal2 (Qfile_error, build_string ("Unsupported file watcher"), file);
}
g_signal_connect (monitor, "changed",
--- 201,208 ----
if (! INTEGERP (watch_descriptor))
{
g_object_unref (monitor);
! xsignal2 (Qfile_notify_error, build_string ("Unsupported file watcher"),
! file);
}
g_signal_connect (monitor, "changed",
***************
*** 226,239 ****
Lisp_Object watch_object = assq_no_quit (watch_descriptor, watch_list);
if (! CONSP (watch_object))
! xsignal2 (Qfile_error, build_string ("Not a watch descriptor"),
watch_descriptor);
eassert (INTEGERP (watch_descriptor));
int_monitor = XLI (watch_descriptor);
monitor = (GFileMonitor *) int_monitor;
if (!g_file_monitor_cancel (monitor))
! xsignal2 (Qfile_error, build_string ("Could not rm watch"),
watch_descriptor);
/* Remove watch descriptor from watch list. */
--- 226,239 ----
Lisp_Object watch_object = assq_no_quit (watch_descriptor, watch_list);
if (! CONSP (watch_object))
! xsignal2 (Qfile_notify_error, build_string ("Not a watch descriptor"),
watch_descriptor);
eassert (INTEGERP (watch_descriptor));
int_monitor = XLI (watch_descriptor);
monitor = (GFileMonitor *) int_monitor;
if (!g_file_monitor_cancel (monitor))
! xsignal2 (Qfile_notify_error, build_string ("Could not rm watch"),
watch_descriptor);
/* Remove watch descriptor from watch list. */
=== modified file 'src/inotify.c'
*** src/inotify.c 2013-01-02 16:30:50 +0000
--- src/inotify.c 2013-06-27 08:42:14 +0000
***************
*** 158,172 ****
to_read = 0;
if (ioctl (fd, FIONREAD, &to_read) == -1)
! report_file_error ("Error while trying to retrieve file system events",
! Qnil);
buffer = xmalloc (to_read);
n = read (fd, buffer, to_read);
if (n < 0)
{
xfree (buffer);
! report_file_error ("Error while trying to read file system events",
! Qnil);
}
EVENT_INIT (event);
--- 158,174 ----
to_read = 0;
if (ioctl (fd, FIONREAD, &to_read) == -1)
! xsignal1
! (Qfile_notify_error,
! build_string ("Error while trying to retrieve file system events"));
buffer = xmalloc (to_read);
n = read (fd, buffer, to_read);
if (n < 0)
{
xfree (buffer);
! xsignal1
! (Qfile_notify_error,
! build_string ("Error while trying to read file system events"));
}
EVENT_INIT (event);
***************
*** 242,248 ****
else if (EQ (symb, Qt) || EQ (symb, Qall_events))
return IN_ALL_EVENTS;
else
! signal_error ("Unknown aspect", symb);
}
static uint32_t
--- 244,250 ----
else if (EQ (symb, Qt) || EQ (symb, Qall_events))
return IN_ALL_EVENTS;
else
! xsignal2 (Qfile_notify_error, build_string ("Unknown aspect"), symb);
}
static uint32_t
***************
*** 335,342 ****
if (inotifyfd == -1)
{
inotifyfd = uninitialized;
! report_file_error ("File watching feature (inotify) is not available",
! Qnil);
}
watch_list = Qnil;
add_read_fd (inotifyfd, &inotify_callback, NULL);
--- 337,345 ----
if (inotifyfd == -1)
{
inotifyfd = uninitialized;
! xsignal1
! (Qfile_notify_error,
! build_string ("File watching feature (inotify) is not available"));
}
watch_list = Qnil;
add_read_fd (inotifyfd, &inotify_callback, NULL);
***************
*** 346,352 ****
encoded_file_name = ENCODE_FILE (file_name);
watchdesc = inotify_add_watch (inotifyfd, SSDATA (encoded_file_name), mask);
if (watchdesc == -1)
! report_file_error ("Could not add watch for file", Fcons (file_name, Qnil));
watch_descriptor = make_watch_descriptor (watchdesc);
--- 349,356 ----
encoded_file_name = ENCODE_FILE (file_name);
watchdesc = inotify_add_watch (inotifyfd, SSDATA (encoded_file_name), mask);
if (watchdesc == -1)
! xsignal2 (Qfile_notify_error,
! build_string ("Could not add watch for file"), file_name);
watch_descriptor = make_watch_descriptor (watchdesc);
***************
*** 375,382 ****
int wd = XINT (watch_descriptor);
if (inotify_rm_watch (inotifyfd, wd) == -1)
! report_file_error ("Could not rm watch", Fcons (watch_descriptor,
! Qnil));
/* Remove watch descriptor from watch list. */
watch_object = Fassoc (watch_descriptor, watch_list);
--- 379,386 ----
int wd = XINT (watch_descriptor);
if (inotify_rm_watch (inotifyfd, wd) == -1)
! xsignal2 (Qfile_notify_error,
! build_string ("Could not rm watch"), watch_descriptor);
/* Remove watch descriptor from watch list. */
watch_object = Fassoc (watch_descriptor, watch_list);
=== modified file 'src/lisp.h'
*** src/lisp.h 2013-06-21 20:11:44 +0000
--- src/lisp.h 2013-06-26 07:41:17 +0000
***************
*** 3799,3804 ****
--- 3799,3805 ----
/* Defined in fileio.c. */
extern Lisp_Object Qfile_error;
+ extern Lisp_Object Qfile_notify_error;
extern Lisp_Object Qfile_exists_p;
extern Lisp_Object Qfile_directory_p;
extern Lisp_Object Qinsert_file_contents;