Comment fonctionne touch -t en interne?

20

Comment touch -tfonctionne exactement la commande, en interne (j'ai essayé de trouver son code source mais je n'ai pas pu)?

syntagme
la source

Réponses:

23

touchappelle l' utimesappel système pour définir l'heure de modification du fichier et son heure d'accès. Sur certains systèmes, au lieu de utimes, il ouvre le fichier, puis définit les temps de fichier via le descripteur, par exemple avec utimensatsous Linux.

Vous pouvez voir comment touchfonctionne votre système en examinant les appels système qu'il effectue. Sous Linux, utilisez strace , par exemple strace touch -d '1 hour ago' foo.

Où trouver le code source dépend de votre système d'exploitation. La version GNU est dans coreutils , il y a une version dans l'arborescence principale de n'importe quel BSD, il y a une version dans BusyBox , dans Minix , etc.

Gilles 'SO- arrête d'être méchant'
la source
28

Parfois, vous n'avez même pas besoin du code source. Utilisez 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 +++

Pourquoi bonjour là - bas, utimensat(). Qu'es-tu?

$ man utimensat

NAME
   utimensat, futimens - change file timestamps with nanosecond precision

Il existe donc une fonction qui modifie l'horodatage des fichiers et l' touchutilise pour mettre à jour l'horodatage d'un fichier. Et c'est ainsi que cela fonctionne en interne.

frostschutz
la source
10

Voici comment cela fonctionne sur Solaris. trussest utilisé à la place de stracece qui est une commande assez différente ici.

Comme sous Gnu / Linux, utimensatest l'appel système utilisé.

$ 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
la source