about summary refs log tree commit diff
path: root/dirent/tst-fdopendir.c
blob: d6a24f47db25b7b6f638682f49161597c3e9354c (plain) (blame)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>

#include <support/xunistd.h>

#ifndef O_NOATIME
# define O_NOATIME	0
#endif

static int
do_test (void)
{
  char fname[] = "/tmp/jXXXXXX";
  int fd = mkstemp (fname);
  if (fd == -1)
    {
      puts ("mkstemp failed");
      return 1;
    }

  xwrite (fd, "hello", 5);
  close (fd);

  struct stat64 st;
  if (stat64 (fname, &st) == -1)
    {
      puts ("first stat failed");
      return 0;
    }

  /* Make sure there is enough time between the creation and the access.  */
  sleep (2);

  fd = open (fname, O_RDONLY | O_NOATIME);
  if (fd == -1)
    {
      puts ("first open failed");
      return 1;
    }

  char buf[5];
  xread(fd, buf, sizeof (buf));

  close(fd);

  struct stat64 st2;
  if (stat64 (fname, &st2) == -1)
    {
      puts ("second stat failed");
      return 0;
    }

  bool no_noatime = false;
#ifdef _STATBUF_ST_NSEC
  if (st.st_atim.tv_sec != st2.st_atim.tv_sec
      || st.st_atim.tv_nsec != st2.st_atim.tv_nsec)
#else
  if (st.st_atime != st2.st_atime)
#endif
    {
      puts ("file atime changed");
      no_noatime = true;
    }

  unlink(fname);

  strcpy(fname, "/tmp/dXXXXXX");
  char *d = mkdtemp (fname);
  if (d == NULL)
    {
      puts ("mkdtemp failed");
      return 1;
    }

  if (stat64 (d, &st) == -1)
    {
      puts ("third stat failed");
      return 0;
    }
  sleep (2);

  fd = open64 (d, O_RDONLY|O_NDELAY|O_DIRECTORY|O_NOATIME);
  if (fd == -1)
    {
      puts ("second open failed");
      return 1;
    }
  DIR *dir = fdopendir (fd);
  if (dir == NULL)
    {
      puts ("fdopendir failed");
      return 1;
    }

  struct dirent *de;
  while ((de = readdir (dir)) != NULL)
    ;

  closedir (dir);

  if (stat64 (d, &st2) == -1)
    {
      puts ("fourth stat failed");
      return 0;
    }
#ifdef _STATBUF_ST_NSEC
  if (!no_noatime
      && (st.st_atim.tv_sec != st2.st_atim.tv_sec
	 || st.st_atim.tv_nsec != st2.st_atim.tv_nsec))
#else
  if (!no_noatime && st.st_atime != st2.st_atime)
#endif
    {
      puts ("directory atime changed");
      return 1;
    }

  rmdir(fname);

  return 0;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"