Wie funktioniert touch -t intern?

20

Wie funktioniert der touch -tBefehl intern genau (ich habe versucht, den Quellcode zu finden, konnte ihn aber nicht finden)?

syntagma
quelle

Antworten:

23

touchruft den utimesSystemaufruf auf, um die Änderungszeit und die Zugriffszeit der Datei festzulegen. Auf einigen Systemen wird stattdessen utimesdie Datei geöffnet und anschließend die Dateizeiten über den Deskriptor festgelegt, z utimensat. B. bei unter Linux.

Sie können die Funktionsweise touchIhres Systems anhand der Systemaufrufe überprüfen. Verwenden Sie unter Linux strace , z strace touch -d '1 hour ago' foo.

Wo Sie den Quellcode finden, hängt von Ihrem Betriebssystem ab. Die GNU-Version befindet sich in coreutils , es gibt eine Version im Hauptquellbaum jeder BSD, es gibt eine Version in BusyBox , in Minix usw.

Gilles 'SO - hör auf böse zu sein'
quelle
28

Manchmal braucht man nicht einmal den Quellcode. Verwenden Sie strace.

$ strace touch -t 201212121212 foobar
execve("/usr/bin/touch", ["touch", "-t", "201212121212", "foobar"], [/* 61 vars */]) = 0
[...] lots of noise [...]
open("foobar", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
dup2(3, 0)                              = 0
close(3)                                = 0
utimensat(0, NULL, {{1355310720, 0}, {1355310720, 0}}, 0) = 0
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Warum hallo dort utimensat(). Was bist du?

$ man utimensat

NAME
   utimensat, futimens - change file timestamps with nanosecond precision

Es gibt also eine Funktion, die Dateizeitstempel ändert und touchzum Aktualisieren des Zeitstempels einer Datei verwendet. Und so funktioniert es intern.

Frostschutz
quelle
10

So funktioniert es unter Solaris. trussverwendet wird, statt stracedessen ist hier ein ganz anderer Befehl.

Wie unter Gnu / Linux utimensatwird der Systemaufruf verwendet.

$ truss -vall -u a.out -f touch -t 1306080000 z
4160:   execve("/usr/bin/touch", 0xF0770FC0, 0xF0770FD4)  argc = 4
...
4160/1@1:       -> main(0x4, 0xf0770fc0, 0xf0770fd4, 0xf0770f7c)
...
4160/1@1:           -> atoi_for2(0xf0771131, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 13
4160/1@1:           -> atoi_for2(0xf0771133, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 6
4160/1@1:           -> atoi_for2(0xf0771135, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 8
4160/1@1:           -> atoi_for2(0xf0771137, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 0
4160/1@1:           -> atoi_for2(0xf0771139, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 0
4160/1@1:         <- parse_time() = 0x51b257e0
4160/1:         stat64("z", 0xF0770ED0)                         = 0
4160/1:             d=0x08A00002 i=75783706 m=0100644 l=1  u=100   g=10    sz=0
4160/1:                 at = Jun  8 01:48:08 CEST 2013  [ 1370648888.022270973 ]
4160/1:                 mt = Jun  8 01:48:08 CEST 2013  [ 1370648888.022270973 ]
4160/1:                 ct = Jun  8 01:48:08 CEST 2013  [ 1370648888.022273810 ]
4160/1:             bsz=4096  blks=0     fs=tmpfs
4160/1:         utimensat(AT_FDCWD, "z", 0xF0770F60, 0)         = 0
4160/1:                 at = Jun  8 00:00:00 CEST 2013  [ 1370642400.000000000 ]
4160/1:                 mt = Jun  8 00:00:00 CEST 2013  [ 1370642400.000000000 ]
4160/1@1:       <- main() = 0
4160/1@1:       -> _fini()
4160/1@1:       <- _fini() = 0xebcc0140
4160/1:         _exit(0)
jlliagre
quelle