Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't...
authorRob Landley <rob@landley.net>
Mon, 1 Dec 2014 18:52:55 +0000 (12:52 -0600)
committerRob Landley <rob@landley.net>
Mon, 1 Dec 2014 18:52:55 +0000 (12:52 -0600)
tests/du.test
toys/posix/du.c

index fabb800..81fb528 100755 (executable)
@@ -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" "" ""
index 22a26d3..00a7f68 100644 (file)
@@ -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;