diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2017-07-09 16:35:38 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2017-07-09 16:35:38 -0400 |
commit | 2328d8dbb5a8c774afb99d363b6e98cd25ee304d (patch) | |
tree | 53822ecfebc872335e9b13f2fb255f0b2aa808d6 | |
parent | f4eed3b771a987ef441fea49ababc356a2933086 (diff) | |
download | bfs-2328d8dbb5a8c774afb99d363b6e98cd25ee304d.tar.xz |
Handle ENOTDIR the same as ENOENT
For a/b/c, ENOTDIR is returned instead of ENOENT if a or b are not
directories. Handle this uniformly when detecting broken symlinks,
readdir races, etc.
-rw-r--r-- | bftw.c | 2 | ||||
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | printf.c | 1 | ||||
-rwxr-xr-x | tests.sh | 10 | ||||
-rw-r--r-- | tests/test_L.out | 1 | ||||
-rw-r--r-- | tests/test_L_depth.out | 1 | ||||
-rw-r--r-- | tests/test_L_xtype_l.out | 1 | ||||
-rw-r--r-- | tests/test_colors.out | 1 | ||||
-rw-r--r-- | tests/test_follow.out | 1 | ||||
-rw-r--r-- | tests/test_printf_types.out | 1 | ||||
-rw-r--r-- | tests/test_xtype_l.out | 1 |
11 files changed, 21 insertions, 3 deletions
@@ -836,7 +836,7 @@ static void bftw_init_buffers(struct bftw_state *state, const struct dirent *de) || (ftwbuf->typeflag == BFTW_LNK && follow) || (ftwbuf->typeflag == BFTW_DIR && (detect_cycles || xdev))) { int ret = ftwbuf_stat(ftwbuf, &state->statbuf); - if (ret != 0 && follow && errno == ENOENT) { + if (ret != 0 && follow && (errno == ENOENT || errno == ENOTDIR)) { // Could be a broken symlink, retry without following ftwbuf->at_flags = AT_SYMLINK_NOFOLLOW; ret = ftwbuf_stat(ftwbuf, &state->statbuf); @@ -51,7 +51,7 @@ struct eval_state { */ static bool eval_should_ignore(const struct eval_state *state, int error) { return state->cmdline->ignore_races - && error == ENOENT + && (error == ENOENT || errno == ENOTDIR) && state->ftwbuf->depth > 0; } @@ -788,7 +788,7 @@ bool eval_xtype(const struct expr *expr, struct eval_state *state) { struct stat sb; if (fstatat(ftwbuf->at_fd, ftwbuf->at_path, &sb, at_flags) != 0) { - if (!follow && errno == ENOENT) { + if (!follow && (errno == ENOENT || errno == ENOTDIR)) { // Broken symlink return eval_type(expr, state); } else { @@ -371,6 +371,7 @@ static int bfs_printf_Y(FILE *file, const struct bfs_printf_directive *directive type = "L"; break; case ENOENT: + case ENOTDIR: type = "N"; break; } @@ -74,6 +74,7 @@ function make_links() { ln -s ../../d "$1/d/e/g" ln -s d/e "$1/h" ln -s q "$1/d/e/i" + ln -s b/c "$1/j" } make_links "$TMP/links" @@ -299,6 +300,7 @@ gnu_tests=( test_flag_double_dash test_ignore_readdir_race test_ignore_readdir_race_root + test_ignore_readdir_race_notdir test_perm_222_slash test_perm_644_slash test_perm_symbolic_slash @@ -797,6 +799,14 @@ function test_ignore_readdir_race_root() { ! $BFS basic/nonexistent -ignore_readdir_race 2>/dev/null } +function test_ignore_readdir_race_notdir() { + # Check -ignore_readdir_race handling when a directory is replaced with a file + rm -rf scratch/* + touchp scratch/foo/bar + + $BFS scratch -mindepth 1 -ignore_readdir_race -execdir rm -r '{}' \; -execdir touch '{}' \; +} + function test_perm_222() { bfs_diff perms -perm 222 } diff --git a/tests/test_L.out b/tests/test_L.out index 36087e8..f9ded0a 100644 --- a/tests/test_L.out +++ b/tests/test_L.out @@ -4,6 +4,7 @@ links/b links/c links/d links/h +links/j links/d/e links/h/f links/h/g diff --git a/tests/test_L_depth.out b/tests/test_L_depth.out index 36087e8..f9ded0a 100644 --- a/tests/test_L_depth.out +++ b/tests/test_L_depth.out @@ -4,6 +4,7 @@ links/b links/c links/d links/h +links/j links/d/e links/h/f links/h/g diff --git a/tests/test_L_xtype_l.out b/tests/test_L_xtype_l.out index 1052fc0..57bee1b 100644 --- a/tests/test_L_xtype_l.out +++ b/tests/test_L_xtype_l.out @@ -1,5 +1,6 @@ links/b links/h +links/j links/h/g links/h/i links/d/e/i diff --git a/tests/test_colors.out b/tests/test_colors.out index a9ab84a..8c8b244 100644 --- a/tests/test_colors.out +++ b/tests/test_colors.out @@ -2,6 +2,7 @@ [01;34mlinks/[0m[01;34md[0m [01;34mlinks/[0m[01;36mb[0m [01;34mlinks/[0m[01;36mh[0m +[01;34mlinks/[0m[40;31;01mj[0m [01;34mlinks/[0ma [01;34mlinks/[0mc [01;34mlinks/d/[0m[01;34me[0m diff --git a/tests/test_follow.out b/tests/test_follow.out index 36087e8..f9ded0a 100644 --- a/tests/test_follow.out +++ b/tests/test_follow.out @@ -4,6 +4,7 @@ links/b links/c links/d links/h +links/j links/d/e links/h/f links/h/g diff --git a/tests/test_printf_types.out b/tests/test_printf_types.out index 94fa833..bd89b47 100644 --- a/tests/test_printf_types.out +++ b/tests/test_printf_types.out @@ -5,6 +5,7 @@ (links/d) () d d (links/d/e) () d d (links/h) (d/e) l d +(links/j) (b/c) l N (links/d/e/f) () d d (links/d/e/i) (q) l N (links/d/e/g) (../../d) l d diff --git a/tests/test_xtype_l.out b/tests/test_xtype_l.out index e5e13fc..2d1293f 100644 --- a/tests/test_xtype_l.out +++ b/tests/test_xtype_l.out @@ -1 +1,2 @@ +links/j links/d/e/i |