(defun tramp-adb-handle-file-directory-p (filename)
"Like `file-directory-p' for Tramp files."
- (car (file-attributes (file-truename filename))))
+ (eq (tramp-compat-file-attribute-type
+ (file-attributes (file-truename filename)))
+ t))
;; This is derived from `tramp-sh-handle-file-truename'. Maybe the
;; code could be shared?
(append '("") (reverse result) (list thisstep))
"/"))
(setq symlink-target
- (nth 0 (file-attributes
- (tramp-make-tramp-file-name
- method user host
- (mapconcat 'identity
- (append '("")
- (reverse result)
- (list thisstep))
- "/")))))
+ (tramp-compat-file-attribute-type
+ (file-attributes
+ (tramp-make-tramp-file-name
+ method user host
+ (mapconcat 'identity
+ (append '("")
+ (reverse result)
+ (list thisstep))
+ "/")))))
(cond ((string= "." thisstep)
(tramp-message v 5 "Ignoring step `.'"))
((string= ".." thisstep)
;; KEEP-DATE handling.
(when keep-date
- (set-file-times newname (nth 5 (file-attributes filename))))))
+ (set-file-times
+ newname
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes filename))))))
(defun tramp-adb-handle-rename-file
(filename newname &optional ok-if-already-exists)
(memq (process-status process)
'(run open listen connect stop))))))
+;; `file-attribute-*' are introduced in Emacs 25.1.
+
+(if (fboundp 'file-attribute-type)
+ (defalias 'tramp-compat-file-attribute-type 'file-attribute-type)
+ (defsubst tramp-compat-file-attribute-type (attributes)
+ "The type field in ATTRIBUTES returned by `file-attributes'.
+The value is either t for directory, string (name linked to) for
+symbolic link, or nil."
+ (nth 0 attributes)))
+
+(if (fboundp 'file-attribute-link-number)
+ (defalias 'tramp-compat-file-attribute-link-number
+ 'file-attribute-link-number)
+ (defsubst tramp-compat-file-attribute-link-number (attributes)
+ "Return the number of links in ATTRIBUTES returned by `file-attributes'."
+ (nth 1 attributes)))
+
+(if (fboundp 'file-attribute-user-id)
+ (defalias 'tramp-compat-file-attribute-user-id 'file-attribute-user-id)
+ (defsubst tramp-compat-file-attribute-user-id (attributes)
+ "The UID field in ATTRIBUTES returned by `file-attributes'.
+This is either a string or a number. If a string value cannot be
+looked up, a numeric value, either an integer or a float, is
+returned."
+ (nth 2 attributes)))
+
+(if (fboundp 'file-attribute-group-id)
+ (defalias 'tramp-compat-file-attribute-group-id 'file-attribute-group-id)
+ (defsubst tramp-compat-file-attribute-group-id (attributes)
+ "The GID field in ATTRIBUTES returned by `file-attributes'.
+This is either a string or a number. If a string value cannot be
+looked up, a numeric value, either an integer or a float, is
+returned."
+ (nth 3 attributes)))
+
+(if (fboundp 'file-attribute-modification-time)
+ (defalias 'tramp-compat-file-attribute-modification-time
+ 'file-attribute-modification-time)
+ (defsubst tramp-compat-file-attribute-modification-time (attributes)
+ "The modification time in ATTRIBUTES returned by `file-attributes'.
+This is the time of the last change to the file's contents, and
+is a list of integers (HIGH LOW USEC PSEC) in the same style
+as (current-time)."
+ (nth 5 attributes)))
+
+(if (fboundp 'file-attribute-size)
+ (defalias 'tramp-compat-file-attribute-size 'file-attribute-size)
+ (defsubst tramp-compat-file-attribute-size (attributes)
+ "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
+This is a floating point number if the size is too large for an integer."
+ (nth 7 attributes)))
+
+(if (fboundp 'file-attribute-modes)
+ (defalias 'tramp-compat-file-attribute-modes 'file-attribute-modes)
+ (defsubst tramp-compat-file-attribute-modes (attributes)
+ "The file modes in ATTRIBUTES returned by `file-attributes'.
+This is a string of ten letters or dashes as in ls -l."
+ (nth 8 attributes)))
+
;; `default-toplevel-value' has been declared in Emacs 24.
(unless (fboundp 'default-toplevel-value)
(defalias 'default-toplevel-value 'symbol-value))
(with-parsed-tramp-file-name directory nil
(if (and recursive (not (file-symlink-p directory)))
(mapc (lambda (file)
- (if (eq t (car (file-attributes file)))
+ (if (eq t (tramp-compat-file-attribute-type
+ (file-attributes file)))
(tramp-compat-delete-directory file recursive trash)
(tramp-compat-delete-file file trash)))
(directory-files
(defun tramp-gvfs-handle-file-directory-p (filename)
"Like `file-directory-p' for Tramp files."
- (eq t (car (file-attributes (file-truename filename)))))
+ (eq t (tramp-compat-file-attribute-type
+ (file-attributes (file-truename filename)))))
(defun tramp-gvfs-handle-file-executable-p (filename)
"Like `file-executable-p' for Tramp files."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
- (set-visited-file-modtime (nth 5 (file-attributes filename))))
+ (set-visited-file-modtime
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes filename))))
;; The end.
(when (or (eq visit t) (null visit) (stringp visit))
(cond
((and user (equal id-format 'string)) user)
(localname
- (nth 2 (file-attributes
- (tramp-make-tramp-file-name method user host localname)
- id-format)))
+ (tramp-compat-file-attribute-user-id
+ (file-attributes
+ (tramp-make-tramp-file-name method user host localname) id-format)))
((equal id-format 'integer) tramp-unknown-id-integer)
((equal id-format 'string) tramp-unknown-id-string)))))
(tramp-get-connection-property vec "default-location" nil)))
(cond
(localname
- (nth 3 (file-attributes
- (tramp-make-tramp-file-name method user host localname)
- id-format)))
+ (tramp-compat-file-attribute-group-id
+ (file-attributes
+ (tramp-make-tramp-file-name method user host localname) id-format)))
((equal id-format 'integer) tramp-unknown-id-integer)
((equal id-format 'string) tramp-unknown-id-string)))))
(append '("") (reverse result) (list thisstep))
"/"))
(setq symlink-target
- (nth 0 (file-attributes
- (tramp-make-tramp-file-name
- method user host
- (mapconcat 'identity
- (append '("")
- (reverse result)
- (list thisstep))
- "/")))))
+ (tramp-compat-file-attribute-type
+ (file-attributes
+ (tramp-make-tramp-file-name
+ method user host
+ (mapconcat 'identity
+ (append '("")
+ (reverse result)
+ (list thisstep))
+ "/")))))
(cond ((string= "." thisstep)
(tramp-message v 5 "Ignoring step `.'"))
((string= ".." thisstep)
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
;; '(-1 65535) means file doesn't exists yet.
- (modtime (or (nth 5 attr) '(-1 65535))))
+ (modtime (or (tramp-compat-file-attribute-modification-time attr)
+ '(-1 65535))))
(setq coding-system-used last-coding-system-used)
;; We use '(0 0) as a don't-know value. See also
;; `tramp-do-file-attributes-with-ls'.
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
- (modtime (nth 5 attr))
+ (modtime (tramp-compat-file-attribute-modification-time attr))
(mt (visited-file-modtime)))
(cond
;; and obtain the result.
(let ((fa1 (file-attributes file1))
(fa2 (file-attributes file2)))
- (if (and (not (equal (nth 5 fa1) '(0 0)))
- (not (equal (nth 5 fa2) '(0 0))))
- (> 0 (tramp-time-diff (nth 5 fa2) (nth 5 fa1)))
+ (if (and
+ (not
+ (equal (tramp-compat-file-attribute-modification-time fa1)
+ '(0 0)))
+ (not
+ (equal (tramp-compat-file-attribute-modification-time fa2)
+ '(0 0))))
+ (> 0 (tramp-time-diff
+ (tramp-compat-file-attribute-modification-time fa2)
+ (tramp-compat-file-attribute-modification-time fa1)))
;; If one of them is the dont-know value, then we can
;; still try to run a shell command on the remote host.
;; However, this only works if both files are Tramp
;; information would be lost by an (attempted) delete and create.
(or (null attributes)
(and
- (= (nth 2 attributes) (tramp-get-remote-uid v 'integer))
+ (= (tramp-compat-file-attribute-user-id attributes)
+ (tramp-get-remote-uid v 'integer))
(or (not group)
- (= (nth 3 attributes) (tramp-get-remote-gid v 'integer)))))))))
+ (= (tramp-compat-file-attribute-group-id attributes)
+ (tramp-get-remote-gid v 'integer)))))))))
;; Directory listings.
(error "Unknown operation `%s', must be `copy' or `rename'" op))
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
- (length (nth 7 (file-attributes (file-truename filename))))
+ (length (tramp-compat-file-attribute-size
+ (file-attributes (file-truename filename))))
(attributes (and preserve-extended-attributes
(apply 'file-extended-attributes (list filename)))))
(set-buffer-multibyte nil)
(insert-file-contents-literally filename)))
;; KEEP-DATE handling.
- (when keep-date (set-file-times newname (nth 5 (file-attributes filename))))
+ (when keep-date
+ (set-file-times
+ newname
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes filename))))
;; Set the mode.
(set-file-modes newname (tramp-default-file-modes filename))
;; If the operation was `rename', delete the original file.
the uid and gid from FILENAME."
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
- (file-times (nth 5 (file-attributes filename)))
+ (file-times (tramp-compat-file-attribute-modification-time
+ (file-attributes filename)))
(file-modes (tramp-default-file-modes filename)))
(with-parsed-tramp-file-name (if t1 filename newname) nil
(let* ((cmd (cond ((and (eq op 'copy) preserve-uid-gid) "cp -f -p")
;; Handle KEEP-DATE argument.
(when (and keep-date (not copy-keep-date))
- (set-file-times newname (nth 5 (file-attributes filename))))
+ (set-file-times
+ newname
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes filename))))
;; Set the mode.
(unless (and keep-date copy-keep-date)
v 'file-error
"Cannot make local copy of non-existing file `%s'" filename))
- (let* ((size (nth 7 (file-attributes (file-truename filename))))
+ (let* ((size (tramp-compat-file-attribute-size
+ (file-attributes (file-truename filename))))
(rem-enc (tramp-get-inline-coding v "remote-encoding" size))
(loc-dec (tramp-get-inline-coding v "local-decoding" size))
(tmpfile (tramp-compat-make-temp-file filename)))
(unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
(tramp-error v 'file-error "File not overwritten")))
- (let ((uid (or (nth 2 (file-attributes filename 'integer))
+ (let ((uid (or (tramp-compat-file-attribute-user-id
+ (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
- (gid (or (nth 3 (file-attributes filename 'integer))
+ (gid (or (tramp-compat-file-attribute-group-id
+ (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer))))
(if (and (tramp-local-host-p v)
;; specified. However, if the method _also_ specifies an
;; encoding function, then that is used for encoding the
;; contents of the tmp file.
- (let* ((size (nth 7 (file-attributes tmpfile)))
+ (let* ((size (tramp-compat-file-attribute-size
+ (file-attributes tmpfile)))
(rem-dec (tramp-get-inline-coding v "remote-decoding" size))
(loc-enc (tramp-get-inline-coding v "local-encoding" size)))
(cond
;; We must pass modtime explicitly, because FILENAME can
;; be different from (buffer-file-name), f.e. if
;; `file-precious-flag' is set.
- (nth 5 file-attr))
- (when (and (= (nth 2 file-attr) uid)
- (= (nth 3 file-attr) gid))
+ (tramp-compat-file-attribute-modification-time file-attr))
+ (when (and (= (tramp-compat-file-attribute-user-id file-attr) uid)
+ (= (tramp-compat-file-attribute-group-id file-attr) gid))
(setq need-chown nil))))
;; Set the ownership.
;; Handle KEEP-DATE argument.
(when keep-date
- (set-file-times newname (nth 5 (file-attributes dirname))))
+ (set-file-times
+ newname
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes dirname))))
;; Set the mode.
(unless keep-date
;; KEEP-DATE handling.
(when keep-date
- (set-file-times newname (nth 5 (file-attributes filename))))))
+ (set-file-times
+ newname
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes filename))))))
(defun tramp-smb-handle-delete-directory (directory &optional recursive)
"Like `delete-directory' for Tramp files."
(defun tramp-smb-handle-file-directory-p (filename)
"Like `file-directory-p' for Tramp files."
(and (file-exists-p filename)
- (eq ?d (aref (nth 8 (file-attributes filename)) 0))))
+ (eq ?d
+ (aref (tramp-compat-file-attribute-modes (file-attributes filename))
+ 0))))
(defun tramp-smb-handle-file-local-copy (filename)
"Like `file-local-copy' for Tramp files."
(defun tramp-smb-handle-file-writable-p (filename)
"Like `file-writable-p' for Tramp files."
(if (file-exists-p filename)
- (string-match "w" (or (nth 8 (file-attributes filename)) ""))
+ (string-match
+ "w"
+ (or (tramp-compat-file-attribute-modes (file-attributes filename)) ""))
(let ((dir (file-name-directory filename)))
(and (file-exists-p dir)
(file-writable-p dir)))))
(insert
(format
"%10s %3d %-8s %-8s %8s %s "
- (or (nth 8 attr) (nth 1 x)) ; mode
- (or (nth 1 attr) 1) ; inode
- (or (nth 2 attr) "nobody") ; uid
- (or (nth 3 attr) "nogroup") ; gid
- (or (nth 7 attr) (nth 2 x)) ; size
+ (or (tramp-compat-file-attribute-modes attr) (nth 1 x))
+ (or (tramp-compat-file-attribute-link-number attr) 1)
+ (or (tramp-compat-file-attribute-user-id attr) "nobody")
+ (or (tramp-compat-file-attribute-group-id attr) "nogroup")
+ (or (tramp-compat-file-attribute-size attr) (nth 2 x))
(format-time-string
(if (time-less-p (time-subtract (current-time) (nth 3 x))
tramp-half-a-year)
"Like `file-modes' for Tramp files."
(let ((truename (or (file-truename filename) filename)))
(when (file-exists-p truename)
- (tramp-mode-string-to-int (nth 8 (file-attributes truename))))))
+ (tramp-mode-string-to-int
+ (tramp-compat-file-attribute-modes (file-attributes truename))))))
;; Localname manipulation functions that grok Tramp localnames...
(defun tramp-handle-file-name-as-directory (file)
(cond
((not (file-exists-p file1)) nil)
((not (file-exists-p file2)) t)
- (t (time-less-p (nth 5 (file-attributes file2))
- (nth 5 (file-attributes file1))))))
+ (t (time-less-p (tramp-compat-file-attribute-modification-time
+ (file-attributes file2))
+ (tramp-compat-file-attribute-modification-time
+ (file-attributes file1))))))
(defun tramp-handle-file-regular-p (filename)
"Like `file-regular-p' for Tramp files."
(and (file-exists-p filename)
- (eq ?- (aref (nth 8 (file-attributes filename)) 0))))
+ (eq ?-
+ (aref (tramp-compat-file-attribute-modes (file-attributes filename))
+ 0))))
(defun tramp-handle-file-remote-p (filename &optional identification connected)
"Like `file-remote-p' for Tramp files."
(defun tramp-handle-file-symlink-p (filename)
"Like `file-symlink-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
- (let ((x (car (file-attributes filename))))
+ (let ((x (tramp-compat-file-attribute-type (file-attributes filename))))
(when (stringp x)
(if (file-name-absolute-p x)
(tramp-make-tramp-file-name method user host x)
(let ((remote-file-name-inhibit-cache t))
;; '(-1 65535) means file doesn't exists yet.
(setq time-list
- (or (nth 5 (file-attributes (buffer-file-name))) '(-1 65535)))))
+ (or (tramp-compat-file-attribute-modification-time
+ (file-attributes (buffer-file-name)))
+ '(-1 65535)))))
;; We use '(0 0) as a don't-know value.
(unless (equal time-list '(0 0))
(tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
- (modtime (nth 5 attr))
+ (modtime (tramp-compat-file-attribute-modification-time attr))
(mt (visited-file-modtime)))
(cond
;; `group-gid' has been introduced with Emacs 24.4.
(if (and (fboundp 'group-gid) (equal id-format 'integer))
(tramp-compat-funcall 'group-gid)
- (nth 3 (file-attributes "~/" id-format))))
+ (tramp-compat-file-attribute-group-id (file-attributes "~/" id-format))))
(defun tramp-get-local-locale (&optional vec)
"Determine locale, supporting UTF8 if possible.
(and
file-attr
(or
- ;; Not a symlink
- (eq t (car file-attr))
- (null (car file-attr)))
+ ;; Not a symlink.
+ (eq t (tramp-compat-file-attribute-type file-attr))
+ (null (tramp-compat-file-attribute-type file-attr)))
(or
;; World accessible.
- (eq access (aref (nth 8 file-attr) (+ offset 6)))
+ (eq access
+ (aref (tramp-compat-file-attribute-modes file-attr)
+ (+ offset 6)))
;; User accessible and owned by user.
(and
- (eq access (aref (nth 8 file-attr) offset))
- (or (equal remote-uid (nth 2 file-attr))
- (equal unknown-id (nth 2 file-attr))))
- ;; Group accessible and owned by user's
- ;; principal group.
+ (eq access
+ (aref (tramp-compat-file-attribute-modes file-attr) offset))
+ (or (equal remote-uid
+ (tramp-compat-file-attribute-user-id file-attr))
+ (equal unknown-id
+ (tramp-compat-file-attribute-user-id file-attr))))
+ ;; Group accessible and owned by user's principal group.
(and
- (eq access (aref (nth 8 file-attr) (+ offset 3)))
- (or (equal remote-gid (nth 3 file-attr))
- (equal unknown-id (nth 3 file-attr))))))))))))
+ (eq access
+ (aref (tramp-compat-file-attribute-modes file-attr)
+ (+ offset 3)))
+ (or (equal remote-gid
+ (tramp-compat-file-attribute-group-id file-attr))
+ (equal unknown-id
+ (tramp-compat-file-attribute-group-id
+ file-attr))))))))))))
;;;###tramp-autoload
(defun tramp-local-host-p (vec)