寝る直前にtail -f ってどういう仕組みなんだろって雑に思ったので実装は読まずにstraceして雰囲気だけ掴んでみた。ざっくり書くと対象のファイルをinotify_add_watch(2)
して監視してそのファイルディスクリプタをreadして書き込みがあれば表示するみたいな流れになっていた。tail -f って複数ファイルを引数に取れたりするのだが引数分inotify_add_watch(2)
を呼び出すことで対応していた。
open("aaa", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0777, st_size=0, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 lseek(3, 0, SEEK_END) = 0 // ファイル末尾までseekしておく lseek(3, 0, SEEK_SET) = 0 // ここを起点とする read(3, "", 8192) = 0 fstat(3, {st_mode=S_IFREG|0777, st_size=0, ...}) = 0 fstatfs(3, {f_type=XFS_SB_MAGIC, f_bsize=4096, f_blocks=7596417, f_bfree=6956471, f_bavail=6956471, f_files=15200256, f_ffree=15115420, f_fsid={val=[64768, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0 lstat("aaa", {st_mode=S_IFREG|0777, st_size=0, ...}) = 0 inotify_init() = 4 inotify_add_watch(4, "aaa", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1 fstat(3, {st_mode=S_IFREG|0777, st_size=0, ...}) = 0 read(4, // 対象ファイルに変更が加わるまではここでブロックする
書き込みを行うとこんな感じ。
read(4, "\1\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0", 20) = 16 fstat(3, {st_mode=S_IFREG|0777, st_size=8, ...}) = 0 read(3, "bbb\n", 8192) = 4 write(1, "bbb\n", 4bbb ) = 4 read(3, "", 8192) = 0 read(4,