0

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?

Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
  • 1
    This code does not compile. The `lutimes` function takes *array of two* `timeval`s as second parameter. You should post your actual code. – michalsrb Feb 08 '18 at 19:27
  • @michalsrb I know, if you actually want to try this just give it the same timeval twice (which should set access time and modification time to the same value). Should I change my example code? – Cobra_Fast Feb 08 '18 at 19:30
  • Better yet show the actual code that gives you the EINVAL error. – michalsrb Feb 08 '18 at 19:54
  • @michalsrb Sure, it's at https://gitlab.com/Cobra_Fast/maidfs/blob/4aa6091c333796ffc041f8fe381128716e970503/maidfs/main.cpp#L1221 and I've managed a workaround since: https://gitlab.com/Cobra_Fast/maidfs/blob/28e13ef589e66c3fa23189375959f279e6eb8f3b/maidfs/main.cpp#L1221 but I'd still like to know how to do it properly. – Cobra_Fast Feb 08 '18 at 20:03

1 Answers1

2

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

michalsrb
  • 4,703
  • 1
  • 18
  • 35