From 2abcca23910d1fa5fe0bcac3ebc5b62df8e0a741 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sun, 4 Aug 2019 12:47:43 +0200 Subject: [PATCH] Implement set-file-* functions for tramp-gvfs.el * lisp/net/tramp-gvfs.el (tramp-gvfs-gio-mapping): Add "gvfs-set-attribute". (tramp-gvfs-file-name-handler-alist): Add `tramp-gvfs-handle-set-file-modes', `tramp-gvfs-handle-set-file-times' and `tramp-gvfs-handle-set-file-uid-gid'. (tramp-gvfs-handle-set-file-modes) (tramp-gvfs-handle-set-file-times) (tramp-sh-handle-set-file-uid-gid): New defuns. * lisp/net/tramp.el (tramp-handle-write-region): Set file modes. * test/lisp/net/tramp-tests.el (tramp-test20-file-modes) (tramp-test22-file-times): Do not skip for tramp-gvfs.el. --- lisp/net/tramp-gvfs.el | 49 +++++++++++++++++++++++++++++++++--- lisp/net/tramp.el | 9 ++++++- test/lisp/net/tramp-tests.el | 11 ++++++-- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 9d45e6a8ce9..a606ba67177 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -471,6 +471,7 @@ It has been changed in GVFS 1.14.") ("gvfs-mount" . "mount") ("gvfs-move" . "move") ("gvfs-rm" . "remove") + ("gvfs-set-attribute" . "set") ("gvfs-trash" . "trash")) "List of cons cells, mapping \"gvfs-\" to \"gio \".") @@ -590,15 +591,15 @@ It has been changed in GVFS 1.14.") (process-file . ignore) (rename-file . tramp-gvfs-handle-rename-file) (set-file-acl . ignore) - (set-file-modes . ignore) + (set-file-modes . tramp-gvfs-handle-set-file-modes) (set-file-selinux-context . ignore) - (set-file-times . ignore) + (set-file-times . tramp-gvfs-handle-set-file-times) (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) (shell-command . ignore) (start-file-process . ignore) (substitute-in-file-name . tramp-handle-substitute-in-file-name) (temporary-file-directory . tramp-handle-temporary-file-directory) - (tramp-set-file-uid-gid . ignore) + (tramp-set-file-uid-gid . tramp-gvfs-handle-set-file-uid-gid) (unhandled-file-name-directory . ignore) (vc-registered . ignore) (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) @@ -1325,6 +1326,48 @@ file-notify events." (tramp-run-real-handler #'rename-file (list filename newname ok-if-already-exists)))) +(defun tramp-gvfs-handle-set-file-modes (filename mode) + "Like `set-file-modes' for Tramp files." + (with-parsed-tramp-file-name filename nil + (tramp-flush-file-properties v (file-name-directory localname)) + (tramp-flush-file-properties v localname) + (tramp-gvfs-send-command + v "gvfs-set-attribute" "-t" "uint32" + (tramp-gvfs-url-file-name (tramp-make-tramp-file-name v)) + "unix::mode" (number-to-string mode)))) + +(defun tramp-gvfs-handle-set-file-times (filename &optional time) + "Like `set-file-times' for Tramp files." + (with-parsed-tramp-file-name filename nil + (tramp-flush-file-properties v (file-name-directory localname)) + (tramp-flush-file-properties v localname) + (let ((time + (if (or (null time) + (tramp-compat-time-equal-p time tramp-time-doesnt-exist) + (tramp-compat-time-equal-p time tramp-time-dont-know)) + (current-time) + time))) + (tramp-gvfs-send-command + v "gvfs-set-attribute" "-t" "uint64" + (tramp-gvfs-url-file-name (tramp-make-tramp-file-name v)) + "time::modified" (format-time-string "%s" time))))) + +(defun tramp-gvfs-set-file-uid-gid (filename &optional uid gid) + "Like `tramp-set-file-uid-gid' for Tramp files." + (with-parsed-tramp-file-name filename nil + (tramp-flush-file-properties v (file-name-directory localname)) + (tramp-flush-file-properties v localname) + (when (natnump uid) + (tramp-gvfs-send-command + v "gvfs-set-attribute" "-t" "uint32" + (tramp-gvfs-url-file-name (tramp-make-tramp-file-name v)) + "unix::uid" (number-to-string uid))) + (when (natnump gid) + (tramp-gvfs-send-command + v "gvfs-set-attribute" "-t" "uint32" + (tramp-gvfs-url-file-name (tramp-make-tramp-file-name v)) + "unix::gid" (number-to-string gid))))) + ;; File name conversions. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 717ced80f28..c589557132a 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3772,9 +3772,16 @@ of." (format "File %s exists; overwrite anyway? " filename))))) (tramp-error v 'file-already-exists filename)) - (let ((tmpfile (tramp-compat-make-temp-file filename))) + (let ((tmpfile (tramp-compat-make-temp-file filename)) + (modes (save-excursion (tramp-default-file-modes filename)))) (when (and append (file-exists-p filename)) (copy-file filename tmpfile 'ok)) + ;; The permissions of the temporary file should be set. If + ;; FILENAME does not exist (eq modes nil) it has been + ;; renamed to the backup file. This case `save-buffer' + ;; handles permissions. + ;; Ensure that it is still readable. + (set-file-modes tmpfile (logior (or modes 0) #o0400)) ;; We say `no-message' here because we don't want the visited file ;; modtime data to be clobbered from the temp file. We call ;; `set-visited-file-modtime' ourselves later on. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 1404ef39d55..f60dea36bf5 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -3143,7 +3143,13 @@ They might differ only in access time." "Check `file-modes'. This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (skip-unless (tramp--test-enabled)) - (skip-unless (or (tramp--test-sh-p) (tramp--test-sudoedit-p))) + (skip-unless + (or (tramp--test-sh-p) (tramp--test-sudoedit-p) + ;; Not all tramp-gvfs.el methods support changing the file mode. + (and + (tramp--test-gvfs-p) + (string-match-p + "ftp" (file-remote-p tramp-test-temporary-file-directory 'method))))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) (let ((tmp-name (tramp--test-make-temp-name nil quoted))) @@ -3443,7 +3449,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." "Check `set-file-times' and `file-newer-than-file-p'." (skip-unless (tramp--test-enabled)) (skip-unless - (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sudoedit-p))) + (or (tramp--test-adb-p) (tramp--test-gvfs-p) + (tramp--test-sh-p) (tramp--test-sudoedit-p))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) -- 2.39.2