为什么 touch 包含 utimensat() 系统调用?

Why does touch include a utimensat() syscall?

查看文件 mtimes 的奇怪时间顺序,我注意到 (gnu) touch 命令包含一个 utimensat 系统调用作为其触摸序列的一部分:

open("touchedLater", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
dup2(3, 0)                              = 0
close(3)                                = 0
dup2(0, 0)                              = 0
utimensat(0, NULL, NULL, 0)             = 0
close(0)                                = 0

touch 命令似乎明确将文件时间戳的亚秒部分归零。其他文件创建方法不一定这样做, 在 clearcase V8 动态视图中,这会导致 "interesting" make 的排序问题。

为什么使用此 utimensat 系统调用将文件的亚秒级修改时间归零?

编辑:dg99 指出这个 API,以 strace 指示的方式调用可能是试图将时间设置为当前时间,而不是清除时间的亚秒部分,如观察到的.为了重现这一点,我尝试调用 utimensat(fd, NULL, NULL, 0),但这会产生 EINVAL。事实证明 strace 在撒谎(也许是轻微的:也许同一个内核系统调用同时执行 utimensatfutimens APIs),而 touch.c 实际上正在做的是:

269               result = futimens (fd, ts);
(gdb) s
272               if (0 < result)
(gdb) p fd
 = 0
(gdb) p ts
 = (struct timespec *) 0x0

以这种方式调用一些独立代码,使用 futimes 还具有使用 clearcase 版本 8 MVFS 清除时间的亚秒部分的外观。

根据我对 utimensat 手册页的阅读,上述调用并未明确将任何内容设置为零,而是将访问和修改时间戳都设置为当前时间:

int utimensat(int dirfd, const char *pathname,
              const struct timespec times[2], int flags);

... the new file timestamps are specified in the array times ... If times is NULL, then both timestamps are set to the current time.