[Toybox] What does the du.c patch do?

Ashwini Sharma ak.ashwini1981 at gmail.com
Mon Dec 1 03:40:19 PST 2014


Hi Rob,

My patch was


+// is recursive tree
+static int is_recursive_loop(struct dirtree *node)
+{
+  struct dirtree *tmp = node;
+
+  while ((tmp = tmp->parent)) {
+    if ((tmp->st.st_ino == node->st.st_ino) &&
+        (tmp->st.st_dev == node->st.st_dev))
+      return 1;
+  }
+  return 0;
+}
+
 // dirtree callback, comput/display size of node
 static int do_du(struct dirtree *node)
 {
@@ -114,6 +127,8 @@
   if (!(toys.optflags & FLAG_l) && !node->again)
     if (seen_inode(&TT.inodes, &node->st)) return 0;

+  if (is_recursive_loop(node)) goto ADD;
+
   // Collect child info before printing directory size
   if (S_ISDIR(node->st.st_mode)) {
     if (!node->again) {
@@ -121,7 +136,7 @@
       return DIRTREE_COMEAGAIN | (DIRTREE_SYMFOLLOW*!!(toys.optflags &
FLAG_L));
     } else TT.depth--;
   }
-
+ADD:
   node->extra += node->st.st_blocks;
   if (node->parent) node->parent->extra += node->extra;

and not the one you mentioned.

This patch is handling the case, of self point symlinks.

$ mkdir sub
$ cd sub
$ ln -s ../sub lnk
$ cd ../
$ du -L sub

without my patch it will keep looping. This patch stops from this looping.

Thanks,
Ashwini

On Sun, Nov 30, 2014 at 6:03 AM, Rob Landley <rob at landley.net> wrote:

> Going through Ashwini's patch stack from last month. (Sorry for the delay,
> but I think I applied all the trivial ones in earlier passes.)
>
> What does the du.c patch do?
>
>   $ mkdir sub
>   $ ln -s . sub/here
>   $ ln -s loop sub/loop
>   $ ./toybox du sub
>   4     sub
>
> There's also a hardlink filter (disabled via -l)...
>
> I'm tempted to add the following to lib/dirtree.c
>
> +// Have we already seen this node?
> +int dirtree_seen(struct dirtree *try, struct stat *st)
> +{
> +  while (try) {
> +    if (try->st.st_ino==st->st_ino && try->st.st_dev==st->st_dev) return
> 1;
> +    try = try->parent;
> +  }
> +
> +  return 0;
> +}
> +
>
> But the existing user I can think of that's already doing this is in cp.c:
>
>     // Detect recursive copies via repeated top node (cp -R .. .) or
>     // identical source/target (fun with hardlinks).
>     if ((TT.top.st_dev == try->st.st_dev && TT.top.st_ino == try->st.st_ino
>          && (catch = TT.destname))
>         || (!fstatat(cfd, catch, &cst, 0) && cst.st_dev == try->st.st_dev
>          && cst.st_ino == try->st.st_ino))
>     {
>       error_msg("'%s' is '%s'", catch, err = dirtree_path(try, 0));
>       free(err);
>
>       return 0;
>     }
>
> Which seems to work?
>
> Anyway, could you give me a testcase where the du.c patch you submitted
> makes a
> difference?
>
> Rob
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.landley.net/pipermail/toybox-landley.net/attachments/20141201/cf7d290e/attachment-0003.htm>


More information about the Toybox mailing list