bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#9879: 23.3; making script executable with tramp


From: Michael Albinus
Subject: bug#9879: 23.3; making script executable with tramp
Date: Wed, 16 Nov 2011 20:59:56 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.90 (gnu/linux)

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.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]