From unknown Wed Jun 25 10:51:04 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#27871 <27871@debbugs.gnu.org> To: bug#27871 <27871@debbugs.gnu.org> Subject: Status: 26.0.50; Bad handling of unmounted directory Reply-To: bug#27871 <27871@debbugs.gnu.org> Date: Wed, 25 Jun 2025 17:51:04 +0000 retitle 27871 26.0.50; Bad handling of unmounted directory reassign 27871 emacs submitter 27871 Philipp
Create a FUSE mount point, e.g.
cd /tmp
mkdir a a/a b
touch a/a/a
bindfs -f a b
While bindfs(1) is running, cd to the mounted directory in a second
shell:
cd /tmp/b/a
Now kill bindfs, e.g. by hitting ^C in the first shell.=C2=A0 The second
shell will now be in an unmounted directory.=C2=A0 From that directory, sta= rt
Emacs:
$ emacs -Q -batch a
Apparent cycle of symbolic links for (unreachable)
or, with stack trace
$ emacs -Q -batch -f toggle-debug-on-error a
Debug on Error enabled globally
...
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a/(unreachable)" (-1) (nil))<= br> =C2=A0 file-truename("(unreachable)/a/(unreachable)/a" (-1) (nil)= )
=C2=A0 file-truename("(unreachable)/a/(unreachable)/a/(unreachable)&qu= ot; (-1) (nil))
=C2=A0 file-truename("(unreachable)/a/(unreachable)/a/(unreachable)/a&= quot; (-1) (nil))
=C2=A0 file-truename("(unreachable)/a/(unreachable)/a/(unreachable)/a/= (unreachable)" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a/(unreachable)/a/(unreachable)/a/= (unreachable)/a" (-1) (nil))
=C2=A0 file-truename("(unreachable)/a/(unreachable)/a/(unreachable)/a/= (unreachable)/a/a")
=C2=A0 find-file-noselect("(unreachable)/a/(unreachable)/a/a")
=C2=A0 #f(compiled-function (displayable-buffers dir line column name) #<= ;bytecode>)((nil) "(unreachable)/a/" (0) (0) "a")
=C2=A0 command-line-1(("-f" "toggle-debug-on-error" &qu= ot;a"))
=C2=A0 command-line()
=C2=A0 normal-top-level()
It seems like the logic for `default-directory' and/or `file-truename= 39;
should be improved for unmounted filesystems.
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: schwab@= linux-m68k.org, 27871@debbugs.gnu.org
>
> Then why not just check that the first character is something other
> than '/'?
Or, more general, that the result fails file_name_absolute_p (which
would be more portable)?
Philipp Stephani wrote:
> +=C2=A0 if (!file_name_absolute_p (dir))
That doesn't look right here, since leading '~' counts as absol= ute to
file_name_absolute_p, which is not what is wanted here.
> +=C2=A0 =C2=A0 =C2=A0 errno =3D ENOTCONN;
Why ENOTCONN? Shouldn't it be ENOENT? The failure has nothing to do wit= h socket
connections.
Also, I'd feel a bit better if we apply the workaround only to the func= tion that
has the problem.