1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-27 10:54:40 +00:00

Handle too long commands in Tramp

* lisp/net/tramp-sh.el (tramp-sh-handle-make-symbolic-link)
(tramp-do-file-attributes-with-ls): Send sequence of commands, in
order to not exceed shell command line limit.

* test/automated/tramp-tests.el (tramp--test-darwin-p): Remove.
(tramp--test-utf8): Include Arabic file name, again.
This commit is contained in:
Michael Albinus 2016-01-10 13:07:21 +01:00
parent 684eb58db9
commit 1089dc98b7
2 changed files with 115 additions and 111 deletions

View File

@ -1100,15 +1100,19 @@ target of the symlink differ."
;; Right, they are on the same host, regardless of user, method,
;; etc. We now make the link on the remote machine. This will
;; occur as the user that FILENAME belongs to.
(tramp-send-command-and-check
l
(format
"cd %s && %s -sf %s %s"
(tramp-shell-quote-argument cwd)
ln
(tramp-shell-quote-argument filename)
(tramp-shell-quote-argument l-localname))
t))))
(and (tramp-send-command-and-check
l (format "cd %s" (tramp-shell-quote-argument cwd)))
(tramp-send-command-and-check
l (format
"%s -sf %s %s"
ln
(tramp-shell-quote-argument filename)
;; The command could exceed PATH_MAX, so we use
;; relative file names. However, relative file names
;; could start with "-". `tramp-shell-quote-argument'
;; does not handle this, we must do it ourselves.
(tramp-shell-quote-argument
(concat "./" (file-name-nondirectory l-localname)))))))))
(defun tramp-sh-handle-file-truename (filename)
"Like `file-truename' for Tramp files."
@ -1266,100 +1270,108 @@ target of the symlink differ."
res-inode res-filemodes res-numlinks
res-uid res-gid res-size res-symlink-target)
(tramp-message vec 5 "file attributes with ls: %s" localname)
(tramp-send-command
vec
(format "(%s %s || %s -h %s) && %s %s %s %s"
(tramp-get-file-exists-command vec)
(tramp-shell-quote-argument localname)
(tramp-get-test-command vec)
(tramp-shell-quote-argument localname)
(tramp-get-ls-command vec)
(if (eq id-format 'integer) "-ildn" "-ild")
;; On systems which have no quoting style, file names
;; with special characters could fail.
(cond
((tramp-get-ls-command-with-quoting-style vec)
"--quoting-style=c")
((tramp-get-ls-command-with-w-option vec)
"-w")
(t ""))
(tramp-shell-quote-argument localname)))
;; Parse `ls -l' output ...
(with-current-buffer (tramp-get-buffer vec)
(when (> (buffer-size) 0)
(goto-char (point-min))
;; ... inode
(setq res-inode
(condition-case err
(read (current-buffer))
(invalid-read-syntax
(when (and (equal (cadr err)
"Integer constant overflow in reader")
(string-match
"^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
(car (cddr err))))
(let* ((big (read (substring (car (cddr err)) 0
(match-beginning 1))))
(small (read (match-string 1 (car (cddr err)))))
(twiddle (/ small 65536)))
(cons (+ big twiddle)
(- small (* twiddle 65536))))))))
;; ... file mode flags
(setq res-filemodes (symbol-name (read (current-buffer))))
;; ... number links
(setq res-numlinks (read (current-buffer)))
;; ... uid and gid
(setq res-uid (read (current-buffer)))
(setq res-gid (read (current-buffer)))
(if (eq id-format 'integer)
;; We cannot send all three commands combined, it could exceed
;; NAME_MAX or PATH_MAX. Happened on Mac OS X, for example.
(when (or (tramp-send-command-and-check
vec
(format "%s %s"
(tramp-get-file-exists-command vec)
(tramp-shell-quote-argument localname)))
(tramp-send-command-and-check
vec
(format "%s -h %s"
(tramp-get-test-command vec)
(tramp-shell-quote-argument localname))))
(tramp-send-command
vec
(format "%s %s %s %s"
(tramp-get-ls-command vec)
(if (eq id-format 'integer) "-ildn" "-ild")
;; On systems which have no quoting style, file names
;; with special characters could fail.
(cond
((tramp-get-ls-command-with-quoting-style vec)
"--quoting-style=c")
((tramp-get-ls-command-with-w-option vec)
"-w")
(t ""))
(tramp-shell-quote-argument localname)))
;; Parse `ls -l' output ...
(with-current-buffer (tramp-get-buffer vec)
(when (> (buffer-size) 0)
(goto-char (point-min))
;; ... inode
(setq res-inode
(condition-case err
(read (current-buffer))
(invalid-read-syntax
(when (and (equal (cadr err)
"Integer constant overflow in reader")
(string-match
"^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
(car (cddr err))))
(let* ((big (read (substring (car (cddr err)) 0
(match-beginning 1))))
(small (read (match-string 1 (car (cddr err)))))
(twiddle (/ small 65536)))
(cons (+ big twiddle)
(- small (* twiddle 65536))))))))
;; ... file mode flags
(setq res-filemodes (symbol-name (read (current-buffer))))
;; ... number links
(setq res-numlinks (read (current-buffer)))
;; ... uid and gid
(setq res-uid (read (current-buffer)))
(setq res-gid (read (current-buffer)))
(if (eq id-format 'integer)
(progn
(unless (numberp res-uid) (setq res-uid -1))
(unless (numberp res-gid) (setq res-gid -1)))
(progn
(unless (numberp res-uid) (setq res-uid -1))
(unless (numberp res-gid) (setq res-gid -1)))
(progn
(unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
(unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
;; ... size
(setq res-size (read (current-buffer)))
;; From the file modes, figure out other stuff.
(setq symlinkp (eq ?l (aref res-filemodes 0)))
(setq dirp (eq ?d (aref res-filemodes 0)))
;; If symlink, find out file name pointed to.
(when symlinkp
(search-forward "-> ")
(setq res-symlink-target
(if (tramp-get-ls-command-with-quoting-style vec)
(read (current-buffer))
(buffer-substring (point) (point-at-eol)))))
;; Return data gathered.
(list
;; 0. t for directory, string (name linked to) for symbolic
;; link, or nil.
(or dirp res-symlink-target)
;; 1. Number of links to file.
res-numlinks
;; 2. File uid.
res-uid
;; 3. File gid.
res-gid
;; 4. Last access time, as a list of integers. Normally this
;; would be in the same format as `current-time', but the
;; subseconds part is not currently implemented, and (0 0)
;; denotes an unknown time.
;; 5. Last modification time, likewise.
;; 6. Last status change time, likewise.
'(0 0) '(0 0) '(0 0) ;CCC how to find out?
;; 7. Size in bytes (-1, if number is out of range).
res-size
;; 8. File modes, as a string of ten letters or dashes as in ls -l.
res-filemodes
;; 9. t if file's gid would change if file were deleted and
;; recreated. Will be set in `tramp-convert-file-attributes'.
t
;; 10. Inode number.
res-inode
;; 11. Device number. Will be replaced by a virtual device number.
-1
)))))
(unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
(unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
;; ... size
(setq res-size (read (current-buffer)))
;; From the file modes, figure out other stuff.
(setq symlinkp (eq ?l (aref res-filemodes 0)))
(setq dirp (eq ?d (aref res-filemodes 0)))
;; If symlink, find out file name pointed to.
(when symlinkp
(search-forward "-> ")
(setq res-symlink-target
(if (tramp-get-ls-command-with-quoting-style vec)
(read (current-buffer))
(buffer-substring (point) (point-at-eol)))))
;; Return data gathered.
(list
;; 0. t for directory, string (name linked to) for symbolic
;; link, or nil.
(or dirp res-symlink-target)
;; 1. Number of links to file.
res-numlinks
;; 2. File uid.
res-uid
;; 3. File gid.
res-gid
;; 4. Last access time, as a list of integers. Normally
;; this would be in the same format as `current-time', but
;; the subseconds part is not currently implemented, and (0
;; 0) denotes an unknown time.
;; 5. Last modification time, likewise.
;; 6. Last status change time, likewise.
'(0 0) '(0 0) '(0 0) ;CCC how to find out?
;; 7. Size in bytes (-1, if number is out of range).
res-size
;; 8. File modes, as a string of ten letters or dashes as in ls -l.
res-filemodes
;; 9. t if file's gid would change if file were deleted and
;; recreated. Will be set in `tramp-convert-file-attributes'.
t
;; 10. Inode number.
res-inode
;; 11. Device number. Will be replaced by a virtual device number.
-1
))))))
(defun tramp-do-file-attributes-with-perl
(vec localname &optional id-format)

View File

@ -1785,14 +1785,6 @@ Several special characters do not work properly there."
(file-truename tramp-test-temporary-file-directory) nil
(string-match "^HP-UX" (tramp-get-connection-property v "uname" ""))))
(defun tramp--test-darwin-p ()
"Check, whether the remote host runs Mac OS X.
Several special characters do not work properly there."
;; We must refill the cache. `file-truename' does it.
(with-parsed-tramp-file-name
(file-truename tramp-test-temporary-file-directory) nil
(string-match "^Darwin" (tramp-get-connection-property v "uname" ""))))
(defun tramp--test-check-files (&rest files)
"Run a simple but comprehensive test over every file in FILES."
;; We must use `file-truename' for the temporary directory, because
@ -2046,7 +2038,7 @@ Use the `ls' command."
(file-name-coding-system 'utf-8))
(tramp--test-check-files
(unless (tramp--test-hpux-p) "Γυρίστε το Γαλαξία με Ώτο Στοπ")
(unless (or (tramp--test-hpux-p) (tramp--test-darwin-p))
(unless (tramp--test-hpux-p)
"أصبح بوسعك الآن تنزيل نسخة كاملة من موسوعة ويكيبيديا العربية لتصفحها بلا اتصال بالإنترنت")
"银河系漫游指南系列"
"Автостопом по гала́ктике")))