Bagaimana cara sentuh -t bekerja secara internal?

20

Bagaimana cara touch -tkerja perintah secara tepat, secara internal (saya mencoba menemukan kode sumbernya tetapi tidak bisa)?

syntagma
sumber

Jawaban:

23

touchmemanggil panggilan utimessistem untuk mengatur waktu modifikasi file dan waktu aksesnya. Pada beberapa sistem, alih-alih utimes, itu membuka file dan kemudian menetapkan waktu file melalui deskriptor, misalnya dengan utimensatdi Linux.

Anda dapat melihat cara touchkerjanya pada sistem Anda dengan melihat panggilan sistem yang dibuatnya. Di Linux, gunakan strace , mis strace touch -d '1 hour ago' foo.

Di mana menemukan kode sumber tergantung pada sistem operasi Anda. Versi GNU ada di coreutils , ada versi di pohon sumber utama BSD apa pun, ada versi di BusyBox , di Minix , dll.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
28

Terkadang Anda bahkan tidak memerlukan kode sumber. Gunakan 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 +++

Kenapa halo di sana utimensat(),. Apakah kamu?

$ man utimensat

NAME
   utimensat, futimens - change file timestamps with nanosecond precision

Jadi ada fungsi yang mengubah stempel waktu file, dan touchmenggunakannya untuk memperbarui stempel waktu file. Dan itulah cara kerjanya secara internal.

frostschutz
sumber
10

Inilah cara kerjanya pada Solaris. trussdigunakan alih-alih straceyang merupakan perintah yang sangat berbeda di sini.

Seperti di bawah Gnu / Linux, utimensatadalah panggilan sistem yang digunakan.

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