-
Notifications
You must be signed in to change notification settings - Fork 192
/
utimensat.c
85 lines (70 loc) · 2.75 KB
/
utimensat.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#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);
}
}
}