diff options
author | Rob Landley <rob@landley.net> | 2014-12-01 12:52:55 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2014-12-01 12:52:55 -0600 |
commit | 10e0d86c088a3eccc27095b51d753e05f3f3cbc8 (patch) | |
tree | c7c2658c41dc0049ceb09b687338c238b21e2791 | |
parent | ef6a773198040a05a56dec2261516fb149823cf6 (diff) | |
download | toybox-10e0d86c088a3eccc27095b51d753e05f3f3cbc8.tar.gz |
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
-rwxr-xr-x | tests/du.test | 3 | ||||
-rw-r--r-- | toys/posix/du.c | 9 |
2 files changed, 12 insertions, 0 deletions
diff --git a/tests/du.test b/tests/du.test index fabb800b..81fb5282 100755 --- a/tests/du.test +++ b/tests/du.test @@ -18,6 +18,9 @@ ln -s ../du_2 du_test/xyz # allocated file space is zero. testing "du counts symlinks without following" "du -ks du_test" "8\tdu_test\n" "" "" testing "du -L follows symlinks" "du -ksL du_test" "16\tdu_test\n" "" "" +ln -s . du_test/up +testing "du -L avoid endless loop" "du -ksL du_test" "16\tdu_test\n" "" "" +rm du_test/up # if -H and -L are specified, the last takes priority testing "du -HL follows symlinks" "du -ksHL du_test" "16\tdu_test\n" "" "" testing "du -H does not follow unspecified symlinks" "du -ksH du_test" "8\tdu_test\n" "" "" diff --git a/toys/posix/du.c b/toys/posix/du.c index 22a26d3a..00a7f68a 100644 --- a/toys/posix/du.c +++ b/toys/posix/du.c @@ -110,6 +110,15 @@ static int do_du(struct dirtree *node) if ((toys.optflags & FLAG_x) && (TT.st_dev != node->st.st_dev)) return 0; + // Don't loop endlessly on recursive directory symlink + if (toys.optflags & FLAG_L) { + struct dirtree *try = node; + + while ((try = try->parent)) + if (node->st.st_dev==try->st.st_dev && node->st.st_ino==try->st.st_ino) + return 0; + } + // Don't count hard links twice if (!(toys.optflags & FLAG_l) && !node->again) if (seen_inode(&TT.inodes, &node->st)) return 0; |