diff options
author | Elliott Hughes <enh@google.com> | 2019-08-06 13:21:21 -0700 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-08-09 20:35:09 -0500 |
commit | 99cfd03d8576de6ac760269f66eb37e3c732243f (patch) | |
tree | 57baaa5f094bed7fb644dc7a33a15ffdf96aacb3 | |
parent | 5fbdad94ac145c59308200d689eea40e79a7ec5e (diff) | |
download | toybox-99cfd03d8576de6ac760269f66eb37e3c732243f.tar.gz |
find: fix dangling symlink behavior.
ENOENT is ignored, but other errors are reported.
-rw-r--r-- | lib/dirtree.c | 2 | ||||
-rwxr-xr-x | tests/find.test | 4 | ||||
-rw-r--r-- | toys/posix/find.c | 6 |
3 files changed, 9 insertions, 3 deletions
diff --git a/lib/dirtree.c b/lib/dirtree.c index c5cf654a..e44df66c 100644 --- a/lib/dirtree.c +++ b/lib/dirtree.c @@ -36,7 +36,7 @@ struct dirtree *dirtree_add_node(struct dirtree *parent, char *name, int flags) int fd = parent ? parent->dirfd : AT_FDCWD; if (fstatat(fd, name, &st,AT_SYMLINK_NOFOLLOW*!(flags&DIRTREE_SYMFOLLOW))) { - if (flags&DIRTREE_STATLESS) statless++; + if ((flags&DIRTREE_STATLESS) && errno == ENOENT) statless++; else goto error; } if (S_ISLNK(st.st_mode)) { diff --git a/tests/find.test b/tests/find.test index ab84fb07..cbca8e76 100755 --- a/tests/find.test +++ b/tests/find.test @@ -104,6 +104,10 @@ testing "-printf" "find dir -name file -printf '%f %p %P %s'" \ "file dir/file file 0" "" "" testing "-printf .N" "find dir -name file -printf %.2f" "fi" "" "" +ln -s does-not-exist dir/dangler +ln -s looper dir/looper +testing "-L dangling link" "LANG=C find -L dir -name file 2>&1 | sed s/\'//g" \ + "dir/file\nfind: dir/looper: Too many levels of symbolic links\n" "" "" testing "-false" "find dir -false" "" "" "" testing "-true" "find dir/file -true" "dir/file\n" "" "" diff --git a/toys/posix/find.c b/toys/posix/find.c index 5fc9b0ce..782cc3bc 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -211,7 +211,8 @@ static int do_find(struct dirtree *new) struct double_list *argdata = TT.argdata; char *s, **ss; - recurse = DIRTREE_COMEAGAIN|(DIRTREE_SYMFOLLOW*!!(toys.optflags&FLAG_L)); + recurse = DIRTREE_STATLESS|DIRTREE_COMEAGAIN| + (DIRTREE_SYMFOLLOW*!!(toys.optflags&FLAG_L)); // skip . and .. below topdir, handle -xdev and -depth if (new) { @@ -669,7 +670,8 @@ void find_main(void) // Loop through paths for (i = 0; i < len; i++) - dirtree_flagread(ss[i], DIRTREE_SYMFOLLOW*!!(toys.optflags&(FLAG_H|FLAG_L)), + dirtree_flagread(ss[i], + DIRTREE_STATLESS|(DIRTREE_SYMFOLLOW*!!(toys.optflags&(FLAG_H|FLAG_L))), do_find); execdir(0, 1); |