Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.statvfs.statvfs

# sys/utimes.h entrypoints
# libc.src.sys.time.utimes
libc.src.sys.time.utimes

# sys/utsname.h entrypoints
libc.src.sys.utsname.uname
Expand Down
4 changes: 4 additions & 0 deletions libc/include/sys/syscall.h.def
Original file line number Diff line number Diff line change
Expand Up @@ -2301,6 +2301,10 @@
#define SYS_utimes __NR_utimes
#endif

#ifdef __NR_utimensat_time64
#define SYS_utimensat_time64 __NR_utimensat_time64
#endif

#ifdef __NR_utrap_install
#define SYS_utrap_install __NR_utrap_install
#endif
Expand Down
22 changes: 15 additions & 7 deletions libc/src/sys/time/linux/utimes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "src/sys/time/utimes.h"

#include "hdr/fcntl_macros.h"
#include "hdr/types/struct_timespec.h"
#include "hdr/types/struct_timeval.h"

#include "src/__support/OSUtil/syscall.h"
Expand All @@ -20,14 +21,24 @@

namespace LIBC_NAMESPACE_DECL {

#if SYS_utimes
constexpr auto UTIMES_SYSCALL_ID = SYS_utimes;
#elif defined(SYS_utimensat)
constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat;
#elif defined(SYS_utimensat_time64)
constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat_time64;
#else
#error "utimes, utimensat, utimensat_time64, syscalls not available."
#endif

LLVM_LIBC_FUNCTION(int, utimes,
(const char *path, const struct timeval times[2])) {
int ret;

#ifdef SYS_utimes
// No need to define a timespec struct, use the syscall directly.
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_utimes, path, times);
#elif defined(SYS_utimensat)
ret = LIBC_NAMESPACE::syscall_impl<int>(UTIMES_SYSCALL_ID, path, times);
#elif defined(SYS_utimensat) || defined(SYS_utimensat_time64)
// the utimensat syscall requires a timespec struct, not timeval.
struct timespec ts[2];
struct timespec *ts_ptr = nullptr; // default value if times is nullptr
Expand Down Expand Up @@ -59,11 +70,8 @@ LLVM_LIBC_FUNCTION(int, utimes,

// utimensat syscall.
// flags=0 means don't follow symlinks (like utimes)
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_utimensat, AT_FDCWD, path, ts_ptr,
0);

#else
#error "utimensat and utimes syscalls not available."
ret = LIBC_NAMESPACE::syscall_impl<int>(UTIMES_SYSCALL_ID, AT_FDCWD, path,
ts_ptr, 0);
#endif // SYS_utimensat

if (ret < 0) {
Expand Down
Loading