From 7f3d63908cd05fb34347d942e435c2964cd8b249 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 6 May 2017 17:58:20 -0700 Subject: [PATCH] Write autoloads file atomically * lisp/emacs-lisp/autoload.el (autoload--save-buffer): New function, to save buffer atomically. (autoload-save-buffers, update-directory-autoloads): Use autoload--save-buffer. * lisp/Makefile.in ($(lisp)/loaddefs.el): No longer write to a temp file by hand. --- lisp/Makefile.in | 13 +------------ lisp/emacs-lisp/autoload.el | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lisp/Makefile.in b/lisp/Makefile.in index cbbea78a00f..1da8814370a 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -203,28 +203,17 @@ $(lisp)/finder-inf.el: # batch-update-autoloads, which only updates the autoloads whose # sources have changed. -# Write to a temporary file in case we're doing a parallel build and a -# CANNOT_DUMP-mode Emacs needs to read loaddefs at startup. -# (FIXME: This seems like something that batch-update-autoloads should -# do internally, then it would Just Work for all loaddefs files.) -# We start by copying an existing loaddefs.el to loaddefs.tmp to avoid -# regenerating the entire file anew, which is slow; starting from an -# almost-correct content will enable the "only update where necessary" -# feature of batch-update-autoloads. - # Use expand-file-name rather than $abs_scrdir so that Emacs does not # get confused when it compares file-names for equality. autoloads .PHONY: $(lisp)/loaddefs.el $(lisp)/loaddefs.el: gen-lisp $(LOADDEFS) @echo Directories for loaddefs: ${SUBDIRS_ALMOST} - @if test -f $@ ; then cp $@ $(lisp)/loaddefs.tmp ; fi $(AM_V_GEN)$(emacs) -l autoload \ --eval '(setq autoload-ensure-writable t)' \ --eval '(setq autoload-builtin-package-versions t)' \ - --eval '(setq generated-autoload-file (expand-file-name (unmsys--file-name "$(lisp)/loaddefs.tmp")))' \ + --eval '(setq generated-autoload-file (expand-file-name (unmsys--file-name "$@")))' \ -f batch-update-autoloads ${SUBDIRS_ALMOST} - $(top_srcdir)/build-aux/move-if-change $(lisp)/loaddefs.tmp $@ # autoloads only runs when loaddefs.el is nonexistent, although it # generates a number of different files. Provide a force option to enable diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index 9865b3198b2..8ad5e6b823d 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -866,11 +866,26 @@ FILE's modification time." (error "%s:0:0: error: %s: %s" file (car err) (cdr err))) )) +;; For parallel builds, to stop another process reading a half-written file. +(defun autoload--save-buffer () + "Save current buffer to its file, atomically." + ;; Copied from byte-compile-file. + (let* ((version-control 'never) + (tempfile (make-temp-name buffer-file-name)) + (kill-emacs-hook + (cons (lambda () (ignore-errors (delete-file tempfile))) + kill-emacs-hook))) + (write-region (point-min) (point-max) tempfile nil 1) + (backup-buffer) + (rename-file tempfile buffer-file-name t) + (set-buffer-modified-p nil) + (set-visited-file-modtime) + (or noninteractive (message "Wrote %s" buffer-file-name)))) + (defun autoload-save-buffers () (while autoload-modified-buffers (with-current-buffer (pop autoload-modified-buffers) - (let ((version-control 'never)) - (save-buffer))))) + (autoload--save-buffer)))) ;; FIXME This command should be deprecated. ;; See http://debbugs.gnu.org/22213#41 @@ -1110,8 +1125,7 @@ write its autoloads into the specified file instead." ;; dependencies don't trigger unnecessarily. (if (not changed) (set-buffer-modified-p nil) - (let ((version-control 'never)) - (save-buffer))) + (autoload--save-buffer)) ;; In case autoload entries were added to other files because of ;; file-local autoload-generated-file settings. -- 2.39.2