Skip to content

Commit a13c016

Browse files
committed
update posix_at
1 parent d1229c2 commit a13c016

1 file changed

Lines changed: 53 additions & 4 deletions

File tree

include/fast_io_hosted/filesystem/posix_at.h

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,19 +336,19 @@ inline void posix_unlinkat_impl(int dirfd, char const *path, int flags)
336336

337337
namespace details
338338
{
339-
inline constexpr struct timespec unix_timestamp_to_struct_timespec64(unix_timestamp stmp) noexcept
339+
inline constexpr struct timespec unix_timestamp_to_struct_timespec(unix_timestamp stmp) noexcept
340340
{
341341
constexpr ::std::uint_least64_t mul_factor{uint_least64_subseconds_per_second / 1000000000u};
342342
return {static_cast<::std::time_t>(stmp.seconds),
343-
static_cast<long>(static_cast<long unsigned>((stmp.subseconds) / mul_factor))};
343+
static_cast<long>(static_cast<long unsigned>(stmp.subseconds / mul_factor))};
344344
}
345345

346346
inline
347347
#if defined(UTIME_NOW) && defined(UTIME_OMIT)
348348
constexpr
349349
#endif
350350
struct timespec
351-
unix_timestamp_to_struct_timespec64([[maybe_unused]] unix_timestamp_option opt) noexcept
351+
unix_timestamp_to_struct_timespec([[maybe_unused]] unix_timestamp_option opt) noexcept
352352
{
353353
#if defined(UTIME_NOW) && defined(UTIME_OMIT)
354354
switch (opt.flags)
@@ -357,13 +357,52 @@ inline
357357
return {.tv_sec = 0, .tv_nsec = UTIME_NOW};
358358
case utime_flags::omit:
359359
return {.tv_sec = 0, .tv_nsec = UTIME_OMIT};
360+
default:
361+
return unix_timestamp_to_struct_timespec(opt.timestamp);
362+
}
363+
#else
364+
throw_posix_error(EINVAL);
365+
#endif
366+
}
367+
368+
#if defined(__linux__) && defined(__NR_utimensat_time64)
369+
370+
// https://github.com/torvalds/linux/blob/07e27ad16399afcd693be20211b0dfae63e0615f/include/uapi/linux/time_types.h#L7
371+
struct kernel_timespec64
372+
{
373+
::std::int_least64_t tv_sec;
374+
::std::int_least64_t tv_nsec;
375+
};
376+
377+
inline constexpr kernel_timespec64 unix_timestamp_to_struct_timespec64(unix_timestamp stmp) noexcept
378+
{
379+
constexpr ::std::uint_least64_t mul_factor{uint_least64_subseconds_per_second / 1000000000u};
380+
return {static_cast<::std::int_least64_t>(stmp.seconds),
381+
static_cast<::std::int_least64_t>(stmp.subseconds / mul_factor)};
382+
}
383+
384+
inline
385+
#if defined(UTIME_NOW) && defined(UTIME_OMIT)
386+
constexpr
387+
#endif
388+
kernel_timespec64
389+
unix_timestamp_to_struct_timespec64([[maybe_unused]] unix_timestamp_option opt) noexcept
390+
{
391+
#if defined(UTIME_NOW) && defined(UTIME_OMIT)
392+
switch (opt.flags)
393+
{
394+
case utime_flags::now:
395+
return {.tv_sec = 0, .tv_nsec = static_cast<::std::int_least64_t>(UTIME_NOW)};
396+
case utime_flags::omit:
397+
return {.tv_sec = 0, .tv_nsec = static_cast<::std::int_least64_t>(UTIME_OMIT)};
360398
default:
361399
return unix_timestamp_to_struct_timespec64(opt.timestamp);
362400
}
363401
#else
364402
throw_posix_error(EINVAL);
365403
#endif
366404
}
405+
#endif
367406

368407
} // namespace details
369408

@@ -375,11 +414,21 @@ inline void posix_utimensat_impl(int dirfd, char const *path, unix_timestamp_opt
375414
{
376415
throw_posix_error(EINVAL);
377416
}
378-
struct timespec ts[2]{
417+
418+
#if defined(__linux__) && defined(__NR_utimensat_time64)
419+
details::kernel_timespec64 ts[2]{
379420
details::unix_timestamp_to_struct_timespec64(last_access_time),
380421
details::unix_timestamp_to_struct_timespec64(last_modification_time),
381422
};
423+
details::kernel_timespec64 *tsptr{ts};
424+
#else
425+
struct timespec ts[2]{
426+
details::unix_timestamp_to_struct_timespec(last_access_time),
427+
details::unix_timestamp_to_struct_timespec(last_modification_time),
428+
};
382429
struct timespec *tsptr{ts};
430+
#endif
431+
383432
system_call_throw_error(
384433
#if defined(__linux__)
385434
#if defined(__NR_utimensat_time64)

0 commit comments

Comments
 (0)