| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/fts-cycle.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /* Detect cycles in file tree walks. | - | ||||||||||||||||||
| 2 | - | |||||||||||||||||||
| 3 | Copyright (C) 2003-2006, 2009-2018 Free Software Foundation, Inc. | - | ||||||||||||||||||
| 4 | - | |||||||||||||||||||
| 5 | Written by Jim Meyering. | - | ||||||||||||||||||
| 6 | - | |||||||||||||||||||
| 7 | This program is free software: you can redistribute it and/or modify | - | ||||||||||||||||||
| 8 | it under the terms of the GNU General Public License as published by | - | ||||||||||||||||||
| 9 | the Free Software Foundation; either version 3 of the License, or | - | ||||||||||||||||||
| 10 | (at your option) any later version. | - | ||||||||||||||||||
| 11 | - | |||||||||||||||||||
| 12 | This program is distributed in the hope that it will be useful, | - | ||||||||||||||||||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||||||||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||||||||
| 15 | GNU General Public License for more details. | - | ||||||||||||||||||
| 16 | - | |||||||||||||||||||
| 17 | You should have received a copy of the GNU General Public License | - | ||||||||||||||||||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | - | ||||||||||||||||||
| 19 | - | |||||||||||||||||||
| 20 | #include "cycle-check.h" | - | ||||||||||||||||||
| 21 | #include "hash.h" | - | ||||||||||||||||||
| 22 | - | |||||||||||||||||||
| 23 | /* Use each of these to map a device/inode pair to an FTSENT. */ | - | ||||||||||||||||||
| 24 | struct Active_dir | - | ||||||||||||||||||
| 25 | { | - | ||||||||||||||||||
| 26 | dev_t dev; | - | ||||||||||||||||||
| 27 | ino_t ino; | - | ||||||||||||||||||
| 28 | FTSENT *fts_ent; | - | ||||||||||||||||||
| 29 | }; | - | ||||||||||||||||||
| 30 | - | |||||||||||||||||||
| 31 | static bool | - | ||||||||||||||||||
| 32 | AD_compare (void const *x, void const *y) | - | ||||||||||||||||||
| 33 | { | - | ||||||||||||||||||
| 34 | struct Active_dir const *ax = x; | - | ||||||||||||||||||
| 35 | struct Active_dir const *ay = y; | - | ||||||||||||||||||
| 36 | return ax->ino == ay->ino executed 1431 times by 3 tests: return ax->ino == ay->ino && ax->dev == ay->dev;Executed by:
| 1431 | ||||||||||||||||||
| 37 | && ax->dev == ay->dev; executed 1431 times by 3 tests: return ax->ino == ay->ino && ax->dev == ay->dev;Executed by:
| 1431 | ||||||||||||||||||
| 38 | } | - | ||||||||||||||||||
| 39 | - | |||||||||||||||||||
| 40 | static size_t | - | ||||||||||||||||||
| 41 | AD_hash (void const *x, size_t table_size) | - | ||||||||||||||||||
| 42 | { | - | ||||||||||||||||||
| 43 | struct Active_dir const *ax = x; | - | ||||||||||||||||||
| 44 | return (uintmax_t) ax->ino % table_size; executed 2858 times by 3 tests: return (uintmax_t) ax->ino % table_size;Executed by:
| 2858 | ||||||||||||||||||
| 45 | } | - | ||||||||||||||||||
| 46 | - | |||||||||||||||||||
| 47 | /* Set up the cycle-detection machinery. */ | - | ||||||||||||||||||
| 48 | - | |||||||||||||||||||
| 49 | static bool | - | ||||||||||||||||||
| 50 | setup_dir (FTS *fts) | - | ||||||||||||||||||
| 51 | { | - | ||||||||||||||||||
| 52 | if (fts->fts_options & (FTS_TIGHT_CYCLE_CHECK | FTS_LOGICAL))
| 530-14208 | ||||||||||||||||||
| 53 | { | - | ||||||||||||||||||
| 54 | enum { HT_INITIAL_SIZE = 31 }; | - | ||||||||||||||||||
| 55 | fts->fts_cycle.ht = hash_initialize (HT_INITIAL_SIZE, NULL, AD_hash, | - | ||||||||||||||||||
| 56 | AD_compare, free); | - | ||||||||||||||||||
| 57 | if (! fts->fts_cycle.ht)
| 0-530 | ||||||||||||||||||
| 58 | return false; never executed: return 0 ; | 0 | ||||||||||||||||||
| 59 | } executed 530 times by 3 tests: end of blockExecuted by:
| 530 | ||||||||||||||||||
| 60 | else | - | ||||||||||||||||||
| 61 | { | - | ||||||||||||||||||
| 62 | fts->fts_cycle.state = malloc (sizeof *fts->fts_cycle.state); | - | ||||||||||||||||||
| 63 | if (! fts->fts_cycle.state)
| 0-14208 | ||||||||||||||||||
| 64 | return false; never executed: return 0 ; | 0 | ||||||||||||||||||
| 65 | cycle_check_init (fts->fts_cycle.state); | - | ||||||||||||||||||
| 66 | } executed 14208 times by 6 tests: end of blockExecuted by:
| 14208 | ||||||||||||||||||
| 67 | - | |||||||||||||||||||
| 68 | return true; executed 14738 times by 6 tests: return 1 ;Executed by:
| 14738 | ||||||||||||||||||
| 69 | } | - | ||||||||||||||||||
| 70 | - | |||||||||||||||||||
| 71 | /* Enter a directory during a file tree walk. */ | - | ||||||||||||||||||
| 72 | - | |||||||||||||||||||
| 73 | static bool | - | ||||||||||||||||||
| 74 | enter_dir (FTS *fts, FTSENT *ent) | - | ||||||||||||||||||
| 75 | { | - | ||||||||||||||||||
| 76 | if (fts->fts_options & (FTS_TIGHT_CYCLE_CHECK | FTS_LOGICAL))
| 1389-100755 | ||||||||||||||||||
| 77 | { | - | ||||||||||||||||||
| 78 | struct stat const *st = ent->fts_statp; | - | ||||||||||||||||||
| 79 | struct Active_dir *ad = malloc (sizeof *ad); | - | ||||||||||||||||||
| 80 | struct Active_dir *ad_from_table; | - | ||||||||||||||||||
| 81 | - | |||||||||||||||||||
| 82 | if (!ad)
| 0-1389 | ||||||||||||||||||
| 83 | return false; never executed: return 0 ; | 0 | ||||||||||||||||||
| 84 | - | |||||||||||||||||||
| 85 | ad->dev = st->st_dev; | - | ||||||||||||||||||
| 86 | ad->ino = st->st_ino; | - | ||||||||||||||||||
| 87 | ad->fts_ent = ent; | - | ||||||||||||||||||
| 88 | - | |||||||||||||||||||
| 89 | /* See if we've already encountered this directory. | - | ||||||||||||||||||
| 90 | This can happen when following symlinks as well as | - | ||||||||||||||||||
| 91 | with a corrupted directory hierarchy. */ | - | ||||||||||||||||||
| 92 | ad_from_table = hash_insert (fts->fts_cycle.ht, ad); | - | ||||||||||||||||||
| 93 | - | |||||||||||||||||||
| 94 | if (ad_from_table != ad)
| 2-1387 | ||||||||||||||||||
| 95 | { | - | ||||||||||||||||||
| 96 | free (ad); | - | ||||||||||||||||||
| 97 | if (!ad_from_table)
| 0-2 | ||||||||||||||||||
| 98 | return false; never executed: return 0 ; | 0 | ||||||||||||||||||
| 99 | - | |||||||||||||||||||
| 100 | /* There was an entry with matching dev/inode already in the table. | - | ||||||||||||||||||
| 101 | Record the fact that we've found a cycle. */ | - | ||||||||||||||||||
| 102 | ent->fts_cycle = ad_from_table->fts_ent; | - | ||||||||||||||||||
| 103 | ent->fts_info = FTS_DC; | - | ||||||||||||||||||
| 104 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 105 | } executed 1389 times by 3 tests: end of blockExecuted by:
| 1389 | ||||||||||||||||||
| 106 | else | - | ||||||||||||||||||
| 107 | { | - | ||||||||||||||||||
| 108 | if (cycle_check (fts->fts_cycle.state, ent->fts_statp))
| 0-100755 | ||||||||||||||||||
| 109 | { | - | ||||||||||||||||||
| 110 | /* FIXME: setting fts_cycle like this isn't proper. | - | ||||||||||||||||||
| 111 | To do what the documentation requires, we'd have to | - | ||||||||||||||||||
| 112 | go around the cycle again and find the right entry. | - | ||||||||||||||||||
| 113 | But no callers in coreutils use the fts_cycle member. */ | - | ||||||||||||||||||
| 114 | ent->fts_cycle = ent; | - | ||||||||||||||||||
| 115 | ent->fts_info = FTS_DC; | - | ||||||||||||||||||
| 116 | } never executed: end of block | 0 | ||||||||||||||||||
| 117 | } executed 100755 times by 6 tests: end of blockExecuted by:
| 100755 | ||||||||||||||||||
| 118 | - | |||||||||||||||||||
| 119 | return true; executed 102144 times by 6 tests: return 1 ;Executed by:
| 102144 | ||||||||||||||||||
| 120 | } | - | ||||||||||||||||||
| 121 | - | |||||||||||||||||||
| 122 | /* Leave a directory during a file tree walk. */ | - | ||||||||||||||||||
| 123 | - | |||||||||||||||||||
| 124 | static void | - | ||||||||||||||||||
| 125 | leave_dir (FTS *fts, FTSENT *ent) | - | ||||||||||||||||||
| 126 | { | - | ||||||||||||||||||
| 127 | struct stat const *st = ent->fts_statp; | - | ||||||||||||||||||
| 128 | if (fts->fts_options & (FTS_TIGHT_CYCLE_CHECK | FTS_LOGICAL))
| 1387-100750 | ||||||||||||||||||
| 129 | { | - | ||||||||||||||||||
| 130 | struct Active_dir obj; | - | ||||||||||||||||||
| 131 | void *found; | - | ||||||||||||||||||
| 132 | obj.dev = st->st_dev; | - | ||||||||||||||||||
| 133 | obj.ino = st->st_ino; | - | ||||||||||||||||||
| 134 | found = hash_delete (fts->fts_cycle.ht, &obj); | - | ||||||||||||||||||
| 135 | if (!found)
| 0-1387 | ||||||||||||||||||
| 136 | abort (); never executed: abort (); | 0 | ||||||||||||||||||
| 137 | free (found); | - | ||||||||||||||||||
| 138 | } executed 1387 times by 3 tests: end of blockExecuted by:
| 1387 | ||||||||||||||||||
| 139 | else | - | ||||||||||||||||||
| 140 | { | - | ||||||||||||||||||
| 141 | FTSENT *parent = ent->fts_parent; | - | ||||||||||||||||||
| 142 | if (parent != NULL && 0 <= parent->fts_level)
| 0-100750 | ||||||||||||||||||
| 143 | CYCLE_CHECK_REFLECT_CHDIR_UP (fts->fts_cycle.state, never executed: abort ();executed 1632 times by 5 tests: end of blockExecuted by:
executed 95861 times by 5 tests: end of blockExecuted by:
| 0-95861 | ||||||||||||||||||
| 144 | *(parent->fts_statp), *st); | - | ||||||||||||||||||
| 145 | } executed 100750 times by 6 tests: end of blockExecuted by:
| 100750 | ||||||||||||||||||
| 146 | } | - | ||||||||||||||||||
| 147 | - | |||||||||||||||||||
| 148 | /* Free any memory used for cycle detection. */ | - | ||||||||||||||||||
| 149 | - | |||||||||||||||||||
| 150 | static void | - | ||||||||||||||||||
| 151 | free_dir (FTS *sp) | - | ||||||||||||||||||
| 152 | { | - | ||||||||||||||||||
| 153 | if (sp->fts_options & (FTS_TIGHT_CYCLE_CHECK | FTS_LOGICAL))
| 530-14208 | ||||||||||||||||||
| 154 | { | - | ||||||||||||||||||
| 155 | if (sp->fts_cycle.ht)
| 0-530 | ||||||||||||||||||
| 156 | hash_free (sp->fts_cycle.ht); executed 530 times by 3 tests: hash_free (sp->fts_cycle.ht);Executed by:
| 530 | ||||||||||||||||||
| 157 | } executed 530 times by 3 tests: end of blockExecuted by:
| 530 | ||||||||||||||||||
| 158 | else | - | ||||||||||||||||||
| 159 | free (sp->fts_cycle.state); executed 14208 times by 6 tests: free (sp->fts_cycle.state);Executed by:
| 14208 | ||||||||||||||||||
| 160 | } | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |