如何正确地将 timespec 转换为 timeval?

How to correctly convert timespec to timeval?

我有一个 struct timespec 对象,我需要将其转换为 struct timeval 以便与 lutimes(...) 一起使用。

我尝试了以下操作,但 lutimes() 抱怨。

const struct timespec ts; // originally provided as function parameter from FUSE
struct timeval tv;
tv.tv_sec = ts.tv_sec;
tv.tv_usec = ts.tv_nsec / 1000;
lutimes(path, tv); // returns -1; errno=EINVAL

现在 EINVAL 来自 lutimes 意味着 usec 组件在 0 <= tv_usec < 1000000 之外,这意味着来自 timespec 的转换出错了。 [source]

如何正确地将 timespec 转换为 timeval


使用touch命令进行更彻底的调试,显示timespec包含tv_sec = 0tv_nsec > 1000000000,当没有指定具体日期时应该使用当前时间.

这是为什么?处理此问题的正确方法是什么?

首先我会澄清一下我最初从问题中不清楚的地方:这是 utimens 操作在 fuse 文件系统中的实现,问题是有时 tv_nsec 字段有值大于或等于 1,000,000,000。

我的猜测是它是两个特殊值之一:UTIME_NOWUTIME_OMIT

保险丝文档指向 utimensat 手册页,其中对这些特殊值进行了解释: http://man7.org/linux/man-pages/man2/utimensat.2.html


同时检查 linux 内核中的 nsec_valid 函数:

https://elixir.free-electrons.com/linux/v4.15.2/source/fs/utimes.c#L40