aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2016-08-30 15:36:14 +0200
committerMichael Albinus2016-08-30 15:36:14 +0200
commit62b6c5d2805a07515cbc4368a32376e4d82cf2c3 (patch)
treead873e2ae433c0631782959f1fd28448026dc761
parent4961cc3f368d9114c305efe6243987bcfa3fd29b (diff)
downloademacs-62b6c5d2805a07515cbc4368a32376e4d82cf2c3.tar.gz
emacs-62b6c5d2805a07515cbc4368a32376e4d82cf2c3.zip
Use `file-attribute-*' in Tramp
* lisp/net/tramp-compat.el (tramp-compat-file-attribute-type) (tramp-compat-file-attribute-link-number) (tramp-compat-file-attribute-user-id) (tramp-compat-file-attribute-group-id) (tramp-compat-file-attribute-modification-time) (tramp-compat-file-attribute-size) (tramp-compat-file-attribute-modes): New defaliases. * lisp/net/tramp.el (tramp-handle-file-modes) (tramp-handle-file-newer-than-file-p) (tramp-handle-file-regular-p, tramp-handle-file-symlink-p) (tramp-handle-set-visited-file-modtime) (tramp-handle-verify-visited-file-modtime) (tramp-get-local-gid, tramp-check-cached-permissions): * lisp/net/tramp-adb.el (tramp-adb-handle-file-directory-p) (tramp-adb-handle-file-truename, tramp-adb-handle-copy-file): * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-delete-directory) (tramp-gvfs-handle-file-directory-p) (tramp-gvfs-handle-write-region, tramp-gvfs-get-remote-uid) (tramp-gvfs-get-remote-gid): * lisp/net/tramp-sh.el (tramp-sh-handle-file-truename) (tramp-sh-handle-set-visited-file-modtime) (tramp-sh-handle-verify-visited-file-modtime) (tramp-sh-handle-file-newer-than-file-p) (tramp-sh-handle-file-ownership-preserved-p) (tramp-do-copy-or-rename-file) (tramp-do-copy-or-rename-file-via-buffer) (tramp-do-copy-or-rename-file-directly) (tramp-do-copy-or-rename-file-out-of-band) (tramp-sh-handle-file-local-copy) (tramp-sh-handle-write-region): * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory) (tramp-smb-handle-copy-file) (tramp-smb-handle-file-directory-p) (tramp-smb-handle-file-writable-p) (tramp-smb-handle-insert-directory): Use them.
-rw-r--r--lisp/net/tramp-adb.el26
-rw-r--r--lisp/net/tramp-compat.el59
-rw-r--r--lisp/net/tramp-gvfs.el22
-rw-r--r--lisp/net/tramp-sh.el76
-rw-r--r--lisp/net/tramp-smb.el28
-rw-r--r--lisp/net/tramp.el56
6 files changed, 193 insertions, 74 deletions
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 48a05a7bf4f..3eb1bc44516 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -246,7 +246,9 @@ pass to the OPERATION."
246 246
247(defun tramp-adb-handle-file-directory-p (filename) 247(defun tramp-adb-handle-file-directory-p (filename)
248 "Like `file-directory-p' for Tramp files." 248 "Like `file-directory-p' for Tramp files."
249 (car (file-attributes (file-truename filename)))) 249 (eq (tramp-compat-file-attribute-type
250 (file-attributes (file-truename filename)))
251 t))
250 252
251;; This is derived from `tramp-sh-handle-file-truename'. Maybe the 253;; This is derived from `tramp-sh-handle-file-truename'. Maybe the
252;; code could be shared? 254;; code could be shared?
@@ -281,14 +283,15 @@ pass to the OPERATION."
281 (append '("") (reverse result) (list thisstep)) 283 (append '("") (reverse result) (list thisstep))
282 "/")) 284 "/"))
283 (setq symlink-target 285 (setq symlink-target
284 (nth 0 (file-attributes 286 (tramp-compat-file-attribute-type
285 (tramp-make-tramp-file-name 287 (file-attributes
286 method user host 288 (tramp-make-tramp-file-name
287 (mapconcat 'identity 289 method user host
288 (append '("") 290 (mapconcat 'identity
289 (reverse result) 291 (append '("")
290 (list thisstep)) 292 (reverse result)
291 "/"))))) 293 (list thisstep))
294 "/")))))
292 (cond ((string= "." thisstep) 295 (cond ((string= "." thisstep)
293 (tramp-message v 5 "Ignoring step `.'")) 296 (tramp-message v 5 "Ignoring step `.'"))
294 ((string= ".." thisstep) 297 ((string= ".." thisstep)
@@ -712,7 +715,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
712 715
713 ;; KEEP-DATE handling. 716 ;; KEEP-DATE handling.
714 (when keep-date 717 (when keep-date
715 (set-file-times newname (nth 5 (file-attributes filename)))))) 718 (set-file-times
719 newname
720 (tramp-compat-file-attribute-modification-time
721 (file-attributes filename))))))
716 722
717(defun tramp-adb-handle-rename-file 723(defun tramp-adb-handle-rename-file
718 (filename newname &optional ok-if-already-exists) 724 (filename newname &optional ok-if-already-exists)
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index 19e48f6f251..1c0b8d20fda 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -261,6 +261,65 @@ process."
261 (memq (process-status process) 261 (memq (process-status process)
262 '(run open listen connect stop)))))) 262 '(run open listen connect stop))))))
263 263
264;; `file-attribute-*' are introduced in Emacs 25.1.
265
266(if (fboundp 'file-attribute-type)
267 (defalias 'tramp-compat-file-attribute-type 'file-attribute-type)
268 (defsubst tramp-compat-file-attribute-type (attributes)
269 "The type field in ATTRIBUTES returned by `file-attributes'.
270The value is either t for directory, string (name linked to) for
271symbolic link, or nil."
272 (nth 0 attributes)))
273
274(if (fboundp 'file-attribute-link-number)
275 (defalias 'tramp-compat-file-attribute-link-number
276 'file-attribute-link-number)
277 (defsubst tramp-compat-file-attribute-link-number (attributes)
278 "Return the number of links in ATTRIBUTES returned by `file-attributes'."
279 (nth 1 attributes)))
280
281(if (fboundp 'file-attribute-user-id)
282 (defalias 'tramp-compat-file-attribute-user-id 'file-attribute-user-id)
283 (defsubst tramp-compat-file-attribute-user-id (attributes)
284 "The UID field in ATTRIBUTES returned by `file-attributes'.
285This is either a string or a number. If a string value cannot be
286looked up, a numeric value, either an integer or a float, is
287returned."
288 (nth 2 attributes)))
289
290(if (fboundp 'file-attribute-group-id)
291 (defalias 'tramp-compat-file-attribute-group-id 'file-attribute-group-id)
292 (defsubst tramp-compat-file-attribute-group-id (attributes)
293 "The GID field in ATTRIBUTES returned by `file-attributes'.
294This is either a string or a number. If a string value cannot be
295looked up, a numeric value, either an integer or a float, is
296returned."
297 (nth 3 attributes)))
298
299(if (fboundp 'file-attribute-modification-time)
300 (defalias 'tramp-compat-file-attribute-modification-time
301 'file-attribute-modification-time)
302 (defsubst tramp-compat-file-attribute-modification-time (attributes)
303 "The modification time in ATTRIBUTES returned by `file-attributes'.
304This is the time of the last change to the file's contents, and
305is a list of integers (HIGH LOW USEC PSEC) in the same style
306as (current-time)."
307 (nth 5 attributes)))
308
309(if (fboundp 'file-attribute-size)
310 (defalias 'tramp-compat-file-attribute-size 'file-attribute-size)
311 (defsubst tramp-compat-file-attribute-size (attributes)
312 "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
313This is a floating point number if the size is too large for an integer."
314 (nth 7 attributes)))
315
316(if (fboundp 'file-attribute-modes)
317 (defalias 'tramp-compat-file-attribute-modes 'file-attribute-modes)
318 (defsubst tramp-compat-file-attribute-modes (attributes)
319 "The file modes in ATTRIBUTES returned by `file-attributes'.
320This is a string of ten letters or dashes as in ls -l."
321 (nth 8 attributes)))
322
264;; `default-toplevel-value' has been declared in Emacs 24. 323;; `default-toplevel-value' has been declared in Emacs 24.
265(unless (fboundp 'default-toplevel-value) 324(unless (fboundp 'default-toplevel-value)
266 (defalias 'default-toplevel-value 'symbol-value)) 325 (defalias 'default-toplevel-value 'symbol-value))
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 398fc87870c..6f1c01362ac 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -754,7 +754,8 @@ file names."
754 (with-parsed-tramp-file-name directory nil 754 (with-parsed-tramp-file-name directory nil
755 (if (and recursive (not (file-symlink-p directory))) 755 (if (and recursive (not (file-symlink-p directory)))
756 (mapc (lambda (file) 756 (mapc (lambda (file)
757 (if (eq t (car (file-attributes file))) 757 (if (eq t (tramp-compat-file-attribute-type
758 (file-attributes file)))
758 (tramp-compat-delete-directory file recursive trash) 759 (tramp-compat-delete-directory file recursive trash)
759 (tramp-compat-delete-file file trash))) 760 (tramp-compat-delete-file file trash)))
760 (directory-files 761 (directory-files
@@ -1017,7 +1018,8 @@ file names."
1017 1018
1018(defun tramp-gvfs-handle-file-directory-p (filename) 1019(defun tramp-gvfs-handle-file-directory-p (filename)
1019 "Like `file-directory-p' for Tramp files." 1020 "Like `file-directory-p' for Tramp files."
1020 (eq t (car (file-attributes (file-truename filename))))) 1021 (eq t (tramp-compat-file-attribute-type
1022 (file-attributes (file-truename filename)))))
1021 1023
1022(defun tramp-gvfs-handle-file-executable-p (filename) 1024(defun tramp-gvfs-handle-file-executable-p (filename)
1023 "Like `file-executable-p' for Tramp files." 1025 "Like `file-executable-p' for Tramp files."
@@ -1214,7 +1216,9 @@ file-notify events."
1214 1216
1215 ;; Set file modification time. 1217 ;; Set file modification time.
1216 (when (or (eq visit t) (stringp visit)) 1218 (when (or (eq visit t) (stringp visit))
1217 (set-visited-file-modtime (nth 5 (file-attributes filename)))) 1219 (set-visited-file-modtime
1220 (tramp-compat-file-attribute-modification-time
1221 (file-attributes filename))))
1218 1222
1219 ;; The end. 1223 ;; The end.
1220 (when (or (eq visit t) (null visit) (stringp visit)) 1224 (when (or (eq visit t) (null visit) (stringp visit))
@@ -1589,9 +1593,9 @@ ID-FORMAT valid values are `string' and `integer'."
1589 (cond 1593 (cond
1590 ((and user (equal id-format 'string)) user) 1594 ((and user (equal id-format 'string)) user)
1591 (localname 1595 (localname
1592 (nth 2 (file-attributes 1596 (tramp-compat-file-attribute-user-id
1593 (tramp-make-tramp-file-name method user host localname) 1597 (file-attributes
1594 id-format))) 1598 (tramp-make-tramp-file-name method user host localname) id-format)))
1595 ((equal id-format 'integer) tramp-unknown-id-integer) 1599 ((equal id-format 'integer) tramp-unknown-id-integer)
1596 ((equal id-format 'string) tramp-unknown-id-string))))) 1600 ((equal id-format 'string) tramp-unknown-id-string)))))
1597 1601
@@ -1606,9 +1610,9 @@ ID-FORMAT valid values are `string' and `integer'."
1606 (tramp-get-connection-property vec "default-location" nil))) 1610 (tramp-get-connection-property vec "default-location" nil)))
1607 (cond 1611 (cond
1608 (localname 1612 (localname
1609 (nth 3 (file-attributes 1613 (tramp-compat-file-attribute-group-id
1610 (tramp-make-tramp-file-name method user host localname) 1614 (file-attributes
1611 id-format))) 1615 (tramp-make-tramp-file-name method user host localname) id-format)))
1612 ((equal id-format 'integer) tramp-unknown-id-integer) 1616 ((equal id-format 'integer) tramp-unknown-id-integer)
1613 ((equal id-format 'string) tramp-unknown-id-string))))) 1617 ((equal id-format 'string) tramp-unknown-id-string)))))
1614 1618
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 61d853f111e..b6aa3a7c619 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1190,14 +1190,15 @@ target of the symlink differ."
1190 (append '("") (reverse result) (list thisstep)) 1190 (append '("") (reverse result) (list thisstep))
1191 "/")) 1191 "/"))
1192 (setq symlink-target 1192 (setq symlink-target
1193 (nth 0 (file-attributes 1193 (tramp-compat-file-attribute-type
1194 (tramp-make-tramp-file-name 1194 (file-attributes
1195 method user host 1195 (tramp-make-tramp-file-name
1196 (mapconcat 'identity 1196 method user host
1197 (append '("") 1197 (mapconcat 'identity
1198 (reverse result) 1198 (append '("")
1199 (list thisstep)) 1199 (reverse result)
1200 "/"))))) 1200 (list thisstep))
1201 "/")))))
1201 (cond ((string= "." thisstep) 1202 (cond ((string= "." thisstep)
1202 (tramp-message v 5 "Ignoring step `.'")) 1203 (tramp-message v 5 "Ignoring step `.'"))
1203 ((string= ".." thisstep) 1204 ((string= ".." thisstep)
@@ -1448,7 +1449,8 @@ target of the symlink differ."
1448 (let* ((remote-file-name-inhibit-cache t) 1449 (let* ((remote-file-name-inhibit-cache t)
1449 (attr (file-attributes f)) 1450 (attr (file-attributes f))
1450 ;; '(-1 65535) means file doesn't exists yet. 1451 ;; '(-1 65535) means file doesn't exists yet.
1451 (modtime (or (nth 5 attr) '(-1 65535)))) 1452 (modtime (or (tramp-compat-file-attribute-modification-time attr)
1453 '(-1 65535))))
1452 (setq coding-system-used last-coding-system-used) 1454 (setq coding-system-used last-coding-system-used)
1453 ;; We use '(0 0) as a don't-know value. See also 1455 ;; We use '(0 0) as a don't-know value. See also
1454 ;; `tramp-do-file-attributes-with-ls'. 1456 ;; `tramp-do-file-attributes-with-ls'.
@@ -1487,7 +1489,7 @@ of."
1487 (with-parsed-tramp-file-name f nil 1489 (with-parsed-tramp-file-name f nil
1488 (let* ((remote-file-name-inhibit-cache t) 1490 (let* ((remote-file-name-inhibit-cache t)
1489 (attr (file-attributes f)) 1491 (attr (file-attributes f))
1490 (modtime (nth 5 attr)) 1492 (modtime (tramp-compat-file-attribute-modification-time attr))
1491 (mt (visited-file-modtime))) 1493 (mt (visited-file-modtime)))
1492 1494
1493 (cond 1495 (cond
@@ -1711,9 +1713,16 @@ be non-negative integers."
1711 ;; and obtain the result. 1713 ;; and obtain the result.
1712 (let ((fa1 (file-attributes file1)) 1714 (let ((fa1 (file-attributes file1))
1713 (fa2 (file-attributes file2))) 1715 (fa2 (file-attributes file2)))
1714 (if (and (not (equal (nth 5 fa1) '(0 0))) 1716 (if (and
1715 (not (equal (nth 5 fa2) '(0 0)))) 1717 (not
1716 (> 0 (tramp-time-diff (nth 5 fa2) (nth 5 fa1))) 1718 (equal (tramp-compat-file-attribute-modification-time fa1)
1719 '(0 0)))
1720 (not
1721 (equal (tramp-compat-file-attribute-modification-time fa2)
1722 '(0 0))))
1723 (> 0 (tramp-time-diff
1724 (tramp-compat-file-attribute-modification-time fa2)
1725 (tramp-compat-file-attribute-modification-time fa1)))
1717 ;; If one of them is the dont-know value, then we can 1726 ;; If one of them is the dont-know value, then we can
1718 ;; still try to run a shell command on the remote host. 1727 ;; still try to run a shell command on the remote host.
1719 ;; However, this only works if both files are Tramp 1728 ;; However, this only works if both files are Tramp
@@ -1765,9 +1774,11 @@ be non-negative integers."
1765 ;; information would be lost by an (attempted) delete and create. 1774 ;; information would be lost by an (attempted) delete and create.
1766 (or (null attributes) 1775 (or (null attributes)
1767 (and 1776 (and
1768 (= (nth 2 attributes) (tramp-get-remote-uid v 'integer)) 1777 (= (tramp-compat-file-attribute-user-id attributes)
1778 (tramp-get-remote-uid v 'integer))
1769 (or (not group) 1779 (or (not group)
1770 (= (nth 3 attributes) (tramp-get-remote-gid v 'integer))))))))) 1780 (= (tramp-compat-file-attribute-group-id attributes)
1781 (tramp-get-remote-gid v 'integer)))))))))
1771 1782
1772;; Directory listings. 1783;; Directory listings.
1773 1784
@@ -2066,7 +2077,8 @@ file names."
2066 (error "Unknown operation `%s', must be `copy' or `rename'" op)) 2077 (error "Unknown operation `%s', must be `copy' or `rename'" op))
2067 (let ((t1 (tramp-tramp-file-p filename)) 2078 (let ((t1 (tramp-tramp-file-p filename))
2068 (t2 (tramp-tramp-file-p newname)) 2079 (t2 (tramp-tramp-file-p newname))
2069 (length (nth 7 (file-attributes (file-truename filename)))) 2080 (length (tramp-compat-file-attribute-size
2081 (file-attributes (file-truename filename))))
2070 (attributes (and preserve-extended-attributes 2082 (attributes (and preserve-extended-attributes
2071 (apply 'file-extended-attributes (list filename))))) 2083 (apply 'file-extended-attributes (list filename)))))
2072 2084
@@ -2177,7 +2189,11 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
2177 (set-buffer-multibyte nil) 2189 (set-buffer-multibyte nil)
2178 (insert-file-contents-literally filename))) 2190 (insert-file-contents-literally filename)))
2179 ;; KEEP-DATE handling. 2191 ;; KEEP-DATE handling.
2180 (when keep-date (set-file-times newname (nth 5 (file-attributes filename)))) 2192 (when keep-date
2193 (set-file-times
2194 newname
2195 (tramp-compat-file-attribute-modification-time
2196 (file-attributes filename))))
2181 ;; Set the mode. 2197 ;; Set the mode.
2182 (set-file-modes newname (tramp-default-file-modes filename)) 2198 (set-file-modes newname (tramp-default-file-modes filename))
2183 ;; If the operation was `rename', delete the original file. 2199 ;; If the operation was `rename', delete the original file.
@@ -2195,7 +2211,8 @@ as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
2195the uid and gid from FILENAME." 2211the uid and gid from FILENAME."
2196 (let ((t1 (tramp-tramp-file-p filename)) 2212 (let ((t1 (tramp-tramp-file-p filename))
2197 (t2 (tramp-tramp-file-p newname)) 2213 (t2 (tramp-tramp-file-p newname))
2198 (file-times (nth 5 (file-attributes filename))) 2214 (file-times (tramp-compat-file-attribute-modification-time
2215 (file-attributes filename)))
2199 (file-modes (tramp-default-file-modes filename))) 2216 (file-modes (tramp-default-file-modes filename)))
2200 (with-parsed-tramp-file-name (if t1 filename newname) nil 2217 (with-parsed-tramp-file-name (if t1 filename newname) nil
2201 (let* ((cmd (cond ((and (eq op 'copy) preserve-uid-gid) "cp -f -p") 2218 (let* ((cmd (cond ((and (eq op 'copy) preserve-uid-gid) "cp -f -p")
@@ -2559,7 +2576,10 @@ The method used must be an out-of-band method."
2559 2576
2560 ;; Handle KEEP-DATE argument. 2577 ;; Handle KEEP-DATE argument.
2561 (when (and keep-date (not copy-keep-date)) 2578 (when (and keep-date (not copy-keep-date))
2562 (set-file-times newname (nth 5 (file-attributes filename)))) 2579 (set-file-times
2580 newname
2581 (tramp-compat-file-attribute-modification-time
2582 (file-attributes filename))))
2563 2583
2564 ;; Set the mode. 2584 ;; Set the mode.
2565 (unless (and keep-date copy-keep-date) 2585 (unless (and keep-date copy-keep-date)
@@ -3114,7 +3134,8 @@ the result will be a local, non-Tramp, file name."
3114 v 'file-error 3134 v 'file-error
3115 "Cannot make local copy of non-existing file `%s'" filename)) 3135 "Cannot make local copy of non-existing file `%s'" filename))
3116 3136
3117 (let* ((size (nth 7 (file-attributes (file-truename filename)))) 3137 (let* ((size (tramp-compat-file-attribute-size
3138 (file-attributes (file-truename filename))))
3118 (rem-enc (tramp-get-inline-coding v "remote-encoding" size)) 3139 (rem-enc (tramp-get-inline-coding v "remote-encoding" size))
3119 (loc-dec (tramp-get-inline-coding v "local-decoding" size)) 3140 (loc-dec (tramp-get-inline-coding v "local-decoding" size))
3120 (tmpfile (tramp-compat-make-temp-file filename))) 3141 (tmpfile (tramp-compat-make-temp-file filename)))
@@ -3205,9 +3226,11 @@ the result will be a local, non-Tramp, file name."
3205 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) 3226 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
3206 (tramp-error v 'file-error "File not overwritten"))) 3227 (tramp-error v 'file-error "File not overwritten")))
3207 3228
3208 (let ((uid (or (nth 2 (file-attributes filename 'integer)) 3229 (let ((uid (or (tramp-compat-file-attribute-user-id
3230 (file-attributes filename 'integer))
3209 (tramp-get-remote-uid v 'integer))) 3231 (tramp-get-remote-uid v 'integer)))
3210 (gid (or (nth 3 (file-attributes filename 'integer)) 3232 (gid (or (tramp-compat-file-attribute-group-id
3233 (file-attributes filename 'integer))
3211 (tramp-get-remote-gid v 'integer)))) 3234 (tramp-get-remote-gid v 'integer))))
3212 3235
3213 (if (and (tramp-local-host-p v) 3236 (if (and (tramp-local-host-p v)
@@ -3284,7 +3307,8 @@ the result will be a local, non-Tramp, file name."
3284 ;; specified. However, if the method _also_ specifies an 3307 ;; specified. However, if the method _also_ specifies an
3285 ;; encoding function, then that is used for encoding the 3308 ;; encoding function, then that is used for encoding the
3286 ;; contents of the tmp file. 3309 ;; contents of the tmp file.
3287 (let* ((size (nth 7 (file-attributes tmpfile))) 3310 (let* ((size (tramp-compat-file-attribute-size
3311 (file-attributes tmpfile)))
3288 (rem-dec (tramp-get-inline-coding v "remote-decoding" size)) 3312 (rem-dec (tramp-get-inline-coding v "remote-decoding" size))
3289 (loc-enc (tramp-get-inline-coding v "local-encoding" size))) 3313 (loc-enc (tramp-get-inline-coding v "local-encoding" size)))
3290 (cond 3314 (cond
@@ -3420,9 +3444,9 @@ the result will be a local, non-Tramp, file name."
3420 ;; We must pass modtime explicitly, because FILENAME can 3444 ;; We must pass modtime explicitly, because FILENAME can
3421 ;; be different from (buffer-file-name), f.e. if 3445 ;; be different from (buffer-file-name), f.e. if
3422 ;; `file-precious-flag' is set. 3446 ;; `file-precious-flag' is set.
3423 (nth 5 file-attr)) 3447 (tramp-compat-file-attribute-modification-time file-attr))
3424 (when (and (= (nth 2 file-attr) uid) 3448 (when (and (= (tramp-compat-file-attribute-user-id file-attr) uid)
3425 (= (nth 3 file-attr) gid)) 3449 (= (tramp-compat-file-attribute-group-id file-attr) gid))
3426 (setq need-chown nil)))) 3450 (setq need-chown nil))))
3427 3451
3428 ;; Set the ownership. 3452 ;; Set the ownership.
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 05ce6041a8b..3b9c49eb26e 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -531,7 +531,10 @@ pass to the OPERATION."
531 531
532 ;; Handle KEEP-DATE argument. 532 ;; Handle KEEP-DATE argument.
533 (when keep-date 533 (when keep-date
534 (set-file-times newname (nth 5 (file-attributes dirname)))) 534 (set-file-times
535 newname
536 (tramp-compat-file-attribute-modification-time
537 (file-attributes dirname))))
535 538
536 ;; Set the mode. 539 ;; Set the mode.
537 (unless keep-date 540 (unless keep-date
@@ -599,7 +602,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
599 602
600 ;; KEEP-DATE handling. 603 ;; KEEP-DATE handling.
601 (when keep-date 604 (when keep-date
602 (set-file-times newname (nth 5 (file-attributes filename)))))) 605 (set-file-times
606 newname
607 (tramp-compat-file-attribute-modification-time
608 (file-attributes filename))))))
603 609
604(defun tramp-smb-handle-delete-directory (directory &optional recursive) 610(defun tramp-smb-handle-delete-directory (directory &optional recursive)
605 "Like `delete-directory' for Tramp files." 611 "Like `delete-directory' for Tramp files."
@@ -887,7 +893,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
887(defun tramp-smb-handle-file-directory-p (filename) 893(defun tramp-smb-handle-file-directory-p (filename)
888 "Like `file-directory-p' for Tramp files." 894 "Like `file-directory-p' for Tramp files."
889 (and (file-exists-p filename) 895 (and (file-exists-p filename)
890 (eq ?d (aref (nth 8 (file-attributes filename)) 0)))) 896 (eq ?d
897 (aref (tramp-compat-file-attribute-modes (file-attributes filename))
898 0))))
891 899
892(defun tramp-smb-handle-file-local-copy (filename) 900(defun tramp-smb-handle-file-local-copy (filename)
893 "Like `file-local-copy' for Tramp files." 901 "Like `file-local-copy' for Tramp files."
@@ -929,7 +937,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
929(defun tramp-smb-handle-file-writable-p (filename) 937(defun tramp-smb-handle-file-writable-p (filename)
930 "Like `file-writable-p' for Tramp files." 938 "Like `file-writable-p' for Tramp files."
931 (if (file-exists-p filename) 939 (if (file-exists-p filename)
932 (string-match "w" (or (nth 8 (file-attributes filename)) "")) 940 (string-match
941 "w"
942 (or (tramp-compat-file-attribute-modes (file-attributes filename)) ""))
933 (let ((dir (file-name-directory filename))) 943 (let ((dir (file-name-directory filename)))
934 (and (file-exists-p dir) 944 (and (file-exists-p dir)
935 (file-writable-p dir))))) 945 (file-writable-p dir)))))
@@ -1014,11 +1024,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
1014 (insert 1024 (insert
1015 (format 1025 (format
1016 "%10s %3d %-8s %-8s %8s %s " 1026 "%10s %3d %-8s %-8s %8s %s "
1017 (or (nth 8 attr) (nth 1 x)) ; mode 1027 (or (tramp-compat-file-attribute-modes attr) (nth 1 x))
1018 (or (nth 1 attr) 1) ; inode 1028 (or (tramp-compat-file-attribute-link-number attr) 1)
1019 (or (nth 2 attr) "nobody") ; uid 1029 (or (tramp-compat-file-attribute-user-id attr) "nobody")
1020 (or (nth 3 attr) "nogroup") ; gid 1030 (or (tramp-compat-file-attribute-group-id attr) "nogroup")
1021 (or (nth 7 attr) (nth 2 x)) ; size 1031 (or (tramp-compat-file-attribute-size attr) (nth 2 x))
1022 (format-time-string 1032 (format-time-string
1023 (if (time-less-p (time-subtract (current-time) (nth 3 x)) 1033 (if (time-less-p (time-subtract (current-time) (nth 3 x))
1024 tramp-half-a-year) 1034 tramp-half-a-year)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 4e9d4c29cd4..ad00f31010f 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2856,7 +2856,8 @@ User is always nil."
2856 "Like `file-modes' for Tramp files." 2856 "Like `file-modes' for Tramp files."
2857 (let ((truename (or (file-truename filename) filename))) 2857 (let ((truename (or (file-truename filename) filename)))
2858 (when (file-exists-p truename) 2858 (when (file-exists-p truename)
2859 (tramp-mode-string-to-int (nth 8 (file-attributes truename)))))) 2859 (tramp-mode-string-to-int
2860 (tramp-compat-file-attribute-modes (file-attributes truename))))))
2860 2861
2861;; Localname manipulation functions that grok Tramp localnames... 2862;; Localname manipulation functions that grok Tramp localnames...
2862(defun tramp-handle-file-name-as-directory (file) 2863(defun tramp-handle-file-name-as-directory (file)
@@ -2926,13 +2927,17 @@ User is always nil."
2926 (cond 2927 (cond
2927 ((not (file-exists-p file1)) nil) 2928 ((not (file-exists-p file1)) nil)
2928 ((not (file-exists-p file2)) t) 2929 ((not (file-exists-p file2)) t)
2929 (t (time-less-p (nth 5 (file-attributes file2)) 2930 (t (time-less-p (tramp-compat-file-attribute-modification-time
2930 (nth 5 (file-attributes file1)))))) 2931 (file-attributes file2))
2932 (tramp-compat-file-attribute-modification-time
2933 (file-attributes file1))))))
2931 2934
2932(defun tramp-handle-file-regular-p (filename) 2935(defun tramp-handle-file-regular-p (filename)
2933 "Like `file-regular-p' for Tramp files." 2936 "Like `file-regular-p' for Tramp files."
2934 (and (file-exists-p filename) 2937 (and (file-exists-p filename)
2935 (eq ?- (aref (nth 8 (file-attributes filename)) 0)))) 2938 (eq ?-
2939 (aref (tramp-compat-file-attribute-modes (file-attributes filename))
2940 0))))
2936 2941
2937(defun tramp-handle-file-remote-p (filename &optional identification connected) 2942(defun tramp-handle-file-remote-p (filename &optional identification connected)
2938 "Like `file-remote-p' for Tramp files." 2943 "Like `file-remote-p' for Tramp files."
@@ -2958,7 +2963,7 @@ User is always nil."
2958(defun tramp-handle-file-symlink-p (filename) 2963(defun tramp-handle-file-symlink-p (filename)
2959 "Like `file-symlink-p' for Tramp files." 2964 "Like `file-symlink-p' for Tramp files."
2960 (with-parsed-tramp-file-name filename nil 2965 (with-parsed-tramp-file-name filename nil
2961 (let ((x (car (file-attributes filename)))) 2966 (let ((x (tramp-compat-file-attribute-type (file-attributes filename))))
2962 (when (stringp x) 2967 (when (stringp x)
2963 (if (file-name-absolute-p x) 2968 (if (file-name-absolute-p x)
2964 (tramp-make-tramp-file-name method user host x) 2969 (tramp-make-tramp-file-name method user host x)
@@ -3279,7 +3284,9 @@ User is always nil."
3279 (let ((remote-file-name-inhibit-cache t)) 3284 (let ((remote-file-name-inhibit-cache t))
3280 ;; '(-1 65535) means file doesn't exists yet. 3285 ;; '(-1 65535) means file doesn't exists yet.
3281 (setq time-list 3286 (setq time-list
3282 (or (nth 5 (file-attributes (buffer-file-name))) '(-1 65535))))) 3287 (or (tramp-compat-file-attribute-modification-time
3288 (file-attributes (buffer-file-name)))
3289 '(-1 65535)))))
3283 ;; We use '(0 0) as a don't-know value. 3290 ;; We use '(0 0) as a don't-know value.
3284 (unless (equal time-list '(0 0)) 3291 (unless (equal time-list '(0 0))
3285 (tramp-run-real-handler 'set-visited-file-modtime (list time-list)))) 3292 (tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
@@ -3303,7 +3310,7 @@ of."
3303 (with-parsed-tramp-file-name f nil 3310 (with-parsed-tramp-file-name f nil
3304 (let* ((remote-file-name-inhibit-cache t) 3311 (let* ((remote-file-name-inhibit-cache t)
3305 (attr (file-attributes f)) 3312 (attr (file-attributes f))
3306 (modtime (nth 5 attr)) 3313 (modtime (tramp-compat-file-attribute-modification-time attr))
3307 (mt (visited-file-modtime))) 3314 (mt (visited-file-modtime)))
3308 3315
3309 (cond 3316 (cond
@@ -3820,7 +3827,7 @@ ID-FORMAT valid values are `string' and `integer'."
3820 ;; `group-gid' has been introduced with Emacs 24.4. 3827 ;; `group-gid' has been introduced with Emacs 24.4.
3821 (if (and (fboundp 'group-gid) (equal id-format 'integer)) 3828 (if (and (fboundp 'group-gid) (equal id-format 'integer))
3822 (tramp-compat-funcall 'group-gid) 3829 (tramp-compat-funcall 'group-gid)
3823 (nth 3 (file-attributes "~/" id-format)))) 3830 (tramp-compat-file-attribute-group-id (file-attributes "~/" id-format))))
3824 3831
3825(defun tramp-get-local-locale (&optional vec) 3832(defun tramp-get-local-locale (&optional vec)
3826 "Determine locale, supporting UTF8 if possible. 3833 "Determine locale, supporting UTF8 if possible.
@@ -3884,23 +3891,32 @@ be granted."
3884 (and 3891 (and
3885 file-attr 3892 file-attr
3886 (or 3893 (or
3887 ;; Not a symlink 3894 ;; Not a symlink.
3888 (eq t (car file-attr)) 3895 (eq t (tramp-compat-file-attribute-type file-attr))
3889 (null (car file-attr))) 3896 (null (tramp-compat-file-attribute-type file-attr)))
3890 (or 3897 (or
3891 ;; World accessible. 3898 ;; World accessible.
3892 (eq access (aref (nth 8 file-attr) (+ offset 6))) 3899 (eq access
3900 (aref (tramp-compat-file-attribute-modes file-attr)
3901 (+ offset 6)))
3893 ;; User accessible and owned by user. 3902 ;; User accessible and owned by user.
3894 (and 3903 (and
3895 (eq access (aref (nth 8 file-attr) offset)) 3904 (eq access
3896 (or (equal remote-uid (nth 2 file-attr)) 3905 (aref (tramp-compat-file-attribute-modes file-attr) offset))
3897 (equal unknown-id (nth 2 file-attr)))) 3906 (or (equal remote-uid
3898 ;; Group accessible and owned by user's 3907 (tramp-compat-file-attribute-user-id file-attr))
3899 ;; principal group. 3908 (equal unknown-id
3909 (tramp-compat-file-attribute-user-id file-attr))))
3910 ;; Group accessible and owned by user's principal group.
3900 (and 3911 (and
3901 (eq access (aref (nth 8 file-attr) (+ offset 3))) 3912 (eq access
3902 (or (equal remote-gid (nth 3 file-attr)) 3913 (aref (tramp-compat-file-attribute-modes file-attr)
3903 (equal unknown-id (nth 3 file-attr)))))))))))) 3914 (+ offset 3)))
3915 (or (equal remote-gid
3916 (tramp-compat-file-attribute-group-id file-attr))
3917 (equal unknown-id
3918 (tramp-compat-file-attribute-group-id
3919 file-attr))))))))))))
3904 3920
3905;;;###tramp-autoload 3921;;;###tramp-autoload
3906(defun tramp-local-host-p (vec) 3922(defun tramp-local-host-p (vec)