Skip to content

Commit a1e2a68

Browse files
committed
Finish implementation of set-file-times FLAG arg in Tramp
* lisp/net/tramp-adb.el (tramp-adb-handle-set-file-times): Implement FLAG. (tramp-adb-handle-copy-file): Adapt `set-file-times' call. * lisp/net/tramp-compat.el (tramp-compat-set-file-times): New defalias. * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes) (tramp-gvfs-handle-set-file-times, tramp-gvfs-set-file-uid-gid): Simplify `tramp-gvfs-url-file-name' call. * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-times): Implement FLAG. (tramp-do-copy-or-rename-file-via-buffer) (tramp-do-copy-or-rename-file-out-of-band): Add optional argument OK-IF-ALREADY-EXISTS. Adapt callees. (tramp-do-copy-or-rename-file-via-buffer) (tramp-do-copy-or-rename-file-directly) (tramp-do-copy-or-rename-file-out-of-band): Adapt `set-file-times' call. * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory) (tramp-smb-handle-copy-file): Adapt `set-file-times' call. * lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file): Adapt `set-file-times' call. (tramp-sudoedit-handle-set-file-times): Implement FLAG. * test/lisp/net/tramp-tests.el (tramp-test22-file-times): Extend test.
1 parent a461baa commit a1e2a68

File tree

7 files changed

+65
-45
lines changed

7 files changed

+65
-45
lines changed

lisp/net/tramp-adb.el

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -676,29 +676,29 @@ But handle the case, if the \"test\" command is not available."
676676

677677
(defun tramp-adb-handle-set-file-times (filename &optional time flag)
678678
"Like `set-file-times' for Tramp files."
679-
flag ;; FIXME: Support 'nofollow'.
680679
(with-parsed-tramp-file-name filename nil
681680
(tramp-flush-file-properties v localname)
682681
(let ((time (if (or (null time)
683682
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
684683
(tramp-compat-time-equal-p time tramp-time-dont-know))
685684
(current-time)
686685
time))
686+
(nofollow (if (eq flag 'nofollow) "-h" ""))
687687
(quoted-name (tramp-shell-quote-argument localname)))
688688
;; Older versions of toybox 'touch' mishandle nanoseconds and/or
689689
;; trailing "Z", so fall back on plain seconds if nanoseconds+Z
690690
;; fails. Also, fall back on old POSIX 'touch -t' if 'touch -d'
691691
;; (introduced in POSIX.1-2008) fails.
692692
(tramp-adb-send-command-and-check
693-
v (format (concat "touch -d %s %s 2>/dev/null || "
694-
"touch -d %s %s 2>/dev/null || "
695-
"touch -t %s %s")
693+
v (format (concat "touch -d %s %s %s 2>/dev/null || "
694+
"touch -d %s %s %s 2>/dev/null || "
695+
"touch -t %s %s %s")
696696
(format-time-string "%Y-%m-%dT%H:%M:%S.%NZ" time t)
697-
quoted-name
697+
nofollow quoted-name
698698
(format-time-string "%Y-%m-%dT%H:%M:%S" time t)
699-
quoted-name
699+
nofollow quoted-name
700700
(format-time-string "%Y%m%d%H%M.%S" time t)
701-
quoted-name)))))
701+
nofollow quoted-name)))))
702702

703703
(defun tramp-adb-handle-copy-file
704704
(filename newname &optional ok-if-already-exists keep-date
@@ -775,7 +775,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
775775

776776
;; KEEP-DATE handling.
777777
(when keep-date
778-
(set-file-times
778+
(tramp-compat-set-file-times
779779
newname
780780
(tramp-compat-file-attribute-modification-time
781781
(file-attributes filename))

lisp/net/tramp-compat.el

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@ A nil value for either argument stands for the current time."
276276
(lambda (reporter &optional value _suffix)
277277
(progress-reporter-update reporter value))))
278278

279-
;; `file-modes' and `set-file-modes' got argument FLAG in Emacs 28.1.
279+
;; `file-modes', `set-file-modes' and `set-file-times' got argument
280+
;; FLAG in Emacs 28.1.
280281
(defalias 'tramp-compat-file-modes
281282
(if (equal (tramp-compat-funcall 'func-arity #'file-modes) '(1 . 2))
282283
#'file-modes
@@ -289,6 +290,12 @@ A nil value for either argument stands for the current time."
289290
(lambda (filename mode &optional _flag)
290291
(set-file-modes filename mode))))
291292

293+
(defalias 'tramp-compat-set-file-times
294+
(if (equal (tramp-compat-funcall 'func-arity #'set-file-times) '(1 . 3))
295+
#'set-file-times
296+
(lambda (filename &optional timestamp _flag)
297+
(set-file-times filename timestamp))))
298+
292299
(add-hook 'tramp-unload-hook
293300
(lambda ()
294301
(unload-feature 'tramp-loaddefs 'force)

lisp/net/tramp-gvfs.el

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,23 +1568,21 @@ If FILE-SYSTEM is non-nil, return file system attributes."
15681568
(tramp-flush-file-properties v localname)
15691569
(tramp-gvfs-send-command
15701570
v "gvfs-set-attribute" (if (eq flag 'nofollow) "-nt" "-t") "uint32"
1571-
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
1572-
"unix::mode" (number-to-string mode))))
1571+
(tramp-gvfs-url-file-name filename) "unix::mode" (number-to-string mode))))
15731572

15741573
(defun tramp-gvfs-handle-set-file-times (filename &optional time flag)
15751574
"Like `set-file-times' for Tramp files."
15761575
(with-parsed-tramp-file-name filename nil
15771576
(tramp-flush-file-properties v localname)
1578-
(let ((time
1579-
(if (or (null time)
1577+
(tramp-gvfs-send-command
1578+
v "gvfs-set-attribute" (if (eq flag 'nofollow) "-nt" "-t") "uint64"
1579+
(tramp-gvfs-url-file-name filename) "time::modified"
1580+
(format-time-string
1581+
"%s" (if (or (null time)
15801582
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
15811583
(tramp-compat-time-equal-p time tramp-time-dont-know))
15821584
(current-time)
1583-
time)))
1584-
(tramp-gvfs-send-command
1585-
v "gvfs-set-attribute" (if flag "-nt" "-t") "uint64"
1586-
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
1587-
"time::modified" (format-time-string "%s" time)))))
1585+
time)))))
15881586

15891587
(defun tramp-gvfs-set-file-uid-gid (filename &optional uid gid)
15901588
"Like `tramp-set-file-uid-gid' for Tramp files."
@@ -1593,12 +1591,11 @@ If FILE-SYSTEM is non-nil, return file system attributes."
15931591
(when (natnump uid)
15941592
(tramp-gvfs-send-command
15951593
v "gvfs-set-attribute" "-t" "uint32"
1596-
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
1597-
"unix::uid" (number-to-string uid)))
1594+
(tramp-gvfs-url-file-name filename) "unix::uid" (number-to-string uid)))
15981595
(when (natnump gid)
15991596
(tramp-gvfs-send-command
16001597
v "gvfs-set-attribute" "-t" "uint32"
1601-
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
1598+
(tramp-gvfs-url-file-name filename)
16021599
"unix::gid" (number-to-string gid)))))
16031600

16041601

lisp/net/tramp-sh.el

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,7 +1500,6 @@ of."
15001500
(with-parsed-tramp-file-name filename nil
15011501
(when (tramp-get-remote-touch v)
15021502
(tramp-flush-file-properties v localname)
1503-
flag ;; FIXME: Support 'nofollow'.
15041503
(let ((time
15051504
(if (or (null time)
15061505
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
@@ -1509,11 +1508,12 @@ of."
15091508
time)))
15101509
(tramp-send-command-and-check
15111510
v (format
1512-
"env TZ=UTC %s %s %s"
1511+
"env TZ=UTC %s %s %s %s"
15131512
(tramp-get-remote-touch v)
15141513
(if (tramp-get-connection-property v "touch-t" nil)
15151514
(format "-t %s" (format-time-string "%Y%m%d%H%M.%S" time t))
15161515
"")
1516+
(if (eq flag 'nofollow) "-h" "")
15171517
(tramp-shell-quote-argument localname)))))))
15181518

15191519
(defun tramp-sh-handle-set-file-uid-gid (filename &optional uid gid)
@@ -1979,7 +1979,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
19791979
(unless (file-directory-p (file-name-directory newname))
19801980
(make-directory (file-name-directory newname) parents))
19811981
(tramp-do-copy-or-rename-file-out-of-band
1982-
'copy dirname newname keep-date))
1982+
'copy dirname newname 'ok-if-already-exists keep-date))
19831983

19841984
;; We must do it file-wise.
19851985
(tramp-run-real-handler
@@ -2075,7 +2075,7 @@ file names."
20752075
(tramp-method-out-of-band-p v1 length)
20762076
(tramp-method-out-of-band-p v2 length))
20772077
(tramp-do-copy-or-rename-file-out-of-band
2078-
op filename newname keep-date))
2078+
op filename newname ok-if-already-exists keep-date))
20792079

20802080
;; No shortcut was possible. So we copy the file
20812081
;; first. If the operation was `rename', we go back
@@ -2088,7 +2088,7 @@ file names."
20882088
;; source and target file.
20892089
(t
20902090
(tramp-do-copy-or-rename-file-via-buffer
2091-
op filename newname keep-date))))))
2091+
op filename newname ok-if-already-exists keep-date))))))
20922092

20932093
;; One file is a Tramp file, the other one is local.
20942094
((or t1 t2)
@@ -2103,11 +2103,11 @@ file names."
21032103
;; corresponding copy-program can be invoked.
21042104
((tramp-method-out-of-band-p v length)
21052105
(tramp-do-copy-or-rename-file-out-of-band
2106-
op filename newname keep-date))
2106+
op filename newname ok-if-already-exists keep-date))
21072107

21082108
;; Use the inline method via a Tramp buffer.
21092109
(t (tramp-do-copy-or-rename-file-via-buffer
2110-
op filename newname keep-date))))
2110+
op filename newname ok-if-already-exists keep-date))))
21112111

21122112
(t
21132113
;; One of them must be a Tramp file.
@@ -2129,7 +2129,8 @@ file names."
21292129
(with-parsed-tramp-file-name newname v2
21302130
(tramp-flush-file-properties v2 v2-localname))))))))
21312131

2132-
(defun tramp-do-copy-or-rename-file-via-buffer (op filename newname keep-date)
2132+
(defun tramp-do-copy-or-rename-file-via-buffer
2133+
(op filename newname ok-if-already-exists keep-date)
21332134
"Use an Emacs buffer to copy or rename a file.
21342135
First arg OP is either `copy' or `rename' and indicates the operation.
21352136
FILENAME is the source file, NEWNAME the target file.
@@ -2157,10 +2158,11 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
21572158
(insert-file-contents-literally filename)))
21582159
;; KEEP-DATE handling.
21592160
(when keep-date
2160-
(set-file-times
2161+
(tramp-compat-set-file-times
21612162
newname
21622163
(tramp-compat-file-attribute-modification-time
2163-
(file-attributes filename))))
2164+
(file-attributes filename))
2165+
(unless ok-if-already-exists 'nofollow)))
21642166
;; Set the mode.
21652167
(set-file-modes newname (tramp-default-file-modes filename))
21662168
;; If the operation was `rename', delete the original file.
@@ -2314,10 +2316,12 @@ the uid and gid from FILENAME."
23142316
;; Set the time and mode. Mask possible errors.
23152317
(ignore-errors
23162318
(when keep-date
2317-
(set-file-times newname file-times)
2319+
(tramp-compat-set-file-times
2320+
newname file-times (unless ok-if-already-exists 'nofollow))
23182321
(set-file-modes newname file-modes))))))
23192322

2320-
(defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date)
2323+
(defun tramp-do-copy-or-rename-file-out-of-band
2324+
(op filename newname ok-if-already-exists keep-date)
23212325
"Invoke `scp' program to copy.
23222326
The method used must be an out-of-band method."
23232327
(let* ((t1 (tramp-tramp-file-p filename))
@@ -2340,9 +2344,9 @@ The method used must be an out-of-band method."
23402344
(unwind-protect
23412345
(progn
23422346
(tramp-do-copy-or-rename-file-out-of-band
2343-
op filename tmpfile keep-date)
2347+
op filename tmpfile ok-if-already-exists keep-date)
23442348
(tramp-do-copy-or-rename-file-out-of-band
2345-
'rename tmpfile newname keep-date))
2349+
'rename tmpfile newname ok-if-already-exists keep-date))
23462350
;; Save exit.
23472351
(ignore-errors
23482352
(if dir-flag
@@ -2516,10 +2520,11 @@ The method used must be an out-of-band method."
25162520

25172521
;; Handle KEEP-DATE argument.
25182522
(when (and keep-date (not copy-keep-date))
2519-
(set-file-times
2523+
(tramp-compat-set-file-times
25202524
newname
25212525
(tramp-compat-file-attribute-modification-time
2522-
(file-attributes filename))))
2526+
(file-attributes filename))
2527+
(unless ok-if-already-exists 'nofollow)))
25232528

25242529
;; Set the mode.
25252530
(unless (and keep-date copy-keep-date)

lisp/net/tramp-smb.el

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,11 @@ pass to the OPERATION."
538538

539539
;; Handle KEEP-DATE argument.
540540
(when keep-date
541-
(set-file-times
541+
(tramp-compat-set-file-times
542542
newname
543543
(tramp-compat-file-attribute-modification-time
544-
(file-attributes dirname))))
544+
(file-attributes dirname))
545+
(unless ok-if-already-exists 'nofollow)))
545546

546547
;; Set the mode.
547548
(unless keep-date
@@ -616,7 +617,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
616617

617618
;; KEEP-DATE handling.
618619
(when keep-date
619-
(set-file-times
620+
(tramp-compat-set-file-times
620621
newname
621622
(tramp-compat-file-attribute-modification-time
622623
(file-attributes filename))

lisp/net/tramp-sudoedit.el

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ absolute file names."
281281
;; Set the time and mode. Mask possible errors.
282282
(when keep-date
283283
(ignore-errors
284-
(set-file-times newname file-times)
284+
(tramp-compat-set-file-times
285+
newname file-times (unless ok-if-already-exists 'nofollow))
285286
(set-file-modes newname file-modes)))
286287

287288
;; Handle `preserve-extended-attributes'. We ignore possible
@@ -527,7 +528,6 @@ the result will be a local, non-Tramp, file name."
527528
"Like `set-file-times' for Tramp files."
528529
(with-parsed-tramp-file-name filename nil
529530
(tramp-flush-file-properties v localname)
530-
flag ;; FIXME: Support 'nofollow'.
531531
(let ((time
532532
(if (or (null time)
533533
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
@@ -537,6 +537,7 @@ the result will be a local, non-Tramp, file name."
537537
(tramp-sudoedit-send-command
538538
v "env" "TZ=UTC" "touch" "-t"
539539
(format-time-string "%Y%m%d%H%M.%S" time t)
540+
(if (eq flag 'nofollow) "-h" "")
540541
(tramp-compat-file-name-unquote localname)))))
541542

542543
(defun tramp-sudoedit-handle-file-truename (filename)

test/lisp/net/tramp-tests.el

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3743,8 +3743,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
37433743
(file-attributes tmp-name1))))
37443744
;; Skip the test, if the remote handler is not able to set
37453745
;; the correct time.
3746-
(skip-unless (set-file-times tmp-name1 (seconds-to-time 1)
3747-
'nofollow))
3746+
(skip-unless (set-file-times tmp-name1 (seconds-to-time 1)))
37483747
;; Dumb remote shells without perl(1) or stat(1) are not
37493748
;; able to return the date correctly. They say "don't know".
37503749
(unless (tramp-compat-time-equal-p
@@ -3761,7 +3760,17 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
37613760
(should (file-newer-than-file-p tmp-name2 tmp-name1))
37623761
;; `tmp-name3' does not exist.
37633762
(should (file-newer-than-file-p tmp-name2 tmp-name3))
3764-
(should-not (file-newer-than-file-p tmp-name3 tmp-name1))))
3763+
(should-not (file-newer-than-file-p tmp-name3 tmp-name1))
3764+
;; Check the NOFOLLOW arg. It exists since Emacs 28. For
3765+
;; regular files, there shouldn't be a difference.
3766+
(when (tramp--test-emacs28-p)
3767+
(with-no-warnings
3768+
(set-file-times tmp-name1 (seconds-to-time 1) 'nofollow)
3769+
(should
3770+
(tramp-compat-time-equal-p
3771+
(tramp-compat-file-attribute-modification-time
3772+
(file-attributes tmp-name1))
3773+
(seconds-to-time 1)))))))
37653774

37663775
;; Cleanup.
37673776
(ignore-errors

0 commit comments

Comments
 (0)