diff options
| author | Michael Albinus | 2018-01-30 17:34:02 +0100 |
|---|---|---|
| committer | Michael Albinus | 2018-01-30 17:34:02 +0100 |
| commit | fd6972ac0720bde830728254b8d791c81e01d63f (patch) | |
| tree | a6a73a8b5aa9c65acf6230c7fe56454f1861e670 /lisp | |
| parent | 084cfae0e624469ebca78b155ffe4e2c20f2b205 (diff) | |
| download | emacs-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.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/net/tramp-archive.el | 111 | ||||
| -rw-r--r-- | lisp/net/tramp-gvfs.el | 17 |
2 files changed, 66 insertions, 62 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 | 305 | The hash key is the archive name. The value is a cons of the | |
| 306 | (defun tramp-archive-local-copy (archive) | 306 | used `tramp-file-name' structure for tramp-gvfs, and the file |
| 307 | "Return copy of ARCHIVE, usable by GVFS. | 307 | name of a local copy, if any.") |
| 308 | ARCHIVE 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 | 311 | The structure consists of the `tramp-archive-method' method, the |
| 312 | ;; This is just an auxiliary VEC for caching properties. | 312 | hexlified archive name as host, and the localname. The archive |
| 313 | (make-tramp-file-name :method tramp-archive-method :host archive) | 313 | name 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. | ||
| 385 | The structure consists of the `tramp-archive-method' method, the | ||
| 386 | hexlified archive name as host, and the localname. The archive | ||
| 387 | name 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. |
| 403 | VEC is expected to be a `tramp-file-name', with the method being | 404 | VEC 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. |