From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Jens Schmidt via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#66546: 30.0.50; save-buffer to write-protected file without backup fails Date: Sat, 14 Oct 2023 21:09:53 +0200 Message-ID: Reply-To: Jens Schmidt Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="17917"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla Thunderbird Cc: eli zaretskii To: 66546@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Oct 14 21:10:51 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qrk2E-0004UB-Rn for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 14 Oct 2023 21:10:50 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qrk25-00031N-1o; Sat, 14 Oct 2023 15:10:42 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qrk22-00030s-On for bug-gnu-emacs@gnu.org; Sat, 14 Oct 2023 15:10:38 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qrk22-0004oL-Gc; Sat, 14 Oct 2023 15:10:38 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qrk2P-0006st-UA; Sat, 14 Oct 2023 15:11:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Jens Schmidt Original-Sender: "Debbugs-submit" Resent-CC: eliz@gnu.org, bug-gnu-emacs@gnu.org Resent-Date: Sat, 14 Oct 2023 19:11:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 66546 X-GNU-PR-Package: emacs X-Debbugs-Original-To: bug-gnu-emacs@gnu.org X-Debbugs-Original-Xcc: eli zaretskii Original-Received: via spool by submit@debbugs.gnu.org id=B.169731065126444 (code B ref -1); Sat, 14 Oct 2023 19:11:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 14 Oct 2023 19:10:51 +0000 Original-Received: from localhost ([127.0.0.1]:50532 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qrk2F-0006sS-58 for submit@debbugs.gnu.org; Sat, 14 Oct 2023 15:10:51 -0400 Original-Received: from lists.gnu.org ([2001:470:142::17]:43870) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qrk2A-0006s9-Tr for submit@debbugs.gnu.org; Sat, 14 Oct 2023 15:10:49 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qrk1g-0002zD-Sy for bug-gnu-emacs@gnu.org; Sat, 14 Oct 2023 15:10:16 -0400 Original-Received: from mr6.vodafonemail.de ([145.253.228.166]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qrk1a-0004kq-SE for bug-gnu-emacs@gnu.org; Sat, 14 Oct 2023 15:10:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vodafonemail.de; s=vfde-mb-mr2-21dec; t=1697310608; bh=+2xPoQRsCG2c1icedDVD/vVGhvmDN6Hjyd+RtD5QFFo=; h=Message-ID:Date:User-Agent:From:Content-Language:To:Subject: Content-Type:From; b=foJDSPcju20g/6wE2Z2WLYZVjIfezeXI/HXFUlY5tyRn/gx771o1/baxfL+TcVjqi 4dko5Jn4lQTb7QBn1vYxGXxmKFrtTa8r5RoFo1L3fHmKzuhgrbcQtgBInPyhE+1pHy vCpMUnAIHXyg8cumPUXEKRs3HS/AaLBq0s+nuj7o= Original-Received: from smtp.vodafone.de (unknown [10.0.0.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by mr6.vodafonemail.de (Postfix) with ESMTPS id 4S7Ccc09gyz1xyd for ; Sat, 14 Oct 2023 19:10:08 +0000 (UTC) Original-Received: from [192.168.178.41] (port-92-194-107-54.dynamic.as20676.net [92.194.107.54]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp.vodafone.de (Postfix) with ESMTPSA id 4S7CcW5Ppnz9s6J for ; Sat, 14 Oct 2023 19:10:00 +0000 (UTC) Content-Language: de-DE-frami, en-US X-purgate-type: clean X-purgate: clean X-purgate-size: 5010 X-purgate-ID: 155817::1697310603-78FF4E22-97FFAD0C/0/0 Received-SPF: pass client-ip=145.253.228.166; envelope-from=jschmidt4gnu@vodafonemail.de; helo=mr6.vodafonemail.de X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:272461 Archived-At: X-Debbugs-Cc: Eli Zaretskii Severity: minor Eli, sorry to disturb you with another edge-case bug, but the commit that has introduced it was yours, I think ... *** Issue A In a shell execute: echo foo > foo chmod 0400 foo ./src/emacs -Q foo C-x C-q bar C-0 C-x C-s => File foo is write-protected; try to save anyway? yes RET => basic-save-buffer-2: Opening output file: Permission denied, /home/jschmidt/work/emacs-master/foo When saving *with* backup, that is, without prefix C-0, everything works as expected: The file temporarily gets write permissions, gets written to, and write permissions get removed again. The root cause is related to Eli's introduction of calls to `set-file-extended-attributes' in ccad023bc3c7. Here: ------------------------- files.el ------------------------- ;; If file not writable, see if we can make it writable ;; temporarily while we write it. ;; But no need to do so if we have just backed it up ;; (setmodes is set) because that says we're superseding. (cond ((and tempsetmodes (not setmodes)) ;; Change the mode back, after writing. (setq setmodes (list (file-modes buffer-file-name) (with-demoted-errors "Error getting extended attributes: %s" (file-extended-attributes buffer-file-name)) buffer-file-name)) ;; If set-file-extended-attributes fails, fall back on ;; set-file-modes. (unless (with-demoted-errors "Error setting attributes: %s" (set-file-extended-attributes buffer-file-name (nth 1 setmodes))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1] (set-file-modes buffer-file-name (logior (car setmodes) 128))))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2] ------------------------- files.el ------------------------- The marked call [1] is a no-op, since it does not change the permissions in any way when writing them back, while the call [2] to `set-file-modes' actually changes the file mode. Since an extended file attribute Elisp object cannot be modified yet (is that so?) to mark it, for example, as writable, I propose to just drop that call to `set-file-extended-attributes', like this: ------------------------- snip ------------------------- diff --git a/lisp/files.el b/lisp/files.el index e1421b403bf..d4d556fa470 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5944,14 +5944,8 @@ basic-save-buffer-2 "Error getting extended attributes: %s" (file-extended-attributes buffer-file-name)) buffer-file-name)) - ;; If set-file-extended-attributes fails, fall back on - ;; set-file-modes. - (unless - (with-demoted-errors "Error setting attributes: %s" - (set-file-extended-attributes buffer-file-name - (nth 1 setmodes))) - (set-file-modes buffer-file-name - (logior (car setmodes) 128))))) + (set-file-modes buffer-file-name + (logior (car setmodes) 128)))) (let (success) (unwind-protect (progn ------------------------- snip ------------------------- *** Issue B But then there is another issue (?), probably even longer unnoticed. To notice it, apply above patch, make, then execute the following test case: rm -f foo echo foo > foo chmod 0400 foo ./src/emacs -Q Define the following advice on `write-region' to simulate a write error: ------------------------- snip ------------------------- (advice-add 'write-region :override (lambda (&rest _) (error "No space left on device"))) ------------------------- snip ------------------------- Then continue C-x C-f foo RET C-x C-q bar C-0 C-x C-s => File foo is write-protected; try to save anyway? yes RET => No space left on device Now check the permissions of file foo: [emacs-master]$ ls -al foo -rw------- 1 jschmidt jschmidt 7 Oct 14 20:33 foo So the write permissions did not get removed again. Here the root cause is that the `unwind-protect' around the `write-region' in `basic-save-buffer-2' does not handle the no-backup case separately. I would extend the clean-up form of the `unwind-protect' to distinguish these both cases and handle the no-backup case appropriately, here by trying first to set back the extended attributes, then the regular ones. *** What to do and where? I can provide patches for both issues. Plus ERT tests. I guess that would be in one changeset, since these are related. Should I provide a separate patch fixing only issue A for emacs-29? Or is that issue not relevant for emacs-29, given that it went unnoticed for 12 years?