This source file includes following definitions.
- perror_exit
- fts_dealloc
- remove_tree
- main
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 #include <config.h>
  18 
  19 #include <fts_.h>
  20 
  21 #include <errno.h>
  22 #include <fcntl.h>
  23 #include <stdio.h>
  24 #include <stdlib.h>
  25 #include <string.h>
  26 #include <sys/stat.h>
  27 #include <unistd.h>
  28 
  29 #define BASE "t-fts.tmp"
  30 static char base[] = BASE; 
  31 static char const base_d[] = BASE "/d";
  32 static char *const argv[2] = { base, 0 };
  33 
  34 static void
  35 perror_exit (char const *message, int status)
     
  36 {
  37   perror (message);
  38   exit (status);
  39 }
  40 
  41 
  42 static void
  43 fts_dealloc (void)
     
  44 {
  45   static char dir[] = "./";
  46   static char *const curr_dir[2] = { dir, 0 };
  47   FTS *ftsp = fts_open (curr_dir, FTS_NOSTAT | FTS_PHYSICAL | FTS_CWDFD, 0);
  48   if (ftsp)
  49     {
  50       if (fts_close (ftsp) != 0)
  51         perror_exit ("fts_close", 9);
  52     }
  53   else
  54     perror_exit (base, 10);
  55 }
  56 
  57 
  58 static void
  59 remove_tree (void)
     
  60 {
  61   FTSENT *e;
  62   FTS *ftsp = fts_open (argv, FTS_NOSTAT | FTS_PHYSICAL | FTS_CWDFD, 0);
  63   if (ftsp)
  64     {
  65       while ((e = fts_read (ftsp)))
  66         {
  67           int status = 0;
  68           switch (e->fts_info)
  69             {
  70             case FTS_DP:
  71               status = unlinkat (ftsp->fts_cwd_fd, e->fts_accpath,
  72                                  AT_REMOVEDIR);
  73               break;
  74 
  75             case FTS_F: case FTS_NSOK:
  76               status = unlinkat (ftsp->fts_cwd_fd, e->fts_accpath, 0);
  77               break;
  78             }
  79           if (status != 0)
  80             perror_exit (e->fts_path, 1);
  81         }
  82       if (fts_close (ftsp) != 0)
  83         perror_exit ("fts_close", 2);
  84     }
  85   else if (errno != ENOENT)
  86     perror_exit (base, 3);
  87 }
  88 
  89 int
  90 main (void)
     
  91 {
  92   FTS *ftsp;
  93   FTSENT *e;
  94   char buf[sizeof BASE + 100];
  95   int i;
  96   enum { needles = 4 };
  97   int needles_seen = 0;
  98   struct stat st;
  99 
 100   remove_tree ();
 101 
 102   
 103 
 104 
 105 
 106 
 107 
 108   if (mkdir (BASE, 0777) != 0)
 109     perror_exit (base, 4);
 110   if (mkdir (base_d, 0777) != 0)
 111     perror_exit (base_d, 5);
 112   for (i = 1; i <= 65536; i++)
 113     {
 114       sprintf (buf, "%s/d/%i", base, i);
 115       if (mkdir (buf, 0777) != 0)
 116         {
 117           if (errno == EMFILE || errno == EMLINK)
 118             break;
 119           if (i <= needles)
 120             perror_exit (buf, 77);
 121           break;
 122         }
 123       if (needles < i && stat (base_d, &st) == 0 && st.st_nlink != i + 2)
 124         break;
 125     }
 126 
 127   
 128   for (i = 1; i <= needles; i++)
 129     {
 130       int fd;
 131       sprintf (buf, "%s/d/%d/needle", base, i);
 132       fd = open (buf, O_WRONLY | O_CREAT, 0666);
 133       if (fd < 0 || close (fd) != 0)
 134         perror_exit (buf, 77);
 135     }
 136 
 137   
 138   ftsp = fts_open (argv, FTS_SEEDOT | FTS_NOSTAT | FTS_PHYSICAL | FTS_CWDFD, 0);
 139   if (!ftsp)
 140     perror_exit (base, 6);
 141   while ((e = fts_read (ftsp)))
 142     needles_seen += strcmp (e->fts_name, "needle") == 0;
 143   int fts_read_errno = errno;
 144   fflush (stdout);
 145   if (fts_read_errno)
 146     {
 147       errno = fts_read_errno;
 148       perror_exit ("fts_read", 7);
 149     }
 150   if (fts_close (ftsp) != 0)
 151     perror_exit (base, 8);
 152 
 153   
 154   if (needles_seen != needles)
 155     {
 156       fprintf (stderr, "%d needles found (should be %d)\n",
 157                needles_seen, needles);
 158       return 1;
 159     }
 160 
 161   remove_tree ();
 162   if (stat (base, &st) == 0)
 163     {
 164       fprintf (stderr, "fts could not remove directory\n");
 165       return 1;
 166     }
 167 
 168   fts_dealloc ();
 169 
 170   return 0;
 171 }