- leave_dir (sp, p); \
- } while (0)
-
-/* Use these each of these to map a device/inode pair to an FTSENT. */
-struct Active_dir
-{
- dev_t dev;
- ino_t ino;
- FTSENT *fts_ent;
-};
-
-static bool
-AD_compare (void const *x, void const *y)
-{
- struct Active_dir const *ax = x;
- struct Active_dir const *ay = y;
- return ax->ino == ay->ino
- && ax->dev == ay->dev;
-}
-
-static size_t
-AD_hash (void const *x, size_t table_size)
-{
- struct Active_dir const *ax = x;
- return (uintmax_t) ax->ino % table_size;
-}
-
-static void
-enter_dir (FTS *fts, FTSENT *ent)
-{
- if (fts->active_dir_ht)
- {
- struct stat const *st = ent->fts_statp;
- struct Active_dir *ad = malloc (sizeof (struct Active_dir));
- struct Active_dir *ad_from_table;
-
- if (ad == NULL)
- goto give_up;
-
- ad->dev = st->st_dev;
- ad->ino = st->st_ino;
- ad->fts_ent = ent;
-
- /* See if we've already encountered this directory.
- This can happen when following symlinks as well as
- with a corrupted directory hierarchy. */
- ad_from_table = hash_insert (fts->active_dir_ht, ad);
-
- if (ad_from_table == NULL)
- {
- give_up:
- /* Insertion failed due to lack of memory. Free the hash
- table and turn off this sort of cycle detection. */
- hash_free (fts->active_dir_ht);
- fts->active_dir_ht = NULL;
- return;
- }
-
- if (ad_from_table != ad)
- {
- /* There was an entry with matching dev/inode already in the table.
- Record the fact that we've found a cycle. */
- ent->fts_cycle = ad_from_table->fts_ent;
- ent->fts_info = FTS_DC;
-
- /* ad was not inserted, so free it. */
- free (ad);
- }
- }
- else if (fts->cycle_state)
- {
- if (cycle_check (fts->cycle_state, ent->fts_statp))
- {
- /* FIXME: setting fts_cycle like this isn't proper.
- To do what the documentation requires, we'd have to
- go around the cycle again and find the right entry.
- But no callers in coreutils use the fts_cycle member. */
- ent->fts_cycle = ent;
- ent->fts_info = FTS_DC;
- }
- }
-}
-
-static void
-leave_dir (FTS *fts, FTSENT *ent)
-{
- if (fts->active_dir_ht)
- {
- struct stat const *st = ent->fts_statp;
- struct Active_dir obj;
- void *found;
- obj.dev = st->st_dev;
- obj.ino = st->st_ino;
- found = hash_delete (fts->active_dir_ht, &obj);
- if (!found)
- abort ();
- free (found);
- }
-}