aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2016-02-09 14:23:53 -0800
committerPaul Eggert2016-02-09 14:23:53 -0800
commit05595c2e59983db469e620c4f34b2eef5123391b (patch)
tree9c72fdb703ebbacb66a9ca08c7a3d4c5bef01049
parent8fa67e959bcc835c359981aae01f0dad3213451a (diff)
parent821213572075b3f5a97676f48aeb6733bf437277 (diff)
downloademacs-05595c2e59983db469e620c4f34b2eef5123391b.tar.gz
emacs-05595c2e59983db469e620c4f34b2eef5123391b.zip
-
-rw-r--r--configure.ac3
-rw-r--r--doc/misc/emacs-mime.texi34
-rw-r--r--doc/misc/gnus.texi2
-rw-r--r--etc/NEWS17
-rw-r--r--lisp/filenotify.el4
-rw-r--r--lisp/gnus/gnus-art.el57
-rw-r--r--lisp/gnus/message.el2
-rw-r--r--lisp/gnus/mm-decode.el38
-rw-r--r--lisp/gnus/mm-view.el2
-rw-r--r--lisp/gnus/mml-sec.el8
-rw-r--r--lisp/gnus/nnimap.el4
-rw-r--r--src/alloc.c70
-rw-r--r--src/lisp.h20
-rw-r--r--test/Makefile.in8
-rw-r--r--test/lisp/filenotify-tests.el179
15 files changed, 311 insertions, 137 deletions
diff --git a/configure.ac b/configure.ac
index 286ca5241ad..c3e25544fee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3370,7 +3370,7 @@ if test "${with_modules}" != "no"; then
3370 else 3370 else
3371 SAVE_LIBS=$LIBS 3371 SAVE_LIBS=$LIBS
3372 LIBS="$LIBS $LIBMODULES" 3372 LIBS="$LIBS $LIBMODULES"
3373 AC_CHECK_FUNCS([dlfunc]) 3373 AC_CHECK_FUNCS([dladdr dlfunc])
3374 LIBS=$SAVE_LIBS 3374 LIBS=$SAVE_LIBS
3375 fi 3375 fi
3376fi 3376fi
@@ -3383,7 +3383,6 @@ if test "${HAVE_MODULES}" = yes; then
3383fi 3383fi
3384AC_SUBST(MODULES_OBJ) 3384AC_SUBST(MODULES_OBJ)
3385AC_SUBST(LIBMODULES) 3385AC_SUBST(LIBMODULES)
3386AC_CHECK_FUNCS(dladdr)
3387 3386
3388### Use -lpng if available, unless '--with-png=no'. 3387### Use -lpng if available, unless '--with-png=no'.
3389HAVE_PNG=no 3388HAVE_PNG=no
diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi
index b252b116a1c..ae1e09105ba 100644
--- a/doc/misc/emacs-mime.texi
+++ b/doc/misc/emacs-mime.texi
@@ -412,17 +412,31 @@ information about emacs-w3m}, @code{links}, @code{lynx},
412external viewer. You can also specify a function, which will be 412external viewer. You can also specify a function, which will be
413called with a @acronym{MIME} handle as the argument. 413called with a @acronym{MIME} handle as the argument.
414 414
415@item mm-inline-text-html-with-images 415@item mm-html-inhibit-images
416@vindex mm-html-inhibit-images
416@vindex mm-inline-text-html-with-images 417@vindex mm-inline-text-html-with-images
417Some @acronym{HTML} mails might have the trick of spammers using 418If this is non-@code{nil}, inhibit displaying of images inline in the
418@samp{<img>} tags. It is likely to be intended to verify whether you 419article body. It is effective to images in @acronym{HTML} articles
419have read the mail. You can prevent your personal information from 420rendered when @code{mm-text-html-renderer} (@pxref{Display
420leaking by setting this option to @code{nil} (which is the default). 421Customization}) is @code{shr} or @code{w3m}. In Gnus, this is
421For emacs-w3m, you may use the command @kbd{t} on the image anchor to 422overridden by the value of @code{gnus-inhibit-images} (@pxref{Misc
422show an image even if it is @code{nil}.@footnote{The command @kbd{T} 423Article, ,Misc Article, gnus, Gnus manual}).
423will load all images. If you have set the option 424
424@code{w3m-key-binding} to @code{info}, use @kbd{i} or @kbd{I} 425@item mm-html-blocked-images
425instead.} 426@vindex mm-html-blocked-images
427External images that have @acronym{URL}s that match this regexp won't
428be fetched and displayed. For instance, to block all @acronym{URL}s
429that have the string ``ads'' in them, do the following:
430
431@lisp
432(setq mm-html-blocked-images "ads")
433@end lisp
434
435It is effective when @code{mm-text-html-renderer} (@pxref{Display
436Customization}) is @code{shr}. In Gnus, this is overridden by the value
437of @code{gnus-blocked-images} or the return value of the function that
438@code{gnus-blocked-images} is set to (@pxref{HTML, ,HTML, gnus, Gnus
439manual}).
426 440
427@item mm-w3m-safe-url-regexp 441@item mm-w3m-safe-url-regexp
428@vindex mm-w3m-safe-url-regexp 442@vindex mm-w3m-safe-url-regexp
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index e6e3e7617ee..fa7cd09123c 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -11790,7 +11790,7 @@ renderer. If set to @code{gnus-w3m}, it uses @code{w3m}.
11790@item gnus-blocked-images 11790@item gnus-blocked-images
11791@vindex gnus-blocked-images 11791@vindex gnus-blocked-images
11792External images that have @acronym{URL}s that match this regexp won't 11792External images that have @acronym{URL}s that match this regexp won't
11793be fetched and displayed. For instance, do block all @acronym{URL}s 11793be fetched and displayed. For instance, to block all @acronym{URL}s
11794that have the string ``ads'' in them, do the following: 11794that have the string ``ads'' in them, do the following:
11795 11795
11796@lisp 11796@lisp
diff --git a/etc/NEWS b/etc/NEWS
index 717c6bc89ab..f0a3bec4525 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -359,12 +359,17 @@ as you type. See also the new variable ‘text-quoting-style’.
359** New minor mode global-eldoc-mode is enabled by default. 359** New minor mode global-eldoc-mode is enabled by default.
360 360
361--- 361---
362** Emacs now supports "bracketed paste mode" when running on a terminal 362** Emacs now uses "bracketed paste mode" on text terminals that support it.
363that supports it. This facility allows Emacs to understand pasted 363Bracketed paste mode causes text terminals to wrap pasted text in special
364chunks of text as strings to be inserted, instead of interpreting each 364escape sequences that allow Emacs to tell the difference between text
365character in the pasted text as actual user input. This results in a 365you type and text you paste from other applications. Emacs then
366paste experience similar to that under a window system, and significant 366avoids interpreting each character in the pasted text as it does with
367performance improvements when pasting large amounts of text. 367keyboard input, which results in a paste experience similar to that
368under a window system, and significant performance improvements when
369pasting large amounts of text.
370
371Bracketed paste mode is disabled by default, so Emacs automatically
372enables it at startup if the terminal supports it.
368 373
369+++ 374+++
370** Emacs now supports the latest version of the UBA. 375** Emacs now supports the latest version of the UBA.
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index faa801ee6e7..66e7fd7a315 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -242,10 +242,14 @@ EVENT is the cadr of the event in `file-notify-handle-event'
242 (and 242 (and
243 (memq action '(deleted renamed)) 243 (memq action '(deleted renamed))
244 (= (length (cdr registered)) 1) 244 (= (length (cdr registered)) 1)
245 ;; Not, when a file is backed up.
246 (not (and (stringp file1) (backup-file-name-p file1)))
245 (or 247 (or
248 ;; Watched file or directory is concerned.
246 (string-equal 249 (string-equal
247 (file-name-nondirectory file) 250 (file-name-nondirectory file)
248 (file-name-nondirectory (car registered))) 251 (file-name-nondirectory (car registered)))
252 ;; File inside a watched directory is concerned.
249 (string-equal 253 (string-equal
250 (file-name-nondirectory file) 254 (file-name-nondirectory file)
251 (car (cadr registered))))))) 255 (car (cadr registered)))))))
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index f36fdd29d62..238a67f5532 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -2258,8 +2258,7 @@ This only works if the article in question is HTML."
2258 (save-restriction 2258 (save-restriction
2259 (widen) 2259 (widen)
2260 (if (eq mm-text-html-renderer 'w3m) 2260 (if (eq mm-text-html-renderer 'w3m)
2261 (let ((mm-inline-text-html-with-images nil)) 2261 (w3m-toggle-inline-images)
2262 (w3m-toggle-inline-images))
2263 (dolist (region (gnus-find-text-property-region (point-min) (point-max) 2262 (dolist (region (gnus-find-text-property-region (point-min) (point-max)
2264 'image-displayer)) 2263 'image-displayer))
2265 (destructuring-bind (start end function) region 2264 (destructuring-bind (start end function) region
@@ -4929,25 +4928,30 @@ General format specifiers can also be used. See Info node
4929 (vector (caddr c) (car c) :active t)) 4928 (vector (caddr c) (car c) :active t))
4930 gnus-url-button-commands))) 4929 gnus-url-button-commands)))
4931 4930
4932(defmacro gnus-bind-safe-url-regexp (&rest body) 4931(defmacro gnus-bind-mm-vars (&rest body)
4933 "Bind `mm-w3m-safe-url-regexp' according to `gnus-safe-html-newsgroups'." 4932 "Bind some mm-* variables and execute BODY."
4934 `(let ((mm-w3m-safe-url-regexp 4933 `(let (mm-html-inhibit-images
4935 (let ((group (if (and (derived-mode-p 'gnus-article-mode) 4934 mm-html-blocked-images
4936 (gnus-buffer-live-p 4935 (mm-w3m-safe-url-regexp mm-w3m-safe-url-regexp))
4937 gnus-article-current-summary)) 4936 (with-current-buffer
4938 (with-current-buffer gnus-article-current-summary 4937 (cond ((derived-mode-p 'gnus-article-mode)
4939 gnus-newsgroup-name) 4938 (if (gnus-buffer-live-p gnus-article-current-summary)
4940 gnus-newsgroup-name))) 4939 gnus-article-current-summary
4941 (if (cond ((not group) 4940 ;; Maybe we're in a mml-preview buffer
4942 ;; Maybe we're in a mml-preview buffer 4941 ;; and no group is selected.
4943 ;; and no group is selected. 4942 (current-buffer)))
4944 t) 4943 ((gnus-buffer-live-p gnus-summary-buffer)
4945 ((stringp gnus-safe-html-newsgroups) 4944 gnus-summary-buffer)
4946 (string-match gnus-safe-html-newsgroups group)) 4945 (t (current-buffer)))
4947 ((consp gnus-safe-html-newsgroups) 4946 (setq mm-html-inhibit-images gnus-inhibit-images
4948 (member group gnus-safe-html-newsgroups))) 4947 mm-html-blocked-images (gnus-blocked-images))
4949 nil 4948 (when (or (not gnus-newsgroup-name)
4950 mm-w3m-safe-url-regexp)))) 4949 (and (stringp gnus-safe-html-newsgroups)
4950 (string-match gnus-safe-html-newsgroups
4951 gnus-newsgroup-name))
4952 (and (consp gnus-safe-html-newsgroups)
4953 (member gnus-newsgroup-name gnus-safe-html-newsgroups)))
4954 (setq mm-w3m-safe-url-regexp nil)))
4951 ,@body)) 4955 ,@body))
4952 4956
4953(defun gnus-mime-button-menu (event prefix) 4957(defun gnus-mime-button-menu (event prefix)
@@ -4975,7 +4979,7 @@ General format specifiers can also be used. See Info node
4975 (or (search-forward "\n\n") (goto-char (point-max))) 4979 (or (search-forward "\n\n") (goto-char (point-max)))
4976 (let ((inhibit-read-only t)) 4980 (let ((inhibit-read-only t))
4977 (delete-region (point) (point-max)) 4981 (delete-region (point) (point-max))
4978 (gnus-bind-safe-url-regexp (mm-display-parts handles))))))) 4982 (gnus-bind-mm-vars (mm-display-parts handles)))))))
4979 4983
4980(defun gnus-article-jump-to-part (n) 4984(defun gnus-article-jump-to-part (n)
4981 "Jump to MIME part N." 4985 "Jump to MIME part N."
@@ -5514,8 +5518,7 @@ If no internal viewer is available, use an external viewer."
5514 (gnus-mime-view-part-as-type 5518 (gnus-mime-view-part-as-type
5515 nil (lambda (type) (mm-inlinable-p handle type))) 5519 nil (lambda (type) (mm-inlinable-p handle type)))
5516 (when handle 5520 (when handle
5517 (gnus-bind-safe-url-regexp 5521 (gnus-bind-mm-vars (mm-display-part handle nil t))))))
5518 (mm-display-part handle nil t))))))
5519 5522
5520(defun gnus-mime-action-on-part (&optional action) 5523(defun gnus-mime-action-on-part (&optional action)
5521 "Do something with the MIME attachment at (point)." 5524 "Do something with the MIME attachment at (point)."
@@ -5745,7 +5748,7 @@ all parts."
5745 (mm-inlined-p handle) 5748 (mm-inlined-p handle)
5746 t) 5749 t)
5747 (with-temp-buffer 5750 (with-temp-buffer
5748 (gnus-bind-safe-url-regexp 5751 (gnus-bind-mm-vars
5749 (setq retval (mm-display-part handle))) 5752 (setq retval (mm-display-part handle)))
5750 (unless (zerop (buffer-size)) 5753 (unless (zerop (buffer-size))
5751 (buffer-string)))))) 5754 (buffer-string))))))
@@ -6106,7 +6109,7 @@ If nil, don't show those extra buttons."
6106 (set-buffer gnus-summary-buffer) 6109 (set-buffer gnus-summary-buffer)
6107 (error)) 6110 (error))
6108 gnus-newsgroup-ignored-charsets))) 6111 gnus-newsgroup-ignored-charsets)))
6109 (gnus-bind-safe-url-regexp (mm-display-part handle t)))) 6112 (gnus-bind-mm-vars (mm-display-part handle t))))
6110 ((and text not-attachment) 6113 ((and text not-attachment)
6111 (mm-display-inline handle))) 6114 (mm-display-inline handle)))
6112 (goto-char (point-max)) 6115 (goto-char (point-max))
@@ -6236,7 +6239,7 @@ If nil, don't show those extra buttons."
6236 (mail-parse-ignored-charsets 6239 (mail-parse-ignored-charsets
6237 (with-current-buffer gnus-summary-buffer 6240 (with-current-buffer gnus-summary-buffer
6238 gnus-newsgroup-ignored-charsets))) 6241 gnus-newsgroup-ignored-charsets)))
6239 (gnus-bind-safe-url-regexp (mm-display-part preferred)) 6242 (gnus-bind-mm-vars (mm-display-part preferred))
6240 ;; Do highlighting. 6243 ;; Do highlighting.
6241 (save-excursion 6244 (save-excursion
6242 (save-restriction 6245 (save-restriction
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 5551820a2cd..6ee5264a4e7 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -2418,6 +2418,8 @@ With prefix-argument just set Follow-Up, don't cross-post."
2418 nil nil '("poster" . 0) 2418 nil nil '("poster" . 0)
2419 (if (boundp 'gnus-group-history) 2419 (if (boundp 'gnus-group-history)
2420 'gnus-group-history)))) 2420 'gnus-group-history))))
2421 (when (fboundp 'gnus-group-real-name)
2422 (setq target-group (gnus-group-real-name target-group)))
2421 (cond ((not (or (null target-group) ; new subject not empty 2423 (cond ((not (or (null target-group) ; new subject not empty
2422 (zerop (string-width target-group)) 2424 (zerop (string-width target-group))
2423 (string-match "^[ \t]*$" target-group))) 2425 (string-match "^[ \t]*$" target-group)))
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 79fc74a13cf..c6cb6520255 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -145,14 +145,23 @@ nil : use external viewer (default web browser)."
145 (function)) 145 (function))
146 :group 'mime-display) 146 :group 'mime-display)
147 147
148(defcustom mm-inline-text-html-with-images nil 148(defcustom mm-html-inhibit-images
149 "If non-nil, Gnus will allow retrieving images in HTML that has <img> tags. 149 (if (boundp 'mm-inline-text-html-with-images)
150See also the documentation for the `mm-w3m-safe-url-regexp' 150 (not (symbol-value 'mm-inline-text-html-with-images))
151variable." 151 t)
152 :version "22.1" 152 "Non-nil means inhibit displaying of images inline in the article body."
153 :version "25.1"
153 :type 'boolean 154 :type 'boolean
154 :group 'mime-display) 155 :group 'mime-display)
155 156
157(defcustom mm-html-blocked-images ""
158 "Regexp matching image URLs to be blocked, or nil meaning not to block.
159Note that cid images that are embedded in a message won't be blocked."
160 :version "25.1"
161 :type '(choice (const :tag "Allow all" nil)
162 (regexp :tag "Regular expression"))
163 :group 'mime-display)
164
156(defcustom mm-w3m-safe-url-regexp "\\`cid:" 165(defcustom mm-w3m-safe-url-regexp "\\`cid:"
157 "Regexp matching URLs which are considered to be safe. 166 "Regexp matching URLs which are considered to be safe.
158Some HTML mails might contain a nasty trick used by spammers, using 167Some HTML mails might contain a nasty trick used by spammers, using
@@ -543,7 +552,7 @@ into
543 552
544\(a 1 b 2 c 3) 553\(a 1 b 2 c 3)
545 554
546The original alist is not modified. See also `destructive-alist-to-plist'." 555The original alist is not modified."
547 (let (plist) 556 (let (plist)
548 (while alist 557 (while alist
549 (let ((el (car alist))) 558 (let ((el (car alist)))
@@ -1828,14 +1837,11 @@ If RECURSIVE, search recursively."
1828(declare-function shr-insert-document "shr" (dom)) 1837(declare-function shr-insert-document "shr" (dom))
1829(defvar shr-blocked-images) 1838(defvar shr-blocked-images)
1830(defvar shr-use-fonts) 1839(defvar shr-use-fonts)
1831(defvar gnus-inhibit-images)
1832(autoload 'gnus-blocked-images "gnus-art")
1833 1840
1834(defun mm-shr (handle) 1841(defun mm-shr (handle)
1835 ;; Require since we bind its variables. 1842 ;; Require since we bind its variables.
1836 (require 'shr) 1843 (require 'shr)
1837 (let ((article-buffer (current-buffer)) 1844 (let ((shr-width (if (and (boundp 'shr-use-fonts)
1838 (shr-width (if (and (boundp 'shr-use-fonts)
1839 shr-use-fonts) 1845 shr-use-fonts)
1840 nil 1846 nil
1841 fill-column)) 1847 fill-column))
@@ -1844,15 +1850,9 @@ If RECURSIVE, search recursively."
1844 (when handle 1850 (when handle
1845 (mm-with-part handle 1851 (mm-with-part handle
1846 (buffer-string)))))) 1852 (buffer-string))))))
1847 shr-inhibit-images shr-blocked-images charset char) 1853 (shr-inhibit-images mm-html-inhibit-images)
1848 (if (and (boundp 'gnus-summary-buffer) 1854 (shr-blocked-images mm-html-blocked-images)
1849 (bufferp gnus-summary-buffer) 1855 charset char)
1850 (buffer-name gnus-summary-buffer))
1851 (with-current-buffer gnus-summary-buffer
1852 (setq shr-inhibit-images gnus-inhibit-images
1853 shr-blocked-images (gnus-blocked-images)))
1854 (setq shr-inhibit-images gnus-inhibit-images
1855 shr-blocked-images (gnus-blocked-images)))
1856 (unless handle 1856 (unless handle
1857 (setq handle (mm-dissect-buffer t))) 1857 (setq handle (mm-dissect-buffer t)))
1858 (setq charset (mail-content-type-get (mm-handle-type handle) 'charset)) 1858 (setq charset (mail-content-type-get (mm-handle-type handle) 'charset))
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index 9942455300d..8e1e3e782cf 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -141,7 +141,7 @@
141 (push (cons 'gnus-article-mode 'mm-w3m-cid-retrieve) 141 (push (cons 'gnus-article-mode 'mm-w3m-cid-retrieve)
142 w3m-cid-retrieve-function-alist)) 142 w3m-cid-retrieve-function-alist))
143 (setq mm-w3m-setup t)) 143 (setq mm-w3m-setup t))
144 (setq w3m-display-inline-images mm-inline-text-html-with-images)) 144 (setq w3m-display-inline-images (not mm-html-inhibit-images)))
145 145
146(defun mm-w3m-cid-retrieve-1 (url handle) 146(defun mm-w3m-cid-retrieve-1 (url handle)
147 (dolist (elem handle) 147 (dolist (elem handle)
diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el
index 48e6384497e..3ac3da0127d 100644
--- a/lisp/gnus/mml-sec.el
+++ b/lisp/gnus/mml-sec.el
@@ -655,10 +655,10 @@ The passphrase is read and cached."
655 (catch 'break 655 (catch 'break
656 (dolist (uid uids nil) 656 (dolist (uid uids nil)
657 (if (and (stringp (epg-user-id-string uid)) 657 (if (and (stringp (epg-user-id-string uid))
658 (equal (car (mail-header-parse-address 658 (equal (downcase (car (mail-header-parse-address
659 (epg-user-id-string uid))) 659 (epg-user-id-string uid))))
660 (car (mail-header-parse-address 660 (downcase (car (mail-header-parse-address
661 recipient))) 661 recipient))))
662 (not (memq (epg-user-id-validity uid) 662 (not (memq (epg-user-id-validity uid)
663 '(revoked expired)))) 663 '(revoked expired))))
664 (throw 'break t)))))) 664 (throw 'break t))))))
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index c285befc760..130658cd367 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -1831,7 +1831,9 @@ Return the server's response to the SELECT or EXAMINE command."
1831 (let ((open-result t)) 1831 (let ((open-result t))
1832 (when (and server 1832 (when (and server
1833 (not (nnimap-server-opened server))) 1833 (not (nnimap-server-opened server)))
1834 (setq open-result (nnimap-open-server server nil no-reconnect))) 1834 (let ((method (gnus-server-to-method server)))
1835 (setq open-result (nnimap-open-server (nth 1 method) (nthcdr 2 method)
1836 no-reconnect))))
1835 (cond 1837 (cond
1836 ((not open-result) 1838 ((not open-result)
1837 nil) 1839 nil)
diff --git a/src/alloc.c b/src/alloc.c
index 7364d7c4047..81cfdb011dc 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -819,8 +819,10 @@ malloc_unblock_input (void)
819 malloc_probe (size); \ 819 malloc_probe (size); \
820 } while (0) 820 } while (0)
821 821
822static void *lmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1));
823static void *lrealloc (void *, size_t);
822 824
823/* Like malloc but check for no memory and block interrupt input.. */ 825/* Like malloc but check for no memory and block interrupt input. */
824 826
825void * 827void *
826xmalloc (size_t size) 828xmalloc (size_t size)
@@ -828,7 +830,7 @@ xmalloc (size_t size)
828 void *val; 830 void *val;
829 831
830 MALLOC_BLOCK_INPUT; 832 MALLOC_BLOCK_INPUT;
831 val = malloc (size); 833 val = lmalloc (size);
832 MALLOC_UNBLOCK_INPUT; 834 MALLOC_UNBLOCK_INPUT;
833 835
834 if (!val && size) 836 if (!val && size)
@@ -845,7 +847,7 @@ xzalloc (size_t size)
845 void *val; 847 void *val;
846 848
847 MALLOC_BLOCK_INPUT; 849 MALLOC_BLOCK_INPUT;
848 val = malloc (size); 850 val = lmalloc (size);
849 MALLOC_UNBLOCK_INPUT; 851 MALLOC_UNBLOCK_INPUT;
850 852
851 if (!val && size) 853 if (!val && size)
@@ -866,9 +868,9 @@ xrealloc (void *block, size_t size)
866 /* We must call malloc explicitly when BLOCK is 0, since some 868 /* We must call malloc explicitly when BLOCK is 0, since some
867 reallocs don't do this. */ 869 reallocs don't do this. */
868 if (! block) 870 if (! block)
869 val = malloc (size); 871 val = lmalloc (size);
870 else 872 else
871 val = realloc (block, size); 873 val = lrealloc (block, size);
872 MALLOC_UNBLOCK_INPUT; 874 MALLOC_UNBLOCK_INPUT;
873 875
874 if (!val && size) 876 if (!val && size)
@@ -1070,7 +1072,7 @@ lisp_malloc (size_t nbytes, enum mem_type type)
1070 allocated_mem_type = type; 1072 allocated_mem_type = type;
1071#endif 1073#endif
1072 1074
1073 val = malloc (nbytes); 1075 val = lmalloc (nbytes);
1074 1076
1075#if ! USE_LSB_TAG 1077#if ! USE_LSB_TAG
1076 /* If the memory just allocated cannot be addressed thru a Lisp 1078 /* If the memory just allocated cannot be addressed thru a Lisp
@@ -1364,6 +1366,62 @@ lisp_align_free (void *block)
1364 MALLOC_UNBLOCK_INPUT; 1366 MALLOC_UNBLOCK_INPUT;
1365} 1367}
1366 1368
1369#if !defined __GNUC__ && !defined __alignof__
1370# define __alignof__(type) alignof (type)
1371#endif
1372
1373/* True if malloc returns a multiple of GCALIGNMENT. In practice this
1374 holds if __alignof__ (max_align_t) is a multiple. Use __alignof__
1375 if available, as otherwise this check would fail with GCC x86.
1376 This is a macro, not an enum constant, for portability to HP-UX
1377 10.20 cc and AIX 3.2.5 xlc. */
1378#define MALLOC_IS_GC_ALIGNED (__alignof__ (max_align_t) % GCALIGNMENT == 0)
1379
1380/* True if P is suitably aligned for SIZE, where Lisp alignment may be
1381 needed if SIZE is Lisp-aligned. */
1382
1383static bool
1384laligned (void *p, size_t size)
1385{
1386 return (MALLOC_IS_GC_ALIGNED || size % GCALIGNMENT != 0
1387 || (intptr_t) p % GCALIGNMENT == 0);
1388}
1389
1390/* Like malloc and realloc except that if SIZE is Lisp-aligned, make
1391 sure the result is too. */
1392
1393static void *
1394lmalloc (size_t size)
1395{
1396#if USE_ALIGNED_ALLOC
1397 if (! MALLOC_IS_GC_ALIGNED)
1398 return aligned_alloc (GCALIGNMENT, size);
1399#endif
1400
1401 void *p;
1402 while (true)
1403 {
1404 p = malloc (size);
1405 if (laligned (p, size))
1406 break;
1407 free (p);
1408 }
1409
1410 eassert ((intptr_t) p % GCALIGNMENT == 0);
1411 return p;
1412}
1413
1414static void *
1415lrealloc (void *p, size_t size)
1416{
1417 do
1418 p = realloc (p, size);
1419 while (! laligned (p, size));
1420
1421 eassert ((intptr_t) p % GCALIGNMENT == 0);
1422 return p;
1423}
1424
1367 1425
1368/*********************************************************************** 1426/***********************************************************************
1369 Interval Allocation 1427 Interval Allocation
diff --git a/src/lisp.h b/src/lisp.h
index 21301702620..f71394e8784 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -67,20 +67,6 @@ DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS)
67#define GCTYPEBITS 3 67#define GCTYPEBITS 3
68DEFINE_GDB_SYMBOL_END (GCTYPEBITS) 68DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
69 69
70/* The number of bits needed in an EMACS_INT over and above the number
71 of bits in a pointer. This is 0 on systems where:
72 1. We can specify multiple-of-8 alignment on static variables.
73 2. We know malloc returns a multiple of 8. */
74#if (defined alignas \
75 && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \
76 || defined CYGWIN || defined __MINGW32__ \
77 || defined DARWIN_OS || defined __FreeBSD__ \
78 || defined __sun))
79# define NONPOINTER_BITS 0
80#else
81# define NONPOINTER_BITS GCTYPEBITS
82#endif
83
84/* EMACS_INT - signed integer wide enough to hold an Emacs value 70/* EMACS_INT - signed integer wide enough to hold an Emacs value
85 EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if 71 EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if
86 pI - printf length modifier for EMACS_INT 72 pI - printf length modifier for EMACS_INT
@@ -88,18 +74,16 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
88#ifndef EMACS_INT_MAX 74#ifndef EMACS_INT_MAX
89# if INTPTR_MAX <= 0 75# if INTPTR_MAX <= 0
90# error "INTPTR_MAX misconfigured" 76# error "INTPTR_MAX misconfigured"
91# elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT 77# elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT
92typedef int EMACS_INT; 78typedef int EMACS_INT;
93typedef unsigned int EMACS_UINT; 79typedef unsigned int EMACS_UINT;
94# define EMACS_INT_MAX INT_MAX 80# define EMACS_INT_MAX INT_MAX
95# define pI "" 81# define pI ""
96# elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT 82# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
97typedef long int EMACS_INT; 83typedef long int EMACS_INT;
98typedef unsigned long EMACS_UINT; 84typedef unsigned long EMACS_UINT;
99# define EMACS_INT_MAX LONG_MAX 85# define EMACS_INT_MAX LONG_MAX
100# define pI "l" 86# define pI "l"
101/* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS.
102 In theory this is not safe, but in practice it seems to be OK. */
103# elif INTPTR_MAX <= LLONG_MAX 87# elif INTPTR_MAX <= LLONG_MAX
104typedef long long int EMACS_INT; 88typedef long long int EMACS_INT;
105typedef unsigned long long int EMACS_UINT; 89typedef unsigned long long int EMACS_UINT;
diff --git a/test/Makefile.in b/test/Makefile.in
index 0034f104598..e651c6caf0b 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -89,10 +89,14 @@ WRITE_LOG = > $@ 2>&1 || { stat=ERROR; cat $@; }; echo $$stat: $@
89## Beware: it approximates 'no-byte-compile', so watch out for false-positives! 89## Beware: it approximates 'no-byte-compile', so watch out for false-positives!
90SELECTOR_DEFAULT = (quote (not (tag :expensive-test))) 90SELECTOR_DEFAULT = (quote (not (tag :expensive-test)))
91SELECTOR_EXPENSIVE = nil 91SELECTOR_EXPENSIVE = nil
92ifndef SELECTOR 92ifdef SELECTOR
93SELECTOR_ACTUAL=$(SELECTOR)
94else ifeq ($(MAKECMDGOALS),check)
95SELECTOR_ACTUAL=$(SELECTOR_DEFAULT)
96else ifeq ($(MAKECMDGOALS),check-maybe)
93SELECTOR_ACTUAL=$(SELECTOR_DEFAULT) 97SELECTOR_ACTUAL=$(SELECTOR_DEFAULT)
94else 98else
95SELECTOR_ACTUAL=$(SELECTOR) 99SELECTOR_ACTUAL=$(SELECTOR_EXPENSIVE)
96endif 100endif
97 101
98 102
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el
index 5fc4ff8bf42..a8521828c0e 100644
--- a/test/lisp/filenotify-tests.el
+++ b/test/lisp/filenotify-tests.el
@@ -62,6 +62,10 @@
62(defvar file-notify--test-event nil) 62(defvar file-notify--test-event nil)
63(defvar file-notify--test-events nil) 63(defvar file-notify--test-events nil)
64 64
65(defconst file-notify--test-read-event-timeout 0.02
66 "Timeout for `read-event' calls.
67It is different for local and remote file notification libraries.")
68
65(defun file-notify--test-timeout () 69(defun file-notify--test-timeout ()
66 "Timeout to wait for arriving events, in seconds." 70 "Timeout to wait for arriving events, in seconds."
67 (cond 71 (cond
@@ -74,19 +78,20 @@
74 "Cleanup after a test." 78 "Cleanup after a test."
75 (file-notify-rm-watch file-notify--test-desc) 79 (file-notify-rm-watch file-notify--test-desc)
76 80
77 (when (and file-notify--test-tmpfile 81 (ignore-errors
78 (file-exists-p file-notify--test-tmpfile)) 82 (delete-file (file-newest-backup file-notify--test-tmpfile)))
83 (ignore-errors
79 (if (file-directory-p file-notify--test-tmpfile) 84 (if (file-directory-p file-notify--test-tmpfile)
80 (delete-directory file-notify--test-tmpfile 'recursive) 85 (delete-directory file-notify--test-tmpfile 'recursive)
81 (delete-file file-notify--test-tmpfile))) 86 (delete-file file-notify--test-tmpfile)))
82 (when (and file-notify--test-tmpfile1 87 (ignore-errors
83 (file-exists-p file-notify--test-tmpfile1))
84 (if (file-directory-p file-notify--test-tmpfile1) 88 (if (file-directory-p file-notify--test-tmpfile1)
85 (delete-directory file-notify--test-tmpfile1 'recursive) 89 (delete-directory file-notify--test-tmpfile1 'recursive)
86 (delete-file file-notify--test-tmpfile1))) 90 (delete-file file-notify--test-tmpfile1)))
87 (when (file-remote-p temporary-file-directory) 91 (ignore-errors
88 (tramp-cleanup-connection 92 (when (file-remote-p temporary-file-directory)
89 (tramp-dissect-file-name temporary-file-directory) nil 'keep-password)) 93 (tramp-cleanup-connection
94 (tramp-dissect-file-name temporary-file-directory) nil 'keep-password)))
90 95
91 (setq file-notify--test-tmpfile nil 96 (setq file-notify--test-tmpfile nil
92 file-notify--test-tmpfile1 nil 97 file-notify--test-tmpfile1 nil
@@ -155,6 +160,7 @@ remote host, or nil."
155 :tags '(:expensive-test) 160 :tags '(:expensive-test)
156 (let* ((temporary-file-directory 161 (let* ((temporary-file-directory
157 file-notify-test-remote-temporary-file-directory) 162 file-notify-test-remote-temporary-file-directory)
163 (file-notify--test-read-event-timeout 0.1)
158 (ert-test (ert-get-test ',test))) 164 (ert-test (ert-get-test ',test)))
159 (skip-unless (file-notify--test-remote-enabled)) 165 (skip-unless (file-notify--test-remote-enabled))
160 (tramp-cleanup-connection 166 (tramp-cleanup-connection
@@ -285,7 +291,27 @@ and the event to `file-notify--test-events'."
285TIMEOUT is the maximum time to wait for, in seconds." 291TIMEOUT is the maximum time to wait for, in seconds."
286 `(with-timeout (,timeout (ignore)) 292 `(with-timeout (,timeout (ignore))
287 (while (null ,until) 293 (while (null ,until)
288 (read-event nil nil 0.1)))) 294 (read-event nil nil file-notify--test-read-event-timeout))))
295
296(defun file-notify--test-with-events-check (events)
297 "Check whether received events match one of the EVENTS alternatives."
298 (let (result)
299 (dolist (elt events result)
300 (setq result
301 (or result
302 (equal elt (mapcar #'cadr file-notify--test-events)))))))
303
304(defun file-notify--test-with-events-explainer (events)
305 "Explain why `file-notify--test-with-events-check' fails."
306 (if (null (cdr events))
307 (format "Received events `%s' do not match expected events `%s'"
308 (mapcar #'cadr file-notify--test-events) (car events))
309 (format
310 "Received events `%s' do not match any sequence of expected events `%s'"
311 (mapcar #'cadr file-notify--test-events) events)))
312
313(put 'file-notify--test-with-events-check 'ert-explainer
314 'file-notify--test-with-events-explainer)
289 315
290(defmacro file-notify--test-with-events (events &rest body) 316(defmacro file-notify--test-with-events (events &rest body)
291 "Run BODY collecting events and then compare with EVENTS. 317 "Run BODY collecting events and then compare with EVENTS.
@@ -297,7 +323,7 @@ longer than timeout seconds for the events to be delivered."
297 `(let* ((,outer file-notify--test-events) 323 `(let* ((,outer file-notify--test-events)
298 (events (if (consp (car ,events)) ,events (list ,events))) 324 (events (if (consp (car ,events)) ,events (list ,events)))
299 (max-length (apply 'max (mapcar 'length events))) 325 (max-length (apply 'max (mapcar 'length events)))
300 create-lockfiles result) 326 create-lockfiles)
301 ;; Flush pending events. 327 ;; Flush pending events.
302 (file-notify--wait-for-events 328 (file-notify--wait-for-events
303 (file-notify--test-timeout) 329 (file-notify--test-timeout)
@@ -309,11 +335,7 @@ longer than timeout seconds for the events to be delivered."
309 (* (ceiling max-length 100) (file-notify--test-timeout)) 335 (* (ceiling max-length 100) (file-notify--test-timeout))
310 (= max-length (length file-notify--test-events))) 336 (= max-length (length file-notify--test-events)))
311 ;; One of the possible results shall match. 337 ;; One of the possible results shall match.
312 (should 338 (should (file-notify--test-with-events-check events))
313 (dolist (elt events result)
314 (setq result
315 (or result
316 (equal elt (mapcar #'cadr file-notify--test-events))))))
317 (setq ,outer (append ,outer file-notify--test-events))) 339 (setq ,outer (append ,outer file-notify--test-events)))
318 (setq file-notify--test-events ,outer)))) 340 (setq file-notify--test-events ,outer))))
319 341
@@ -342,7 +364,7 @@ longer than timeout seconds for the events to be delivered."
342 (t '(created changed deleted stopped))) 364 (t '(created changed deleted stopped)))
343 (write-region 365 (write-region
344 "another text" nil file-notify--test-tmpfile nil 'no-message) 366 "another text" nil file-notify--test-tmpfile nil 'no-message)
345 (read-event nil nil 0.1) 367 (read-event nil nil file-notify--test-read-event-timeout)
346 (delete-file file-notify--test-tmpfile)) 368 (delete-file file-notify--test-tmpfile))
347 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 369 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
348 (let (file-notify--test-events) 370 (let (file-notify--test-events)
@@ -371,10 +393,10 @@ longer than timeout seconds for the events to be delivered."
371 '((changed deleted stopped) 393 '((changed deleted stopped)
372 (changed changed deleted stopped))) 394 (changed changed deleted stopped)))
373 (t '(changed changed deleted stopped))) 395 (t '(changed changed deleted stopped)))
374 (read-event nil nil 0.1) 396 (read-event nil nil file-notify--test-read-event-timeout)
375 (write-region 397 (write-region
376 "another text" nil file-notify--test-tmpfile nil 'no-message) 398 "another text" nil file-notify--test-tmpfile nil 'no-message)
377 (read-event nil nil 0.1) 399 (read-event nil nil file-notify--test-read-event-timeout)
378 (delete-file file-notify--test-tmpfile)) 400 (delete-file file-notify--test-tmpfile))
379 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 401 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
380 (let (file-notify--test-events) 402 (let (file-notify--test-events)
@@ -405,10 +427,10 @@ longer than timeout seconds for the events to be delivered."
405 ((string-equal (file-notify--test-library) "kqueue") 427 ((string-equal (file-notify--test-library) "kqueue")
406 '(created changed deleted stopped)) 428 '(created changed deleted stopped))
407 (t '(created changed deleted deleted stopped))) 429 (t '(created changed deleted deleted stopped)))
408 (read-event nil nil 0.1) 430 (read-event nil nil file-notify--test-read-event-timeout)
409 (write-region 431 (write-region
410 "any text" nil file-notify--test-tmpfile nil 'no-message) 432 "any text" nil file-notify--test-tmpfile nil 'no-message)
411 (read-event nil nil 0.1) 433 (read-event nil nil file-notify--test-read-event-timeout)
412 (delete-directory temporary-file-directory 'recursive)) 434 (delete-directory temporary-file-directory 'recursive))
413 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 435 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
414 (let (file-notify--test-events) 436 (let (file-notify--test-events)
@@ -440,17 +462,17 @@ longer than timeout seconds for the events to be delivered."
440 '(created changed created changed deleted stopped)) 462 '(created changed created changed deleted stopped))
441 (t '(created changed created changed 463 (t '(created changed created changed
442 deleted deleted deleted stopped))) 464 deleted deleted deleted stopped)))
443 (read-event nil nil 0.1) 465 (read-event nil nil file-notify--test-read-event-timeout)
444 (write-region 466 (write-region
445 "any text" nil file-notify--test-tmpfile nil 'no-message) 467 "any text" nil file-notify--test-tmpfile nil 'no-message)
446 (read-event nil nil 0.1) 468 (read-event nil nil file-notify--test-read-event-timeout)
447 (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1) 469 (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
448 ;; The next two events shall not be visible. 470 ;; The next two events shall not be visible.
449 (read-event nil nil 0.1) 471 (read-event nil nil file-notify--test-read-event-timeout)
450 (set-file-modes file-notify--test-tmpfile 000) 472 (set-file-modes file-notify--test-tmpfile 000)
451 (read-event nil nil 0.1) 473 (read-event nil nil file-notify--test-read-event-timeout)
452 (set-file-times file-notify--test-tmpfile '(0 0)) 474 (set-file-times file-notify--test-tmpfile '(0 0))
453 (read-event nil nil 0.1) 475 (read-event nil nil file-notify--test-read-event-timeout)
454 (delete-directory temporary-file-directory 'recursive)) 476 (delete-directory temporary-file-directory 'recursive))
455 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 477 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
456 (let (file-notify--test-events) 478 (let (file-notify--test-events)
@@ -480,13 +502,13 @@ longer than timeout seconds for the events to be delivered."
480 ((string-equal (file-notify--test-library) "kqueue") 502 ((string-equal (file-notify--test-library) "kqueue")
481 '(created changed renamed deleted stopped)) 503 '(created changed renamed deleted stopped))
482 (t '(created changed renamed deleted deleted stopped))) 504 (t '(created changed renamed deleted deleted stopped)))
483 (read-event nil nil 0.1) 505 (read-event nil nil file-notify--test-read-event-timeout)
484 (write-region 506 (write-region
485 "any text" nil file-notify--test-tmpfile nil 'no-message) 507 "any text" nil file-notify--test-tmpfile nil 'no-message)
486 (read-event nil nil 0.1) 508 (read-event nil nil file-notify--test-read-event-timeout)
487 (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1) 509 (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
488 ;; After the rename, we won't get events anymore. 510 ;; After the rename, we won't get events anymore.
489 (read-event nil nil 0.1) 511 (read-event nil nil file-notify--test-read-event-timeout)
490 (delete-directory temporary-file-directory 'recursive)) 512 (delete-directory temporary-file-directory 'recursive))
491 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 513 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
492 (let (file-notify--test-events) 514 (let (file-notify--test-events)
@@ -514,14 +536,14 @@ longer than timeout seconds for the events to be delivered."
514 (file-remote-p temporary-file-directory)) 536 (file-remote-p temporary-file-directory))
515 '(attribute-changed attribute-changed attribute-changed)) 537 '(attribute-changed attribute-changed attribute-changed))
516 (t '(attribute-changed attribute-changed))) 538 (t '(attribute-changed attribute-changed)))
517 (read-event nil nil 0.1) 539 (read-event nil nil file-notify--test-read-event-timeout)
518 (write-region 540 (write-region
519 "any text" nil file-notify--test-tmpfile nil 'no-message) 541 "any text" nil file-notify--test-tmpfile nil 'no-message)
520 (read-event nil nil 0.1) 542 (read-event nil nil file-notify--test-read-event-timeout)
521 (set-file-modes file-notify--test-tmpfile 000) 543 (set-file-modes file-notify--test-tmpfile 000)
522 (read-event nil nil 0.1) 544 (read-event nil nil file-notify--test-read-event-timeout)
523 (set-file-times file-notify--test-tmpfile '(0 0)) 545 (set-file-times file-notify--test-tmpfile '(0 0))
524 (read-event nil nil 0.1) 546 (read-event nil nil file-notify--test-read-event-timeout)
525 (delete-file file-notify--test-tmpfile)) 547 (delete-file file-notify--test-tmpfile))
526 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 548 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
527 (let (file-notify--test-events) 549 (let (file-notify--test-events)
@@ -678,10 +700,10 @@ longer than timeout seconds for the events to be delivered."
678 (changed changed deleted stopped))) 700 (changed changed deleted stopped)))
679 (t '(changed changed deleted stopped))) 701 (t '(changed changed deleted stopped)))
680 (should (file-notify-valid-p file-notify--test-desc)) 702 (should (file-notify-valid-p file-notify--test-desc))
681 (read-event nil nil 0.1) 703 (read-event nil nil file-notify--test-read-event-timeout)
682 (write-region 704 (write-region
683 "another text" nil file-notify--test-tmpfile nil 'no-message) 705 "another text" nil file-notify--test-tmpfile nil 'no-message)
684 (read-event nil nil 0.1) 706 (read-event nil nil file-notify--test-read-event-timeout)
685 (delete-file file-notify--test-tmpfile)) 707 (delete-file file-notify--test-tmpfile))
686 ;; After deleting the file, the descriptor is not valid anymore. 708 ;; After deleting the file, the descriptor is not valid anymore.
687 (should-not (file-notify-valid-p file-notify--test-desc)) 709 (should-not (file-notify-valid-p file-notify--test-desc))
@@ -713,10 +735,10 @@ longer than timeout seconds for the events to be delivered."
713 '(created changed deleted stopped)) 735 '(created changed deleted stopped))
714 (t '(created changed deleted deleted stopped))) 736 (t '(created changed deleted deleted stopped)))
715 (should (file-notify-valid-p file-notify--test-desc)) 737 (should (file-notify-valid-p file-notify--test-desc))
716 (read-event nil nil 0.1) 738 (read-event nil nil file-notify--test-read-event-timeout)
717 (write-region 739 (write-region
718 "any text" nil file-notify--test-tmpfile nil 'no-message) 740 "any text" nil file-notify--test-tmpfile nil 'no-message)
719 (read-event nil nil 0.1) 741 (read-event nil nil file-notify--test-read-event-timeout)
720 (delete-directory temporary-file-directory t)) 742 (delete-directory temporary-file-directory t))
721 ;; After deleting the parent directory, the descriptor must 743 ;; After deleting the parent directory, the descriptor must
722 ;; not be valid anymore. 744 ;; not be valid anymore.
@@ -814,9 +836,9 @@ longer than timeout seconds for the events to be delivered."
814 (let ((source-file-list source-file-list) 836 (let ((source-file-list source-file-list)
815 (target-file-list target-file-list)) 837 (target-file-list target-file-list))
816 (while (and source-file-list target-file-list) 838 (while (and source-file-list target-file-list)
817 (read-event nil nil 0.1) 839 (read-event nil nil file-notify--test-read-event-timeout)
818 (write-region "" nil (pop source-file-list) nil 'no-message) 840 (write-region "" nil (pop source-file-list) nil 'no-message)
819 (read-event nil nil 0.1) 841 (read-event nil nil file-notify--test-read-event-timeout)
820 (write-region "" nil (pop target-file-list) nil 'no-message)))) 842 (write-region "" nil (pop target-file-list) nil 'no-message))))
821 (file-notify--test-with-events 843 (file-notify--test-with-events
822 (cond 844 (cond
@@ -829,16 +851,93 @@ longer than timeout seconds for the events to be delivered."
829 (let ((source-file-list source-file-list) 851 (let ((source-file-list source-file-list)
830 (target-file-list target-file-list)) 852 (target-file-list target-file-list))
831 (while (and source-file-list target-file-list) 853 (while (and source-file-list target-file-list)
832 (rename-file (pop source-file-list) (pop target-file-list) t) 854 (read-event nil nil file-notify--test-read-event-timeout)
833 (read-event nil nil 0.02)))) 855 (rename-file (pop source-file-list) (pop target-file-list) t))))
834 (file-notify--test-with-events (make-list n 'deleted) 856 (file-notify--test-with-events (make-list n 'deleted)
835 (dolist (file target-file-list) 857 (dolist (file target-file-list)
836 (prog1 (delete-file file) (read-event nil nil 0.02))))) 858 (read-event nil nil file-notify--test-read-event-timeout)
859 (delete-file file) file-notify--test-read-event-timeout)))
860
861 ;; Cleanup.
837 (file-notify--test-cleanup))) 862 (file-notify--test-cleanup)))
838 863
839(file-notify--deftest-remote file-notify-test06-many-events 864(file-notify--deftest-remote file-notify-test06-many-events
840 "Check that events are not dropped for remote directories.") 865 "Check that events are not dropped for remote directories.")
841 866
867(ert-deftest file-notify-test07-backup ()
868 "Check that backup keeps file notification."
869 (skip-unless (file-notify--test-local-enabled))
870
871 (unwind-protect
872 (progn
873 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
874 (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
875 (should
876 (setq file-notify--test-desc
877 (file-notify-add-watch
878 file-notify--test-tmpfile
879 '(change) #'file-notify--test-event-handler)))
880 (should (file-notify-valid-p file-notify--test-desc))
881 (file-notify--test-with-events
882 (cond
883 ;; For w32notify and in the remote case, there are two
884 ;; `changed' events.
885 ((or (string-equal (file-notify--test-library) "w32notify")
886 (file-remote-p temporary-file-directory))
887 '(changed changed))
888 (t '(changed)))
889 ;; There shouldn't be any problem, because the file is kept.
890 (with-temp-buffer
891 (let ((buffer-file-name file-notify--test-tmpfile)
892 (make-backup-files t)
893 (backup-by-copying t)
894 (kept-new-versions 1)
895 (delete-old-versions t))
896 (insert "another text")
897 (save-buffer))))
898 ;; After saving the buffer, the descriptor is still valid.
899 (should (file-notify-valid-p file-notify--test-desc))
900 (delete-file file-notify--test-tmpfile))
901
902 ;; Cleanup.
903 (file-notify--test-cleanup))
904
905 (unwind-protect
906 (progn
907 ;; It doesn't work for kqueue, because we don't use an
908 ;; implicit directory monitor.
909 (unless (string-equal (file-notify--test-library) "kqueue")
910 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
911 (write-region
912 "any text" nil file-notify--test-tmpfile nil 'no-message)
913 (should
914 (setq file-notify--test-desc
915 (file-notify-add-watch
916 file-notify--test-tmpfile
917 '(change) #'file-notify--test-event-handler)))
918 (should (file-notify-valid-p file-notify--test-desc))
919 (file-notify--test-with-events '(renamed created changed)
920 ;; The file is renamed when creating a backup. It shall
921 ;; still be watched.
922 (with-temp-buffer
923 (let ((buffer-file-name file-notify--test-tmpfile)
924 (make-backup-files t)
925 (backup-by-copying nil)
926 (backup-by-copying-when-mismatch nil)
927 (kept-new-versions 1)
928 (delete-old-versions t))
929 (insert "another text")
930 (save-buffer))))
931 ;; After saving the buffer, the descriptor is still valid.
932 (should (file-notify-valid-p file-notify--test-desc))
933 (delete-file file-notify--test-tmpfile)))
934
935 ;; Cleanup.
936 (file-notify--test-cleanup)))
937
938(file-notify--deftest-remote file-notify-test07-backup
939 "Check that backup keeps file notification for remote files.")
940
842(defun file-notify-test-all (&optional interactive) 941(defun file-notify-test-all (&optional interactive)
843 "Run all tests for \\[file-notify]." 942 "Run all tests for \\[file-notify]."
844 (interactive "p") 943 (interactive "p")