Subject: bug#33791: 26.1; Eshell on Windows connecting to GNU/Linux machine using TRAMP and plink: env: ‘c:/home/jordan/test.sh’: No such file or directory

From: Eli Zaretskii <[email-masked]>
Date: Sun, 23 Dec 2018 17:58:36 +0200

> From: Jordan Wilson <[email-masked]>
> Cc: [email-masked], [email-masked]
> Date: Sun, 23 Dec 2018 12:40:14 +0000
> 
> Hmm...seems the bug I'm experiencing is more low-lying than eshell. I've
> followed it down to C-level. eshell/cd -> cd -> locate-file ->
> locate-file-internal. In my case both problems arise from "c:"
> being prepended somewhere.
> 
> Evaluating:
> 
>      (locate-file-internal ".." '("./") nil (lambda (f) (message f)))
> 
> while in "/plink:[email-masked]:/home/jordan/test" returns
> "c:/plink:[email-masked]:/home/jordan". Whilst
> 
>      (locate-file-internal ".."
>             '("/plink:[email-masked]:/home/jordan/test")
>              nil (lambda (f) (message f)))
> 
> correctly returns "/plink:[email-masked]:/home/jordan".
> 
> It seems the problem is something to do with converting from a
> relative to absolute path. Eval'ing (expand-file-name "..") correctly
> returns "/plink:[email-masked]:/home/jordan", though. Strange.

Right you are, thanks.  The problem is that locate-file doesn't
support remote file names.  Does the patch below produce good results?

Michael, do you agree with this solution?  Do you think it's safe
enough to put it on the release branch (it's a regression from a few
years ago)?

diff --git a/lisp/files.el b/lisp/files.el
index eb09a7c..cfe67b4 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -801,9 +801,15 @@ cd
     (setq cd-path (or (parse-colon-path (getenv "CDPATH"))
                       (list "./"))))
   (cd-absolute
-   (or (locate-file dir cd-path nil
-                    (lambda (f) (and (file-directory-p f) 'dir-ok)))
-       (error "No such directory found via CDPATH environment variable"))))
+   (or
+    ;; locate-file doesn't support remote file names, so detect them
+    ;; and support them here by hand.
+    (and (file-name-absolute-p (expand-file-name dir))
+         (file-accessible-directory-p (expand-file-name dir))
+         (expand-file-name dir))
+    (locate-file dir cd-path nil
+                 (lambda (f) (and (file-directory-p f) 'dir-ok)))
+    (error "No such directory found via CDPATH environment variable"))))
 
 (defun directory-files-recursively (dir regexp &optional include-directories)
   "Return list of all files under DIR that have file names matching REGEXP.