I have a struct timespec object I need to convert to struct timeval for use with lutimes(...).
I've attempted the following, but lutimes() complains.
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
Now EINVAL from lutimes means the usec component was outside of 0 <= tv_usec < 1000000, meaning the conversion from timespec went wrong. [source]
How do I properly convert from timespec to timeval?
More thorough debugging with the touch command, reveals that timespec contains tv_sec = 0 and tv_nsec > 1000000000, when no specific date was specified and the current time should be used.
Why is this? What's the proper way to handle this?
First I'll clarify what was not clear to me at first from the question: This is implementation of the utimens operation in fuse filesystem and the problem is that sometimes the tv_nsec field has value bigger or equal to 1,000,000,000.
My guess is that it is one of the two special values: UTIME_NOW or UTIME_OMIT.
The fuse documentation points to the utimensat manual page, which has explanation for those special values:
http://man7.org/linux/man-pages/man2/utimensat.2.html
Also check the nsec_valid function in linux kernel:
https://elixir.free-electrons.com/linux/v4.15.2/source/fs/utimes.c#L40