]> git.saurik.com Git - apple/xnu.git/blame - tests/utimensat.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / utimensat.c
CommitLineData
5ba3f43e
A
1#include <sys/cdefs.h>
2#include <sys/param.h>
3#include <sys/stat.h>
4#include <sys/time.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <limits.h>
8#include <paths.h>
9#include <stdio.h>
10#include <string.h>
11#include <unistd.h>
12
13#include <darwintest.h>
14#include <darwintest_utils.h>
15
cb323159
A
16T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
17
5ba3f43e
A
18#define FILENAME "utimensat"
19
20static const struct timespec tptr[][2] = {
21 { { 0x12345678, 987654321 }, { 0x15263748, 123456789 }, },
22
23 { { 0, UTIME_NOW }, { 0x15263748, 123456789 }, },
24 { { 0x12345678, 987654321 }, { 0, UTIME_NOW }, },
25 { { 0, UTIME_NOW }, { 0, UTIME_NOW }, },
26
27 { { 0, UTIME_OMIT }, { 0x15263748, 123456789 }, },
28 { { 0x12345678, 987654321 }, { 0, UTIME_OMIT }, },
29 { { 0, UTIME_OMIT }, { 0, UTIME_OMIT }, },
30
31 { { 0, UTIME_NOW }, { 0, UTIME_OMIT }, },
32 { { 0, UTIME_OMIT }, { 0, UTIME_NOW }, },
33};
34
35T_DECL(utimensat, "Try various versions of utimensat")
36{
37 T_SETUPBEGIN;
38 T_ASSERT_POSIX_ZERO(chdir(dt_tmpdir()), NULL);
a39ff7e2
A
39 // Skip the test if the current working directory is not on APFS.
40 struct statfs sfs = { 0 };
41 T_QUIET; T_ASSERT_POSIX_SUCCESS(statfs(".", &sfs), NULL);
42 if (memcmp(&sfs.f_fstypename[0], "apfs", strlen("apfs")) != 0) {
43 T_SKIP("utimensat is APFS-only, but working directory is non-APFS");
44 }
5ba3f43e
A
45 T_SETUPEND;
46
47 struct stat pre_st, post_st;
48 int fd;
49
0a7de745 50 T_ASSERT_POSIX_SUCCESS((fd = open(FILENAME, O_CREAT | O_RDWR, 0644)), NULL);
5ba3f43e
A
51 T_ASSERT_POSIX_ZERO(close(fd), NULL);
52
0a7de745
A
53 for (size_t i = 0; i < sizeof(tptr) / sizeof(tptr[0]); i++) {
54 T_LOG("=== {%ld, %ld} {%ld, %ld} ===",
55 tptr[i][0].tv_sec, tptr[i][0].tv_nsec,
56 tptr[i][1].tv_sec, tptr[i][1].tv_nsec);
5ba3f43e
A
57
58 struct timespec now;
59 clock_gettime(CLOCK_REALTIME, &now);
60
61 T_ASSERT_POSIX_ZERO(stat(FILENAME, &pre_st), NULL);
62 T_ASSERT_POSIX_ZERO(utimensat(AT_FDCWD, FILENAME, tptr[i], 0), NULL);
63 T_ASSERT_POSIX_ZERO(stat(FILENAME, &post_st), NULL);
64
65 if (tptr[i][0].tv_nsec == UTIME_NOW) {
66 T_ASSERT_GE(post_st.st_atimespec.tv_sec, now.tv_sec, NULL);
67 } else if (tptr[i][0].tv_nsec == UTIME_OMIT) {
68 T_ASSERT_EQ(post_st.st_atimespec.tv_sec, pre_st.st_atimespec.tv_sec, NULL);
69 T_ASSERT_EQ(post_st.st_atimespec.tv_nsec, pre_st.st_atimespec.tv_nsec, NULL);
70 } else {
71 T_ASSERT_EQ(post_st.st_atimespec.tv_sec, tptr[i][0].tv_sec, NULL);
72 T_ASSERT_EQ(post_st.st_atimespec.tv_nsec, tptr[i][0].tv_nsec, NULL);
73 }
74
75 if (tptr[i][1].tv_nsec == UTIME_NOW) {
76 T_ASSERT_GE(post_st.st_mtimespec.tv_sec, now.tv_sec, NULL);
77 } else if (tptr[i][1].tv_nsec == UTIME_OMIT) {
78 T_ASSERT_EQ(post_st.st_mtimespec.tv_sec, pre_st.st_mtimespec.tv_sec, NULL);
79 T_ASSERT_EQ(post_st.st_mtimespec.tv_nsec, pre_st.st_mtimespec.tv_nsec, NULL);
80 } else {
81 T_ASSERT_EQ(post_st.st_mtimespec.tv_sec, tptr[i][1].tv_sec, NULL);
82 T_ASSERT_EQ(post_st.st_mtimespec.tv_nsec, tptr[i][1].tv_nsec, NULL);
83 }
84 }
85}