From b46da967104df09edcad706e5e8ef31326a113dd Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 6 Feb 2016 22:49:35 -0500 Subject: bftw: Don't give up when following a broken symlink. --- bftw.c | 10 +++++++++- tests.sh | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/bftw.c b/bftw.c index a49cbed..e445432 100644 --- a/bftw.c +++ b/bftw.c @@ -631,7 +631,15 @@ static void bftw_init_buffers(struct bftw_state *state, const struct dirent *de) || ftwbuf->typeflag == BFTW_UNKNOWN || (ftwbuf->typeflag == BFTW_LNK && follow)) { int flags = follow ? 0 : AT_SYMLINK_NOFOLLOW; - if (ftwbuf_stat(ftwbuf, &state->statbuf, flags) != 0) { + + int ret = ftwbuf_stat(ftwbuf, &state->statbuf, flags); + if (ret != 0 && follow && errno == ENOENT) { + // Could be a broken symlink, retry without following + flags = AT_SYMLINK_NOFOLLOW; + ret = ftwbuf_stat(ftwbuf, &state->statbuf, flags); + } + + if (ret != 0) { state->error = errno; ftwbuf_set_error(ftwbuf, state->error); } diff --git a/tests.sh b/tests.sh index 0a2f60a..493bfab 100755 --- a/tests.sh +++ b/tests.sh @@ -36,6 +36,7 @@ function links_structure() { mkdir -p "$1/d/e" ln -s ../../d "$1/d/e/f" touchp "$1/d/e/g" + ln -s q "$1/d/e/h" } # Checks for any (order-independent) differences between bfs and find @@ -168,7 +169,12 @@ function test_0023() { find_diff -H "$1" -newer "$1/d/e/f" } -for i in {1..23}; do +function test_0024() { + links_structure "$1" + find_diff -H "$1/d/e/h" +} + +for i in {1..24}; do dir="$(mktemp -d "${TMPDIR:-/tmp}"/bfs.XXXXXXXXXX)" test="test_$(printf '%04d' $i)" "$test" "$dir" -- cgit v1.2.3