From: Michael Albinus <michael.albinus@gmx.de>
To: Daniel Gildea <gildea@cs.rochester.edu>
Cc: 9879@debbugs.gnu.org, Dan Gildea <gildea@pobox.com>
Subject: bug#9879: 23.3; making script executable with tramp
Date: Wed, 16 Nov 2011 20:59:56 +0100 [thread overview]
Message-ID: <87pqgrsurn.fsf@gmx.de> (raw)
In-Reply-To: <87bosgt2wt.fsf@gmx.de> (Michael Albinus's message of "Sun, 13 Nov 2011 17:14:58 +0100")
Michael Albinus <michael.albinus@gmx.de> writes:
> You are working on "/u/gildea/xx.sh", which is a symlink to
> "/home/vax7/u19/gildea/xx.sh". You have written "/u/gildea/xx.sh". Tramp
> tries to check "/home/vax7/u19/gildea/xx.sh" file properties afterwards,
> and it decides that this file doesn't exist.
>
> This is likely because of Tramp's cache, which hasn't been refreshed
> accordingly for the symlink's target after writing.
>
> I will check how to fix this; unfortunately there is no simple patch. It
> might take a day, or two.
The following two patches shall solve the problem, could you, please
verify?
The patches are for Emacs 23.3, however, the line numbers might be a
little bit different.
--8<---------------cut here---------------start------------->8---
Index: tramp.el
===================================================================
RCS file: /sources/tramp/tramp/lisp/tramp.el,v
retrieving revision 2.814.2.16
diff -c -r2.814.2.16 tramp.el
*** tramp.el 12 Oct 2011 14:56:21 -0000 2.814.2.16
--- tramp.el 16 Nov 2011 19:50:48 -0000
***************
*** 2671,2776 ****
(defun tramp-handle-file-truename (filename &optional counter prev-dirs)
"Like `file-truename' for Tramp files."
(with-parsed-tramp-file-name (expand-file-name filename) nil
! (with-file-property v localname "file-truename"
! (let ((result nil)) ; result steps in reverse order
! (tramp-message v 4 "Finding true name for `%s'" filename)
! (cond
! ;; Use GNU readlink --canonicalize-missing where available.
! ((tramp-get-remote-readlink v)
! (setq result
! (tramp-send-command-and-read
! v
! (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\""
! (tramp-get-remote-readlink v)
! (tramp-shell-quote-argument localname)))))
!
! ;; Use Perl implementation.
! ((and (tramp-get-remote-perl v)
! (tramp-get-connection-property v "perl-file-spec" nil)
! (tramp-get-connection-property v "perl-cwd-realpath" nil))
! (tramp-maybe-send-script
! v tramp-perl-file-truename "tramp_perl_file_truename")
! (setq result
! (tramp-send-command-and-read
! v
! (format "tramp_perl_file_truename %s"
! (tramp-shell-quote-argument localname)))))
!
! ;; Do it yourself. We bind `directory-sep-char' here for
! ;; XEmacs on Windows, which would otherwise use backslash.
! (t (let* ((directory-sep-char ?/)
! (steps (tramp-compat-split-string localname "/"))
! (localnamedir (tramp-run-real-handler
! 'file-name-as-directory (list localname)))
! (is-dir (string= localname localnamedir))
! (thisstep nil)
! (numchase 0)
! ;; Don't make the following value larger than
! ;; necessary. People expect an error message in a
! ;; timely fashion when something is wrong;
! ;; otherwise they might think that Emacs is hung.
! ;; Of course, correctness has to come first.
! (numchase-limit 20)
! symlink-target)
! (while (and steps (< numchase numchase-limit))
! (setq thisstep (pop steps))
! (tramp-message
! v 5 "Check %s"
! (mapconcat 'identity
! (append '("") (reverse result) (list thisstep))
! "/"))
! (setq symlink-target
! (nth 0 (file-attributes
! (tramp-make-tramp-file-name
! method user host
! (mapconcat 'identity
! (append '("")
! (reverse result)
! (list thisstep))
! "/")))))
! (cond ((string= "." thisstep)
! (tramp-message v 5 "Ignoring step `.'"))
! ((string= ".." thisstep)
! (tramp-message v 5 "Processing step `..'")
! (pop result))
! ((stringp symlink-target)
! ;; It's a symlink, follow it.
! (tramp-message v 5 "Follow symlink to %s" symlink-target)
! (setq numchase (1+ numchase))
! (when (file-name-absolute-p symlink-target)
! (setq result nil))
! ;; If the symlink was absolute, we'll get a string like
! ;; "/user@host:/some/target"; extract the
! ;; "/some/target" part from it.
! (when (tramp-tramp-file-p symlink-target)
! (unless (tramp-equal-remote filename symlink-target)
! (tramp-error
! v 'file-error
! "Symlink target `%s' on wrong host" symlink-target))
! (setq symlink-target localname))
! (setq steps
! (append (tramp-compat-split-string
! symlink-target "/")
! steps)))
! (t
! ;; It's a file.
! (setq result (cons thisstep result)))))
! (when (>= numchase numchase-limit)
! (tramp-error
! v 'file-error
! "Maximum number (%d) of symlinks exceeded" numchase-limit))
! (setq result (reverse result))
! ;; Combine list to form string.
! (setq result
! (if result
! (mapconcat 'identity (cons "" result) "/")
! "/"))
! (when (and is-dir (or (string= "" result)
! (not (string= (substring result -1) "/"))))
! (setq result (concat result "/"))))))
! (tramp-message v 4 "True name of `%s' is `%s'" filename result)
! (tramp-make-tramp-file-name method user host result)))))
;; Basic functions.
--- 2671,2780 ----
(defun tramp-handle-file-truename (filename &optional counter prev-dirs)
"Like `file-truename' for Tramp files."
(with-parsed-tramp-file-name (expand-file-name filename) nil
! (tramp-make-tramp-file-name method user host
! (with-file-property v localname "file-truename"
! (let ((result nil)) ; result steps in reverse order
! (tramp-message v 4 "Finding true name for `%s'" filename)
! (cond
! ;; Use GNU readlink --canonicalize-missing where available.
! ((tramp-get-remote-readlink v)
! (setq result
! (tramp-send-command-and-read
! v
! (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\""
! (tramp-get-remote-readlink v)
! (tramp-shell-quote-argument localname)))))
!
! ;; Use Perl implementation.
! ((and (tramp-get-remote-perl v)
! (tramp-get-connection-property v "perl-file-spec" nil)
! (tramp-get-connection-property v "perl-cwd-realpath" nil))
! (tramp-maybe-send-script
! v tramp-perl-file-truename "tramp_perl_file_truename")
! (setq result
! (tramp-send-command-and-read
! v
! (format "tramp_perl_file_truename %s"
! (tramp-shell-quote-argument localname)))))
!
! ;; Do it yourself. We bind `directory-sep-char' here for
! ;; XEmacs on Windows, which would otherwise use backslash.
! (t (let* ((directory-sep-char ?/)
! (steps (tramp-compat-split-string localname "/"))
! (localnamedir (tramp-run-real-handler
! 'file-name-as-directory (list localname)))
! (is-dir (string= localname localnamedir))
! (thisstep nil)
! (numchase 0)
! ;; Don't make the following value larger than
! ;; necessary. People expect an error message in
! ;; a timely fashion when something is wrong;
! ;; otherwise they might think that Emacs is hung.
! ;; Of course, correctness has to come first.
! (numchase-limit 20)
! symlink-target)
! (while (and steps (< numchase numchase-limit))
! (setq thisstep (pop steps))
! (tramp-message
! v 5 "Check %s"
! (mapconcat 'identity
! (append '("") (reverse result) (list thisstep))
! "/"))
! (setq symlink-target
! (nth 0 (file-attributes
! (tramp-make-tramp-file-name
! method user host
! (mapconcat 'identity
! (append '("")
! (reverse result)
! (list thisstep))
! "/")))))
! (cond ((string= "." thisstep)
! (tramp-message v 5 "Ignoring step `.'"))
! ((string= ".." thisstep)
! (tramp-message v 5 "Processing step `..'")
! (pop result))
! ((stringp symlink-target)
! ;; It's a symlink, follow it.
! (tramp-message
! v 5 "Follow symlink to %s" symlink-target)
! (setq numchase (1+ numchase))
! (when (file-name-absolute-p symlink-target)
! (setq result nil))
! ;; If the symlink was absolute, we'll get a
! ;; string like "/user@host:/some/target";
! ;; extract the "/some/target" part from it.
! (when (tramp-tramp-file-p symlink-target)
! (unless (tramp-equal-remote filename symlink-target)
! (tramp-error
! v 'file-error
! "Symlink target `%s' on wrong host"
! symlink-target))
! (setq symlink-target localname))
! (setq steps
! (append (tramp-compat-split-string
! symlink-target "/")
! steps)))
! (t
! ;; It's a file.
! (setq result (cons thisstep result)))))
! (when (>= numchase numchase-limit)
! (tramp-error
! v 'file-error
! "Maximum number (%d) of symlinks exceeded" numchase-limit))
! (setq result (reverse result))
! ;; Combine list to form string.
! (setq result
! (if result
! (mapconcat 'identity (cons "" result) "/")
! "/"))
! (when (and is-dir
! (or (string= "" result)
! (not (string= (substring result -1) "/"))))
! (setq result (concat result "/"))))))
! (tramp-message v 4 "True name of `%s' is `%s'" filename result)
! result)))))
;; Basic functions.
--8<---------------cut here---------------end--------------->8---
--8<---------------cut here---------------start------------->8---
Index: tramp-cache.el
===================================================================
RCS file: /sources/tramp/tramp/lisp/tramp-cache.el,v
retrieving revision 2.57.2.1
diff -c -r2.57.2.1 tramp-cache.el
*** tramp-cache.el 24 Jan 2011 10:09:40 -0000 2.57.2.1
--- tramp-cache.el 16 Nov 2011 19:54:34 -0000
***************
*** 145,150 ****
--- 145,155 ----
(defun tramp-flush-file-property (vec file)
"Remove all properties of FILE in the cache context of VEC."
+ ;; Remove file property of symlinks.
+ (let ((truename (tramp-get-file-property vec file "file-truename" nil)))
+ (when (and (stringp truename)
+ (not (string-equal file truename)))
+ (tramp-flush-file-property vec truename)))
;; Unify localname.
(setq vec (copy-sequence vec))
(aset vec 3 (tramp-run-real-handler 'directory-file-name (list file)))
--8<---------------cut here---------------end--------------->8---
Best regards, Michael.
next prev parent reply other threads:[~2011-11-16 19:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-26 18:48 bug#9879: 23.3; making script executable with tramp Dan Gildea
2011-10-27 23:17 ` Glenn Morris
2011-10-27 23:42 ` Dan Gildea
2011-11-11 20:44 ` Glenn Morris
2011-11-13 10:42 ` Michael Albinus
2011-11-13 14:15 ` Daniel Gildea
2011-11-13 16:14 ` Michael Albinus
2011-11-16 19:59 ` Michael Albinus [this message]
2011-11-16 20:26 ` Dan Gildea
2011-11-16 21:55 ` Michael Albinus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pqgrsurn.fsf@gmx.de \
--to=michael.albinus@gmx.de \
--cc=9879@debbugs.gnu.org \
--cc=gildea@cs.rochester.edu \
--cc=gildea@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.