[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-0001.htm>
More information about the Toybox
mailing list