[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

enabling atomic-update more often, i.e., rewrite via rename

From: Jim Meyering
Subject: enabling atomic-update more often, i.e., rewrite via rename
Date: Fri, 09 Dec 2011 11:26:38 +0100

TL;DR, for a regular file with no other hard links in a writable directory,
why is the default to rewrite in place (non-atomically), rather than to write
to temporary-in-same-dir and then to rename, thus updating atomically?

A few days ago I was editing my .procmailrc file with emacs, made a
small change and saved it.  I was dismayed to see that change provoke a
flurry of syntax errors from procmail as two or three incoming messages
made it parse the partially-rewritten .procmailrc file.  Emacs was rewriting
that file in place, and procmail was reading it at the same time.

This made me think there must be a way to configure emacs so that when
it writes a file, it updates that file atomically.

Sure enough, there is: the buffer-local file-precious-flag.
I've added these two lines to the top of .procmailrc, and
confirmed via strace that emacs now does indeed update via rename:

  # -*- file-precious-flag: t -*-
  # The above tells emacs to save by write-then-rename, i.e., atomically.

That solved my immediate problem, but why isn't this the default, I wondered?
Reading files.el, it seems that one reason is to avoid breaking hard links.
If you set break-hardlink-on-save to `t' and the file happens to have
two or more links, then it does happen by default.

Here's the relevant code from files.el:

    (let* ((dir (file-name-directory buffer-file-name))
           (dir-writable (file-writable-p dir)))
      (if (or (and file-precious-flag dir-writable)
              (and break-hardlink-on-save
                   (file-exists-p buffer-file-name)
                   (> (file-nlinks buffer-file-name) 1)
                   (or dir-writable
                       (error (concat (format
                                       "Directory %s write-protected; " dir)
                                      "cannot break hardlink when saving")))))
          ;; Write temp name, then rename it.
          ;; This requires write access to the containing dir,
          ;; which is why we don't try it if we don't have that access.

But my .procmailrc has only one link and is in a writable directory,
so an atomic update would not cause any harm.

Has anyone considered making update-via-rename the default in that case?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]