mirror of
https://github.com/darlinghq/darling-xnu.git
synced 2024-11-26 22:10:24 +00:00
86 lines
2.8 KiB
C
86 lines
2.8 KiB
C
#include <sys/cdefs.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h>
|
|
#include <paths.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <darwintest.h>
|
|
#include <darwintest_utils.h>
|
|
|
|
T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
|
|
|
|
#define FILENAME "utimensat"
|
|
|
|
static const struct timespec tptr[][2] = {
|
|
{ { 0x12345678, 987654321 }, { 0x15263748, 123456789 }, },
|
|
|
|
{ { 0, UTIME_NOW }, { 0x15263748, 123456789 }, },
|
|
{ { 0x12345678, 987654321 }, { 0, UTIME_NOW }, },
|
|
{ { 0, UTIME_NOW }, { 0, UTIME_NOW }, },
|
|
|
|
{ { 0, UTIME_OMIT }, { 0x15263748, 123456789 }, },
|
|
{ { 0x12345678, 987654321 }, { 0, UTIME_OMIT }, },
|
|
{ { 0, UTIME_OMIT }, { 0, UTIME_OMIT }, },
|
|
|
|
{ { 0, UTIME_NOW }, { 0, UTIME_OMIT }, },
|
|
{ { 0, UTIME_OMIT }, { 0, UTIME_NOW }, },
|
|
};
|
|
|
|
T_DECL(utimensat, "Try various versions of utimensat")
|
|
{
|
|
T_SETUPBEGIN;
|
|
T_ASSERT_POSIX_ZERO(chdir(dt_tmpdir()), NULL);
|
|
// Skip the test if the current working directory is not on APFS.
|
|
struct statfs sfs = { 0 };
|
|
T_QUIET; T_ASSERT_POSIX_SUCCESS(statfs(".", &sfs), NULL);
|
|
if (memcmp(&sfs.f_fstypename[0], "apfs", strlen("apfs")) != 0) {
|
|
T_SKIP("utimensat is APFS-only, but working directory is non-APFS");
|
|
}
|
|
T_SETUPEND;
|
|
|
|
struct stat pre_st, post_st;
|
|
int fd;
|
|
|
|
T_ASSERT_POSIX_SUCCESS((fd = open(FILENAME, O_CREAT | O_RDWR, 0644)), NULL);
|
|
T_ASSERT_POSIX_ZERO(close(fd), NULL);
|
|
|
|
for (size_t i = 0; i < sizeof(tptr) / sizeof(tptr[0]); i++) {
|
|
T_LOG("=== {%ld, %ld} {%ld, %ld} ===",
|
|
tptr[i][0].tv_sec, tptr[i][0].tv_nsec,
|
|
tptr[i][1].tv_sec, tptr[i][1].tv_nsec);
|
|
|
|
struct timespec now;
|
|
clock_gettime(CLOCK_REALTIME, &now);
|
|
|
|
T_ASSERT_POSIX_ZERO(stat(FILENAME, &pre_st), NULL);
|
|
T_ASSERT_POSIX_ZERO(utimensat(AT_FDCWD, FILENAME, tptr[i], 0), NULL);
|
|
T_ASSERT_POSIX_ZERO(stat(FILENAME, &post_st), NULL);
|
|
|
|
if (tptr[i][0].tv_nsec == UTIME_NOW) {
|
|
T_ASSERT_GE(post_st.st_atimespec.tv_sec, now.tv_sec, NULL);
|
|
} else if (tptr[i][0].tv_nsec == UTIME_OMIT) {
|
|
T_ASSERT_EQ(post_st.st_atimespec.tv_sec, pre_st.st_atimespec.tv_sec, NULL);
|
|
T_ASSERT_EQ(post_st.st_atimespec.tv_nsec, pre_st.st_atimespec.tv_nsec, NULL);
|
|
} else {
|
|
T_ASSERT_EQ(post_st.st_atimespec.tv_sec, tptr[i][0].tv_sec, NULL);
|
|
T_ASSERT_EQ(post_st.st_atimespec.tv_nsec, tptr[i][0].tv_nsec, NULL);
|
|
}
|
|
|
|
if (tptr[i][1].tv_nsec == UTIME_NOW) {
|
|
T_ASSERT_GE(post_st.st_mtimespec.tv_sec, now.tv_sec, NULL);
|
|
} else if (tptr[i][1].tv_nsec == UTIME_OMIT) {
|
|
T_ASSERT_EQ(post_st.st_mtimespec.tv_sec, pre_st.st_mtimespec.tv_sec, NULL);
|
|
T_ASSERT_EQ(post_st.st_mtimespec.tv_nsec, pre_st.st_mtimespec.tv_nsec, NULL);
|
|
} else {
|
|
T_ASSERT_EQ(post_st.st_mtimespec.tv_sec, tptr[i][1].tv_sec, NULL);
|
|
T_ASSERT_EQ(post_st.st_mtimespec.tv_nsec, tptr[i][1].tv_nsec, NULL);
|
|
}
|
|
}
|
|
}
|