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