aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMichael Albinus2018-01-30 17:34:02 +0100
committerMichael Albinus2018-01-30 17:34:02 +0100
commitfd6972ac0720bde830728254b8d791c81e01d63f (patch)
treea6a73a8b5aa9c65acf6230c7fe56454f1861e670 /lisp
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.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/net/tramp-archive.el111
-rw-r--r--lisp/net/tramp-gvfs.el17
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 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.