aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2018-01-30 17:34:02 +0100
committerMichael Albinus2018-01-30 17:34:02 +0100
commitfd6972ac0720bde830728254b8d791c81e01d63f (patch)
treea6a73a8b5aa9c65acf6230c7fe56454f1861e670
parent084cfae0e624469ebca78b155ffe4e2c20f2b205 (diff)
downloademacs-fd6972ac0720bde830728254b8d791c81e01d63f.tar.gz
emacs-fd6972ac0720bde830728254b8d791c81e01d63f.zip
Fix Bug#30262
* lisp/net/tramp-archive.el (tramp-archive-hash): Document (changed) layout. (tramp-archive-dissect-file-name): Merge with `tramp-archive-local-copy', which has been removed by this. (tramp-archive-cleanup-hash): Adapt to changed `tramp-archive-hash'. (Bug#30262) * lisp/net/tramp-gvfs.el (tramp-gvfs-unmount): Flush connection properties. * test/lisp/net/tramp-archive-tests.el (tramp-archive-test01-file-name-syntax) (tramp-archive-test02-file-name-dissect) (tramp-archive-test16-directory-files) (tramp-archive-test26-file-name-completion): Adapt to changed test file. (tramp-archive-test08-file-local-copy): Be more robust in cleanup. * test/lisp/net/tramp-archive-resources/foo.tar.gz: Adapt to extended test.
-rw-r--r--lisp/net/tramp-archive.el111
-rw-r--r--lisp/net/tramp-gvfs.el17
-rw-r--r--test/lisp/net/tramp-archive-resources/foo.tar.gzbin234 -> 274 bytes
-rw-r--r--test/lisp/net/tramp-archive-tests.el32
4 files changed, 84 insertions, 76 deletions
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 45e3bf0a606..ac8b76b9442 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -301,27 +301,42 @@ pass to the OPERATION."
301 t)) 301 t))
302 302
303(defvar tramp-archive-hash (make-hash-table :test 'equal) 303(defvar tramp-archive-hash (make-hash-table :test 'equal)
304 "Hash table for archive local copies.") 304 "Hash table for archive local copies.
305 305The hash key is the archive name. The value is a cons of the
306(defun tramp-archive-local-copy (archive) 306used `tramp-file-name' structure for tramp-gvfs, and the file
307 "Return copy of ARCHIVE, usable by GVFS. 307name of a local copy, if any.")
308ARCHIVE is the archive component of an archive file name." 308
309 (setq archive (file-truename archive)) 309(defun tramp-archive-dissect-file-name (name)
310 (let ((tramp-verbose 0)) 310 "Return a `tramp-file-name' structure.
311 (with-tramp-connection-property 311The structure consists of the `tramp-archive-method' method, the
312 ;; This is just an auxiliary VEC for caching properties. 312hexlified archive name as host, and the localname. The archive
313 (make-tramp-file-name :method tramp-archive-method :host archive) 313name is kept in slot `hop'"
314 "archive" 314 (save-match-data
315 (unless (tramp-archive-file-name-p name)
316 (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name))
317 ;; The `string-match' happened in `tramp-archive-file-name-p'.
318 (let ((archive (match-string 1 name))
319 (localname (match-string 2 name))
320 (tramp-verbose 0)
321 vec copy)
322
323 (setq archive (file-truename archive))
324
315 (cond 325 (cond
326 ;; The value is already in the hash table.
327 ((setq vec (car (gethash archive tramp-archive-hash))))
328
316 ;; File archives inside file archives. 329 ;; File archives inside file archives.
317 ((tramp-archive-file-name-p archive) 330 ((tramp-archive-file-name-p archive)
318 (let ((archive 331 (let ((archive
319 (tramp-make-tramp-file-name 332 (tramp-make-tramp-file-name
320 (tramp-archive-dissect-file-name archive) nil 'noarchive))) 333 (tramp-archive-dissect-file-name archive) nil 'noarchive)))
321 ;; We call `file-attributes' in order to mount the archive. 334 (setq vec
322 (file-attributes archive) 335 (make-tramp-file-name
323 (puthash archive nil tramp-archive-hash) 336 :method tramp-archive-method :hop archive
324 archive)) 337 :host (url-hexify-string (tramp-gvfs-url-file-name archive)))))
338 (puthash archive (list vec) tramp-archive-hash))
339
325 ;; http://... 340 ;; http://...
326 ((and url-handler-mode 341 ((and url-handler-mode
327 tramp-compat-use-url-tramp-p 342 tramp-compat-use-url-tramp-p
@@ -332,26 +347,36 @@ ARCHIVE is the archive component of an archive file name."
332 (url-type (url-generic-parse-url archive)) 347 (url-type (url-generic-parse-url archive))
333 url-tramp-protocols)) 348 url-tramp-protocols))
334 (archive (url-tramp-convert-url-to-tramp archive))) 349 (archive (url-tramp-convert-url-to-tramp archive)))
335 (puthash archive nil tramp-archive-hash) 350 (setq vec
336 archive)) 351 (make-tramp-file-name
352 :method tramp-archive-method :hop archive
353 :host (url-hexify-string (tramp-gvfs-url-file-name archive)))))
354 (puthash archive (list vec) tramp-archive-hash))
355
337 ;; GVFS supported schemes. 356 ;; GVFS supported schemes.
338 ((or (tramp-gvfs-file-name-p archive) 357 ((or (tramp-gvfs-file-name-p archive)
339 (not (file-remote-p archive))) 358 (not (file-remote-p archive)))
340 (puthash archive nil tramp-archive-hash) 359 (setq vec
341 archive) 360 (make-tramp-file-name
361 :method tramp-archive-method :hop archive
362 :host (url-hexify-string (tramp-gvfs-url-file-name archive))))
363 (puthash archive (list vec) tramp-archive-hash))
364
342 ;; Anything else. Here we call `file-local-copy', which we 365 ;; Anything else. Here we call `file-local-copy', which we
343 ;; have avoided so far. 366 ;; have avoided so far.
344 (t (let ((inhibit-file-name-operation 'file-local-copy) 367 (t (let ((inhibit-file-name-operation 'file-local-copy)
345 (inhibit-file-name-handlers 368 (inhibit-file-name-handlers
346 (cons 'jka-compr-handler inhibit-file-name-handlers)) 369 (cons 'jka-compr-handler inhibit-file-name-handlers)))
347 result) 370 (setq copy (file-local-copy archive)
348 (or (and (setq result (gethash archive tramp-archive-hash nil)) 371 vec
349 (file-readable-p result)) 372 (make-tramp-file-name
350 (puthash 373 :method tramp-archive-method :hop archive
351 archive 374 :host (url-hexify-string (tramp-gvfs-url-file-name copy)))))
352 (setq result (file-local-copy archive)) 375 (puthash archive (cons vec copy) tramp-archive-hash)))
353 tramp-archive-hash)) 376
354 result)))))) 377 ;; So far, `vec' handles just the mount point. Add `localname'.
378 (setf (tramp-file-name-localname vec) localname)
379 vec)))
355 380
356;;;###tramp-autoload 381;;;###tramp-autoload
357(defun tramp-archive-cleanup-hash () 382(defun tramp-archive-cleanup-hash ()
@@ -360,16 +385,10 @@ ARCHIVE is the archive component of an archive file name."
360 (lambda (key value) 385 (lambda (key value)
361 ;; Unmount local copy. 386 ;; Unmount local copy.
362 (ignore-errors 387 (ignore-errors
363 (let ((tramp-gvfs-methods tramp-archive-all-gvfs-methods) 388 (tramp-message (car value) 3 "Unmounting %s" (or (cdr value) key))
364 (file-archive (file-name-as-directory key))) 389 (tramp-gvfs-unmount (car value)))
365 (tramp-message
366 (and (tramp-tramp-file-p key) (tramp-dissect-file-name key)) 3
367 "Unmounting %s" file-archive)
368 (tramp-gvfs-unmount
369 (tramp-dissect-file-name
370 (tramp-archive-gvfs-file-name file-archive)))))
371 ;; Delete local copy. 390 ;; Delete local copy.
372 (ignore-errors (when value (delete-file value))) 391 (ignore-errors (delete-file (cdr value)))
373 (remhash key tramp-archive-hash)) 392 (remhash key tramp-archive-hash))
374 tramp-archive-hash) 393 tramp-archive-hash)
375 (clrhash tramp-archive-hash)) 394 (clrhash tramp-archive-hash))
@@ -380,24 +399,6 @@ ARCHIVE is the archive component of an archive file name."
380 (remove-hook 'kill-emacs-hook 399 (remove-hook 'kill-emacs-hook
381 'tramp-archive-cleanup-hash))) 400 'tramp-archive-cleanup-hash)))
382 401
383(defun tramp-archive-dissect-file-name (name)
384 "Return a `tramp-file-name' structure.
385The structure consists of the `tramp-archive-method' method, the
386hexlified archive name as host, and the localname. The archive
387name is kept in slot `hop'"
388 (save-match-data
389 (unless (tramp-archive-file-name-p name)
390 (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name))
391 ;; The `string-match' happened in `tramp-archive-file-name-p'.
392 (let ((archive (match-string 1 name))
393 (localname (match-string 2 name))
394 (tramp-verbose 0))
395 (make-tramp-file-name
396 :method tramp-archive-method :user nil :domain nil :host
397 (url-hexify-string
398 (tramp-gvfs-url-file-name (tramp-archive-local-copy archive)))
399 :port nil :localname localname :hop archive))))
400
401(defsubst tramp-file-name-archive (vec) 402(defsubst tramp-file-name-archive (vec)
402 "Extract the archive file name from VEC. 403 "Extract the archive file name from VEC.
403VEC is expected to be a `tramp-file-name', with the method being 404VEC is expected to be a `tramp-file-name', with the method being
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 6745ae02c7b..70ac077a7c5 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -1778,13 +1778,16 @@ file-notify events."
1778 1778
1779(defun tramp-gvfs-unmount (vec) 1779(defun tramp-gvfs-unmount (vec)
1780 "Unmount the object identified by VEC." 1780 "Unmount the object identified by VEC."
1781 (let ((vec (copy-tramp-file-name vec))) 1781 (setf (tramp-file-name-localname vec) "/"
1782 (setf (tramp-file-name-localname vec) "/" 1782 (tramp-file-name-hop vec) nil)
1783 (tramp-file-name-hop vec) nil) 1783 (when (tramp-gvfs-connection-mounted-p vec)
1784 (when (tramp-gvfs-connection-mounted-p vec) 1784 (tramp-gvfs-send-command
1785 (tramp-gvfs-send-command 1785 vec "gvfs-mount" "-u"
1786 vec "gvfs-mount" "-u" 1786 (tramp-gvfs-url-file-name (tramp-make-tramp-file-name vec))))
1787 (tramp-gvfs-url-file-name (tramp-make-tramp-file-name vec)))))) 1787 (while (tramp-gvfs-connection-mounted-p vec)
1788 (read-event nil nil 0.1))
1789 (tramp-flush-connection-properties vec)
1790 (tramp-flush-connection-properties (tramp-get-connection-process vec)))
1788 1791
1789(defun tramp-gvfs-mount-spec-entry (key value) 1792(defun tramp-gvfs-mount-spec-entry (key value)
1790 "Construct a mount-spec entry to be used in a mount_spec. 1793 "Construct a mount-spec entry to be used in a mount_spec.
diff --git a/test/lisp/net/tramp-archive-resources/foo.tar.gz b/test/lisp/net/tramp-archive-resources/foo.tar.gz
index 68925b147fc..0d2e9878dd7 100644
--- a/test/lisp/net/tramp-archive-resources/foo.tar.gz
+++ b/test/lisp/net/tramp-archive-resources/foo.tar.gz
Binary files differ
diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el
index 149ed370432..82dd5de8b9a 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -99,9 +99,9 @@ variables, so we check the Emacs version directly."
99 (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo/bar"))) 99 (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo/bar")))
100 ;; A file archive inside a file archive. 100 ;; A file archive inside a file archive.
101 (should 101 (should
102 (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo.tar"))) 102 (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar")))
103 (should 103 (should
104 (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo.tar/")))) 104 (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar/"))))
105 105
106(ert-deftest tramp-archive-test02-file-name-dissect () 106(ert-deftest tramp-archive-test02-file-name-dissect ()
107 "Check archive file name components." 107 "Check archive file name components."
@@ -145,13 +145,14 @@ variables, so we check the Emacs version directly."
145 145
146 ;; File archive in file archive. 146 ;; File archive in file archive.
147 (let* ((tramp-archive-test-file-archive 147 (let* ((tramp-archive-test-file-archive
148 (concat tramp-archive-test-archive "bar.tar")) 148 (concat tramp-archive-test-archive "baz.tar"))
149 (tramp-archive-test-archive 149 (tramp-archive-test-archive
150 (file-name-as-directory tramp-archive-test-file-archive)) 150 (file-name-as-directory tramp-archive-test-file-archive))
151 (tramp-methods (cons `(,tramp-archive-method) tramp-methods)) 151 (tramp-methods (cons `(,tramp-archive-method) tramp-methods))
152 (tramp-gvfs-methods tramp-archive-all-gvfs-methods)) 152 (tramp-gvfs-methods tramp-archive-all-gvfs-methods))
153 (unwind-protect 153 (unwind-protect
154 (with-parsed-tramp-archive-file-name tramp-archive-test-archive nil 154 (with-parsed-tramp-archive-file-name
155 (expand-file-name "bar" tramp-archive-test-archive) nil
155 (should (string-equal method tramp-archive-method)) 156 (should (string-equal method tramp-archive-method))
156 (should-not user) 157 (should-not user)
157 (should-not domain) 158 (should-not domain)
@@ -184,8 +185,12 @@ variables, so we check the Emacs version directly."
184 nil "/")) 185 nil "/"))
185 (file-name-nondirectory tramp-archive-test-file-archive))))) 186 (file-name-nondirectory tramp-archive-test-file-archive)))))
186 (should-not port) 187 (should-not port)
187 (should (string-equal localname "/")) 188 (should (string-equal localname "/bar"))
188 (should (string-equal archive tramp-archive-test-file-archive))) 189 ;; The `archive' component is now already a Tramp file name.
190 (should
191 (string-equal
192 archive
193 (tramp-archive-gvfs-file-name tramp-archive-test-file-archive))))
189 194
190 ;; Cleanup. 195 ;; Cleanup.
191 (tramp-archive-cleanup-hash)))) 196 (tramp-archive-cleanup-hash))))
@@ -290,9 +295,8 @@ This checks also `file-name-as-directory', `file-name-directory',
290 :type tramp-file-missing)) 295 :type tramp-file-missing))
291 296
292 ;; Cleanup. 297 ;; Cleanup.
293 (ignore-errors 298 (ignore-errors (tramp-archive--test-delete tmp-name))
294 (tramp-archive--test-delete tmp-name) 299 (tramp-archive-cleanup-hash))))
295 (tramp-archive-cleanup-hash)))))
296 300
297(ert-deftest tramp-archive-test09-insert-file-contents () 301(ert-deftest tramp-archive-test09-insert-file-contents ()
298 "Check `insert-file-contents'." 302 "Check `insert-file-contents'."
@@ -444,7 +448,7 @@ This checks also `file-name-as-directory', `file-name-directory',
444 (skip-unless tramp-gvfs-enabled) 448 (skip-unless tramp-gvfs-enabled)
445 449
446 (let ((tmp-name tramp-archive-test-archive) 450 (let ((tmp-name tramp-archive-test-archive)
447 (files '("." ".." "bar" "foo.hrd" "foo.lnk" "foo.txt"))) 451 (files '("." ".." "bar" "baz.tar" "foo.hrd" "foo.lnk" "foo.txt")))
448 (unwind-protect 452 (unwind-protect
449 (progn 453 (progn
450 (should (file-directory-p tmp-name)) 454 (should (file-directory-p tmp-name))
@@ -656,7 +660,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
656 ;; Local files. 660 ;; Local files.
657 (should (equal (file-name-completion "fo" tmp-name) "foo.")) 661 (should (equal (file-name-completion "fo" tmp-name) "foo."))
658 (should (equal (file-name-completion "foo.txt" tmp-name) t)) 662 (should (equal (file-name-completion "foo.txt" tmp-name) t))
659 (should (equal (file-name-completion "b" tmp-name) "bar/")) 663 (should (equal (file-name-completion "b" tmp-name) "ba"))
660 (should-not (file-name-completion "a" tmp-name)) 664 (should-not (file-name-completion "a" tmp-name))
661 (should 665 (should
662 (equal 666 (equal
@@ -668,18 +672,18 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
668 (should 672 (should
669 (equal 673 (equal
670 (sort (file-name-all-completions "b" tmp-name) 'string-lessp) 674 (sort (file-name-all-completions "b" tmp-name) 'string-lessp)
671 '("bar/"))) 675 '("bar/" "baz.tar")))
672 (should-not (file-name-all-completions "a" tmp-name)) 676 (should-not (file-name-all-completions "a" tmp-name))
673 ;; `completion-regexp-list' restricts the completion to 677 ;; `completion-regexp-list' restricts the completion to
674 ;; files which match all expressions in this list. 678 ;; files which match all expressions in this list.
675 (let ((completion-regexp-list 679 (let ((completion-regexp-list
676 `(,directory-files-no-dot-files-regexp "b"))) 680 `(,directory-files-no-dot-files-regexp "b")))
677 (should 681 (should
678 (equal (file-name-completion "" tmp-name) "bar/")) 682 (equal (file-name-completion "" tmp-name) "ba"))
679 (should 683 (should
680 (equal 684 (equal
681 (sort (file-name-all-completions "" tmp-name) 'string-lessp) 685 (sort (file-name-all-completions "" tmp-name) 'string-lessp)
682 '("bar/"))))) 686 '("bar/" "baz.tar")))))
683 687
684 ;; Cleanup. 688 ;; Cleanup.
685 (tramp-archive-cleanup-hash)))) 689 (tramp-archive-cleanup-hash))))