1 #include <stdio.h>
2 #include <fcntl.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <dirent.h>
6 #include <stdbool.h>
7 #include <string.h>
8 #include <sys/stat.h>
9
10 #ifndef O_NOATIME
11 # define O_NOATIME 0
12 #endif
13
14 static int
do_test(void)15 do_test (void)
16 {
17 char fname[] = "/tmp/jXXXXXX";
18 int fd = mkstemp (fname);
19 if (fd == -1)
20 {
21 puts ("mkstemp failed");
22 return 1;
23 }
24
25 write (fd, "hello", 5);
26 close (fd);
27
28 struct stat64 st;
29 if (stat64 (fname, &st) == -1)
30 {
31 puts ("first stat failed");
32 return 0;
33 }
34
35 /* Make sure there is enough time between the creation and the access. */
36 sleep (2);
37
38 fd = open (fname, O_RDONLY | O_NOATIME);
39 if (fd == -1)
40 {
41 puts ("first open failed");
42 return 1;
43 }
44
45 char buf[5];
46 read(fd, buf, sizeof (buf));
47 close(fd);
48
49 struct stat64 st2;
50 if (stat64 (fname, &st2) == -1)
51 {
52 puts ("second stat failed");
53 return 0;
54 }
55
56 bool no_noatime = false;
57 #ifdef _STATBUF_ST_NSEC
58 if (st.st_atim.tv_sec != st2.st_atim.tv_sec
59 || st.st_atim.tv_nsec != st2.st_atim.tv_nsec)
60 #else
61 if (st.st_atime != st2.st_atime)
62 #endif
63 {
64 puts ("file atime changed");
65 no_noatime = true;
66 }
67
68 unlink(fname);
69
70 strcpy(fname, "/tmp/dXXXXXX");
71 char *d = mkdtemp (fname);
72 if (d == NULL)
73 {
74 puts ("mkdtemp failed");
75 return 1;
76 }
77
78 if (stat64 (d, &st) == -1)
79 {
80 puts ("third stat failed");
81 return 0;
82 }
83 sleep (2);
84
85 fd = open64 (d, O_RDONLY|O_NDELAY|O_DIRECTORY|O_NOATIME);
86 if (fd == -1)
87 {
88 puts ("second open failed");
89 return 1;
90 }
91 DIR *dir = fdopendir (fd);
92 if (dir == NULL)
93 {
94 puts ("fdopendir failed");
95 return 1;
96 }
97
98 struct dirent *de;
99 while ((de = readdir (dir)) != NULL)
100 ;
101
102 closedir (dir);
103
104 if (stat64 (d, &st2) == -1)
105 {
106 puts ("fourth stat failed");
107 return 0;
108 }
109 #ifdef _STATBUF_ST_NSEC
110 if (!no_noatime
111 && (st.st_atim.tv_sec != st2.st_atim.tv_sec
112 || st.st_atim.tv_nsec != st2.st_atim.tv_nsec))
113 #else
114 if (!no_noatime && st.st_atime != st2.st_atime)
115 #endif
116 {
117 puts ("directory atime changed");
118 return 1;
119 }
120
121 rmdir(fname);
122
123 return 0;
124 }
125
126 #define TEST_FUNCTION do_test ()
127 #include "../test-skeleton.c"
128