From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Jim Meyering Newsgroups: gmane.emacs.devel Subject: enabling atomic-update more often, i.e., rewrite via rename Date: Fri, 09 Dec 2011 11:26:38 +0100 Message-ID: <87zkf282ht.fsf@rho.meyering.net> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1323426416 7898 80.91.229.12 (9 Dec 2011 10:26:56 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 9 Dec 2011 10:26:56 +0000 (UTC) To: Emacs development discussions Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Dec 09 11:26:51 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RYxfG-0000u9-Io for ged-emacs-devel@m.gmane.org; Fri, 09 Dec 2011 11:26:50 +0100 Original-Received: from localhost ([::1]:38296 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RYxfG-0006QM-2u for ged-emacs-devel@m.gmane.org; Fri, 09 Dec 2011 05:26:50 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:48322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RYxf8-0006Q1-M9 for emacs-devel@gnu.org; Fri, 09 Dec 2011 05:26:47 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RYxf7-0004MX-6j for emacs-devel@gnu.org; Fri, 09 Dec 2011 05:26:42 -0500 Original-Received: from mx.meyering.net ([88.168.87.75]:33925) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RYxf6-0004MG-Uz for emacs-devel@gnu.org; Fri, 09 Dec 2011 05:26:41 -0500 Original-Received: from rho.meyering.net (localhost.localdomain [127.0.0.1]) by rho.meyering.net (Acme Bit-Twister) with ESMTP id E9B18605CE for ; Fri, 9 Dec 2011 11:26:38 +0100 (CET) Original-Lines: 46 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 88.168.87.75 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:146597 Archived-At: 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?