branch: elpa/elfeed
commit 41ee64bd46821b0093c413c45b8cb73e44708234
Author: Steven Allen <[email protected]>
Commit: Daniel Mendler <[email protected]>

    elfeed-db-save: write index atomically
    
    Write the elfeed index atomically to avoid corruption. See #95, #80,
    etc.
---
 elfeed-db.el | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/elfeed-db.el b/elfeed-db.el
index 83ccaa2eaa..449c2054a3 100644
--- a/elfeed-db.el
+++ b/elfeed-db.el
@@ -269,8 +269,14 @@ The FEED-OR-ID may be a feed struct or a feed ID (url)."
   (elfeed-db-ensure)
   (setf elfeed-db (plist-put elfeed-db :version elfeed-db-version))
   (mkdir elfeed-db-directory t)
-  (let ((coding-system-for-write 'utf-8))
-    (with-temp-file (expand-file-name "index" elfeed-db-directory)
+  (let* ((coding-system-for-write 'utf-8)
+         (dest (expand-file-name "index" elfeed-db-directory))
+         (temp (concat dest "-tmp"))
+         (write-region-inhibit-fsync nil))
+    ;; We write to a temporary file and rename to avoid corrupting the database
+    ;; on crash. `file-precious-flag' is insufficient as it only works for
+    ;; `save-buffer'.
+    (with-temp-file temp
       (let ((standard-output (current-buffer))
             (print-level nil)
             (print-length nil)
@@ -282,8 +288,9 @@ The FEED-OR-ID may be a feed struct or a feed ID (url)."
           (princ ";; Dummy index for backwards compatablity:\n")
           (prin1 (elfeed-db--dummy))
           (princ "\n\n;; Real index:\n"))
-        (prin1 elfeed-db)
-        :success))))
+        (prin1 elfeed-db)))
+    (rename-file temp dest t)
+    :success))
 
 (defun elfeed-db-save-safe ()
   "Run `elfeed-db-save' without triggering any errors, for use as a safe hook."

Reply via email to