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
14static int
15do_test (void)
16{
17 char fname[] = "/tmp/jXXXXXX";
18 int fd = mkstemp (template: fname);
19 if (fd == -1)
20 {
21 puts (s: "mkstemp failed");
22 return 1;
23 }
24
25 write (fd, "hello", 5);
26 close (fd: fd);
27
28 struct stat64 st;
29 if (stat64 (file: fname, buf: &st) == -1)
30 {
31 puts (s: "first stat failed");
32 return 0;
33 }
34
35 /* Make sure there is enough time between the creation and the access. */
36 sleep (seconds: 2);
37
38 fd = open (file: fname, O_RDONLY | O_NOATIME);
39 if (fd == -1)
40 {
41 puts (s: "first open failed");
42 return 1;
43 }
44
45 char buf[5];
46 read(fd, buf, sizeof (buf));
47 close(fd: fd);
48
49 struct stat64 st2;
50 if (stat64 (file: fname, buf: &st2) == -1)
51 {
52 puts (s: "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 (s: "file atime changed");
65 no_noatime = true;
66 }
67
68 unlink(name: fname);
69
70 strcpy(fname, "/tmp/dXXXXXX");
71 char *d = mkdtemp (template: fname);
72 if (d == NULL)
73 {
74 puts (s: "mkdtemp failed");
75 return 1;
76 }
77
78 if (stat64 (file: d, buf: &st) == -1)
79 {
80 puts (s: "third stat failed");
81 return 0;
82 }
83 sleep (seconds: 2);
84
85 fd = open64 (file: d, O_RDONLY|O_NDELAY|O_DIRECTORY|O_NOATIME);
86 if (fd == -1)
87 {
88 puts (s: "second open failed");
89 return 1;
90 }
91 DIR *dir = fdopendir (fd: fd);
92 if (dir == NULL)
93 {
94 puts (s: "fdopendir failed");
95 return 1;
96 }
97
98 struct dirent *de;
99 while ((de = readdir (dirp: dir)) != NULL)
100 ;
101
102 closedir (dirp: dir);
103
104 if (stat64 (file: d, buf: &st2) == -1)
105 {
106 puts (s: "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 (s: "directory atime changed");
118 return 1;
119 }
120
121 rmdir(path: fname);
122
123 return 0;
124}
125
126#define TEST_FUNCTION do_test ()
127#include "../test-skeleton.c"
128

source code of glibc/dirent/tst-fdopendir.c