#include "hdr/fcntl_macros.h"
#include "hdr/sys_stat_macros.h"
#include "hdr/types/struct_timeval.h"
#include "src/fcntl/open.h"
#include "src/stdio/remove.h"
#include "src/sys/stat/stat.h"
#include "src/sys/time/utimes.h"
#include "src/unistd/close.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
using LlvmLibcUtimesTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
TEST_F(LlvmLibcUtimesTest, ChangeTimesSpecific) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *FILE_PATH = "utimes_pass.test";
auto TEST_FILE = libc_make_test_file_path(FILE_PATH);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
struct timeval times[2];
times[0].tv_sec = 54321;
times[0].tv_usec = 12345;
times[1].tv_sec = 43210;
times[1].tv_usec = 23456;
ASSERT_THAT(LIBC_NAMESPACE::utimes(TEST_FILE, times), Succeeds(0));
struct stat statbuf;
ASSERT_EQ(LIBC_NAMESPACE::stat(TEST_FILE, &statbuf), 0);
ASSERT_EQ(statbuf.st_atim.tv_sec, times[0].tv_sec);
ASSERT_EQ(statbuf.st_mtim.tv_sec, times[1].tv_sec);
ASSERT_EQ(statbuf.st_atim.tv_nsec,
static_cast<long>(times[0].tv_usec * 1000));
ASSERT_EQ(statbuf.st_mtim.tv_nsec,
static_cast<long>(times[1].tv_usec * 1000));
ASSERT_THAT(LIBC_NAMESPACE::remove(TEST_FILE), Succeeds(0));
}
TEST_F(LlvmLibcUtimesTest, InvalidMicroseconds) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *FILE_PATH = "utimes_fail.test";
auto TEST_FILE = libc_make_test_file_path(FILE_PATH);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_GT(fd, 0);
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
struct timeval times[2];
times[0].tv_sec = 54321;
times[0].tv_usec = 4567;
times[1].tv_sec = 43210;
times[1].tv_usec = 1000000;
ASSERT_THAT(LIBC_NAMESPACE::utimes(TEST_FILE, times), Fails(EINVAL));
times[0].tv_sec = 54321;
times[0].tv_usec = -4567;
times[1].tv_sec = 43210;
times[1].tv_usec = 1000;
ASSERT_THAT(LIBC_NAMESPACE::utimes(TEST_FILE, times), Fails(EINVAL));
ASSERT_THAT(LIBC_NAMESPACE::remove(TEST_FILE), Succeeds(0));
}