Stacey Marshall <stacey.marsh...@gmail.com> writes: Hi Stacey,
Thanks for this exhaustive bug report, and the proper analysis. > 3. In another terminal session clear up caches, start emacs, and access > directory via tramp path > > rm -rf ~/.cache/emacs ~/.emacs.d/tramp > emacs -nw -Q --eval '(add-to-list `load-path "~/emacs/tramp/lisp/")' \ > --eval '(require `tramp)' --eval '(setq tramp-verbose 11)' \ > --eval '(find-file > "/scp:foobar@localhost:/export/home/foobar/tmp/is_it_the_length_of_path_and_not_the_d")' > > At this point, if necessary accept the connection and type password > as required... And then emacs appears hung. A C-g (Control-G) > aborts the transfer. Switching to the debug buffer > `(switch-to-buffer "*debug tramp/scp foobar@localhost*")` and > duplicating it (M-n) (before it gets contaminated/removed). > It shows some output, though this tends to differ slightly each time! Yep. According to the debug buffer you've sent, Tramp has sent the following command: --8<---------------cut here---------------start------------->8--- 16:34:47.760152 tramp-send-command (6) # (if test -h "/export/home/foobar/tmp/is_it_the_length_of_path_and_not_the_d/"; then echo t; else echo nil; fi) && /usr/bin/readlink --canonicalize-missing /export/home/foobar/tmp/is_it_the_length_of_path_and_not_the_d/ 2>/dev/null; echo tramp_exit_status $? --8<---------------cut here---------------end--------------->8--- The "(if test ... tramp_exit_status $?" sequence is 257 characters long, it seems to exceed the shell line length on Solaris. The problem is, that the looooongish file name is used twice. > diff --git a/lisp/tramp-sh.el b/lisp/tramp-sh.el > index 047d93a5..e0ccc0ce 100644 > --- a/lisp/tramp-sh.el > +++ b/lisp/tramp-sh.el > @@ -1292,20 +1292,12 @@ Operations not mentioned here will be handled by the > normal Emacs functions.") > ;; Use GNU readlink --canonicalize-missing where available. > ((tramp-get-remote-readlink v) > (tramp-send-command-and-check > - v (format > - (concat > - "(if %s -h \"%s\"; then echo t; else echo nil; fi) && " > - "%s --canonicalize-missing %s") > - (tramp-get-test-command v) > - (tramp-shell-quote-argument localname) > - (tramp-get-remote-readlink v) > - (tramp-shell-quote-argument localname))) > + v (format "%s --canonicalize-missing %s" > + (tramp-get-remote-readlink v) > + (tramp-shell-quote-argument localname))) > (with-current-buffer (tramp-get-connection-buffer v) > (goto-char (point-min)) > - (tramp-set-file-property v localname "file-symlink-marker" (read > (current-buffer))) > - ;; We cannot call `read', the file name isn't quoted. > - (forward-line) > - (buffer-substring (point) (line-end-position)))) > + (buffer-substring (point-min) (line-end-position)))) Yes. But this removes the performance optimization, to return both the information, whether a give file is a symlink, and its true name. This optimization avoids one round trip. > At this point I thought I should raise it with yourselves. Instead, I've puzzled the attached patch, which uses a shell function instead. Could you please check? > Stace Best regards, Michael.
diff --git a/lisp/tramp-sh.el b/lisp/tramp-sh.el index 047d93a5..481a3979 100644 --- a/lisp/tramp-sh.el +++ b/lisp/tramp-sh.el @@ -648,6 +648,14 @@ we have this shell function. Format specifiers are replaced by `tramp-expand-script', percent characters need to be doubled.") +(defconst tramp-readlink-file-truename + "if %s -h \"$1\"; then echo t; else echo nil; fi +%s --canonicalize-missing \"$1\"" + "Shell script to produce output suitable for use with `file-truename' +on the remote file system. +Format specifiers are replaced by `tramp-expand-script', percent +characters need to be doubled.") + (defconst tramp-perl-file-truename "%p -e ' use File::Spec; @@ -1291,14 +1299,12 @@ Operations not mentioned here will be handled by the normal Emacs functions.") (cond ;; Use GNU readlink --canonicalize-missing where available. ((tramp-get-remote-readlink v) + (tramp-maybe-send-script + v (format tramp-readlink-file-truename + (tramp-get-test-command v) (tramp-get-remote-readlink v)) + "tramp_readlink_file_truename") (tramp-send-command-and-check - v (format - (concat - "(if %s -h \"%s\"; then echo t; else echo nil; fi) && " - "%s --canonicalize-missing %s") - (tramp-get-test-command v) - (tramp-shell-quote-argument localname) - (tramp-get-remote-readlink v) - (tramp-shell-quote-argument localname))) + v (format "tramp_readlink_file_truename %s" + (tramp-shell-quote-argument localname))) (with-current-buffer (tramp-get-connection-buffer v) (goto-char (point-min)) (tramp-set-file-property v localname "file-symlink-marker" (read (current-buffer)))