¿Cómo funciona touch -t internamente?

20

¿Cómo funciona el touch -tcomando exactamente, internamente (intenté encontrar su código fuente pero no pude)?

sintagma
fuente

Respuestas:

23

touchllama a la llamada del utimessistema para establecer el tiempo de modificación del archivo y su tiempo de acceso. En algunos sistemas, en lugar de utimes, abre el archivo y luego establece los tiempos del archivo a través del descriptor, por ejemplo, con utimensatLinux.

Puede ver cómo touchfunciona en su sistema mirando las llamadas del sistema que realiza. En Linux, use strace , por ejemplo strace touch -d '1 hour ago' foo.

Dónde encontrar el código fuente depende de su sistema operativo. La versión de GNU está en coreutils , hay una versión en el árbol fuente principal de cualquier BSD, hay una versión en BusyBox , en Minix , etc.

Gilles 'SO- deja de ser malvado'
fuente
28

A veces ni siquiera necesitas el código fuente. Uso 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 +++

¿Por qué hola allí utimensat()? ¿Que eres?

$ man utimensat

NAME
   utimensat, futimens - change file timestamps with nanosecond precision

Entonces, hay una función que cambia las marcas de tiempo del archivo y la touchusa para actualizar la marca de tiempo de un archivo. Y así es como funciona internamente.

Frostschutz
fuente
10

Así es como funciona en Solaris. trussse usa en lugar de lo stracecual es un comando bastante diferente aquí.

Al igual que en Gnu / Linux, utimensates la llamada al sistema utilizada.

$ 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
fuente