From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#46397: 27.1; Cannot delete buffer pointing to a file in a path that includes a file Date: Wed, 10 Feb 2021 11:23:46 -0800 Organization: UCLA Computer Science Department Message-ID: <39d0e035-27b6-e2bd-daa2-747dda2c1a35@cs.ucla.edu> References: <87h7mllgin.fsf@nexoid.at> <83a6scj745.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------A3DE93C10AF52A2D753617B8" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="18118"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.1 Cc: Matt Armstrong , 46397@debbugs.gnu.org, craven@gmx.net To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Feb 10 20:24:36 2021 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 1l9v6K-0004bB-JT for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 10 Feb 2021 20:24:36 +0100 Original-Received: from localhost ([::1]:49458 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l9v6J-0001Fs-LQ for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 10 Feb 2021 14:24:35 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:51754) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l9v5n-0001EQ-PO for bug-gnu-emacs@gnu.org; Wed, 10 Feb 2021 14:24:10 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:45704) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l9v5m-0003bH-Fl for bug-gnu-emacs@gnu.org; Wed, 10 Feb 2021 14:24:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1l9v5m-0004fJ-CN for bug-gnu-emacs@gnu.org; Wed, 10 Feb 2021 14:24:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 10 Feb 2021 19:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 46397 X-GNU-PR-Package: emacs Original-Received: via spool by 46397-submit@debbugs.gnu.org id=B46397.161298503617921 (code B ref 46397); Wed, 10 Feb 2021 19:24:02 +0000 Original-Received: (at 46397) by debbugs.gnu.org; 10 Feb 2021 19:23:56 +0000 Original-Received: from localhost ([127.0.0.1]:57250 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l9v5f-0004ey-NE for submit@debbugs.gnu.org; Wed, 10 Feb 2021 14:23:56 -0500 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:33630) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l9v5d-0004el-S9 for 46397@debbugs.gnu.org; Wed, 10 Feb 2021 14:23:54 -0500 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 65DFD16005D; Wed, 10 Feb 2021 11:23:48 -0800 (PST) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id pj-rbGkhHWqL; Wed, 10 Feb 2021 11:23:47 -0800 (PST) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 37710160087; Wed, 10 Feb 2021 11:23:47 -0800 (PST) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 0d17747Onp4k; Wed, 10 Feb 2021 11:23:47 -0800 (PST) Original-Received: from [192.168.1.9] (cpe-23-243-218-95.socal.res.rr.com [23.243.218.95]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id C685816005D; Wed, 10 Feb 2021 11:23:46 -0800 (PST) In-Reply-To: <83a6scj745.fsf@gnu.org> Content-Language: en-US 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" Xref: news.gmane.io gmane.emacs.bugs:199794 Archived-At: This is a multi-part message in MIME format. --------------A3DE93C10AF52A2D753617B8 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On 2/10/21 7:05 AM, Eli Zaretskii wrote: > I think instead of ignoring some errors, we should allow the user to > get out of these situations, after showing the error. That is, > instead of silently ignoring the error on some low level, we should > propagate it to userlock.el and allow the user to decide whether > he/she wants to ignore the error or do something about that. These > errors could mean something innocent, or they could mean something > more serious, and we shouldn't second-guess which one is it. I agree with this. However, I think there are two bugs here. The first bug is that the low-level locking code is busted, in that it=20 thinks there's a lock file when ENOTDIR says there isn't. I installed=20 the first attached patch into master to fix this bug. This patch isn't=20 what Matt suggested - it's a bit earlier in the low-level C code where=20 the bug really occurred. (The area that Matt was looking at was later=20 on, when we have the lock and are removing it, and the ENOENT check=20 there is for the rare case where NFS is being used and its unlink=20 implementation gets confused and fails with ENOENT even though it was=20 actually successful and where any error other than ENOENT is serious.) The second bug is that once you're in a tricky situation where the file=20 can't be unlocked for whatever reason and you attempt to exit Emacs,=20 Emacs tries to auto-save the buffer, fails because of the lock problem,=20 and then gets into a weird state where you cannot do anything. This=20 problem can happen in other scenarios. For example: * Run Emacs and visit the file /tmp/a/b where /tmp/a does not exist.=20 Emacs will warn "Use M-x make-directory RET RET to create the directory=20 and its parents"; ignore the warning. * Type some characters so that /tmp/a/b's buffer is nonempty. * Create an inaccessible directory /tmp/a by running "mkdir -m 0 /tmp/a"=20 outside Emacs. * Type C-x C-c to exit Emacs. It will say "Save file /tmp/a/b?" Type=20 "n". It will then say "Modified buffers exist; exit anyway? (yes or=20 no)". Type "yes". Emacs will then hang, in a weird state where it is=20 trying to auto-save but hanging in the middle of that. I did not fix this latter problem, so it needs further investigation.=20 While looking into it, though, I did see some longstanding code in=20 files.el that could use a bit of sprucing up given the more-modern=20 primitives available now, and so installed the second attached patch=20 into master. --------------A3DE93C10AF52A2D753617B8 Content-Type: text/x-patch; charset=UTF-8; name="0001-Fix-file-lock-issue-Bug-46397.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Fix-file-lock-issue-Bug-46397.patch" =46rom 4459dcc07865f6ae1f21f624fcb09cf8fdaecdb5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 10 Feb 2021 10:50:44 -0800 Subject: [PATCH 1/2] Fix file lock issue (Bug#46397) * src/filelock.c (current_lock_owner): Also treat ENOTDIR as meaning the lock file does not exist. --- src/filelock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filelock.c b/src/filelock.c index 35baa0c666..373fc00a42 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -532,7 +532,7 @@ current_lock_owner (lock_info_type *owner, char *lfna= me) /* If nonexistent lock file, all is well; otherwise, got strange error= =2E */ lfinfolen =3D read_lock_data (lfname, owner->user); if (lfinfolen < 0) - return errno =3D=3D ENOENT ? 0 : errno; + return errno =3D=3D ENOENT || errno =3D=3D ENOTDIR ? 0 : errno; if (MAX_LFINFO < lfinfolen) return ENAMETOOLONG; owner->user[lfinfolen] =3D 0; --=20 2.27.0 --------------A3DE93C10AF52A2D753617B8 Content-Type: text/x-patch; charset=UTF-8; name="0002-Simplify-and-speed-up-after-find-file.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0002-Simplify-and-speed-up-after-find-file.patch" =46rom 4467073c50d2c7fbbb30530d1a0a25f8272ff56f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 10 Feb 2021 10:55:42 -0800 Subject: [PATCH 2/2] Simplify and speed up after-find-file Use newer primitives like file-accessible-directory-p to simplify and speed up longstanding code in after-find-file. * lisp/files.el (after-find-file): Prefer file-exists-p + file-symlink-p to file-attributes + file-symlink-p + file-chase-links + file-exists-p. Prefer file-accessible-directory-p to directory-file-name + file-attributes. Prefer file-directory-p to file-name-directory + file-exists-p. --- lisp/files.el | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index dada69c145..9ff8f31e37 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2530,13 +2530,11 @@ after-find-file (msg (cond ((not warn) nil) - ((and error (file-attributes buffer-file-name)) + ((and error (file-exists-p buffer-file-name)) (setq buffer-read-only t) - (if (and (file-symlink-p buffer-file-name) - (not (file-exists-p - (file-chase-links buffer-file-name)))) - "Symbolic link that points to nonexistent file" - "File exists, but cannot be read")) + "File exists, but cannot be read") + ((and error (file-symlink-p buffer-file-name)) + "Symbolic link that points to nonexistent file") ((not buffer-read-only) (if (and warn ;; No need to warn if buffer is auto-saved @@ -2553,13 +2551,12 @@ after-find-file ((not error) (setq not-serious t) "Note: file is write protected") - ((file-attributes (directory-file-name default-directory)) + ((file-accessible-directory-p default-directory) "File not found and directory write-protected") - ((file-exists-p (file-name-directory buffer-file-name)) - (setq buffer-read-only nil)) (t (setq buffer-read-only nil) - "Use M-x make-directory RET RET to create the directory and its p= arents")))) + (unless (file-directory-p default-directory) + "Use M-x make-directory RET RET to create the directory and its parent= s"))))) (when msg (message "%s" msg) (or not-serious (sit-for 1 t)))) --=20 2.27.0 --------------A3DE93C10AF52A2D753617B8--