Hey,

This diff adds a flag to du(1) to limit the depth of results that are displayed
to the user.

The semantics are equivalent to FreeBSD's, where it is mutually exclusive with
-a and -s, and du -d 0 is equivalent to du -s.

Thoughts?

William Orr

Index: usr.bin/du/du.1
===================================================================
RCS file: /cvs/src/usr.bin/du/du.1,v
retrieving revision 1.31
diff -u -b -w -p -r1.31 du.1
--- usr.bin/du/du.1     14 Feb 2014 18:17:50 -0000      1.31
+++ usr.bin/du/du.1     16 Sep 2014 05:39:39 -0000
@@ -38,7 +38,7 @@
 .Nd display disk usage statistics
 .Sh SYNOPSIS
 .Nm du
-.Op Fl a | s
+.Op Fl a | s | d Ar depth
 .Op Fl chkrx
 .Op Fl H | L | P
 .Op Ar
@@ -61,6 +61,10 @@ The options are as follows:
 Display an entry for each file in the file hierarchy.
 .It Fl c
 Display the grand total after all the arguments have been processed.
+.It Fl d Ar depth
+Display an entry for each file and directory up to
+.Ar depth
+levels
 .It Fl H
 Symbolic links on the command line are followed.
 Symbolic links encountered in the tree traversal are not followed.
Index: usr.bin/du/du.c
===================================================================
RCS file: /cvs/src/usr.bin/du/du.c,v
retrieving revision 1.25
diff -u -b -w -p -r1.25 du.c
--- usr.bin/du/du.c     20 May 2014 01:25:23 -0000      1.25
+++ usr.bin/du/du.c     16 Sep 2014 05:39:39 -0000
@@ -40,6 +40,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fts.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -60,15 +61,17 @@ main(int argc, char *argv[])
        long blocksize;
        quad_t totalblocks;
        int ftsoptions, listdirs, listfiles;
-       int Hflag, Lflag, aflag, cflag, hflag, kflag, sflag;
+       int Hflag, Lflag, aflag, cflag, hflag, kflag, sflag, dflag;
        int ch, notused, rval;
+       int maxdepth = -1;
        char **save;
+       const char *errstr = NULL;
 
        save = argv;
-       Hflag = Lflag = aflag = cflag = hflag = kflag = sflag = 0;
+       Hflag = Lflag = aflag = cflag = hflag = kflag = sflag = dflag = 0;
        totalblocks = 0;
        ftsoptions = FTS_PHYSICAL;
-       while ((ch = getopt(argc, argv, "HLPachksxr")) != -1)
+       while ((ch = getopt(argc, argv, "HLPachksxrd:")) != -1)
                switch (ch) {
                case 'H':
                        Hflag = 1;
@@ -103,6 +106,14 @@ main(int argc, char *argv[])
                case 'x':
                        ftsoptions |= FTS_XDEV;
                        break;
+               case 'd':
+                       maxdepth = (int)strtonum(optarg, 0, INT_MAX, &errstr);
+                       if (errstr) {
+                               warnx("max depth %s invalid: %s", optarg, 
errstr);
+                               usage();
+                       }
+                       dflag = 1;
+                       break;
                case '?':
                default:
                        usage();
@@ -129,11 +140,12 @@ main(int argc, char *argv[])
                ftsoptions |= FTS_LOGICAL;
        }
 
-       if (aflag) {
-               if (sflag)
+       if (aflag + sflag + dflag > 1)
                        usage();
+
+       if (aflag)
                listdirs = listfiles = 1;
-       } else if (sflag)
+       else if (sflag || dflag)
                listdirs = listfiles = 0;
        else {
                listfiles = 0;
@@ -172,7 +184,8 @@ main(int argc, char *argv[])
                         * root of a traversal, display the total.
                         */
                        if (listdirs ||
-                           (!listfiles && p->fts_level == FTS_ROOTLEVEL)) {
+                           (!listfiles && p->fts_level == FTS_ROOTLEVEL) ||
+                           p->fts_level <= maxdepth) {
                                prtout((quad_t)howmany(p->fts_number,
                                    (unsigned long)blocksize), p->fts_path,
                                    hflag);
@@ -193,7 +206,7 @@ main(int argc, char *argv[])
                         * If listing each file, or a non-directory file was
                         * the root of a traversal, display the total.
                         */
-                       if (listfiles || p->fts_level == FTS_ROOTLEVEL)
+                       if (listfiles || p->fts_level == FTS_ROOTLEVEL || 
p->fts_level <= maxdepth)
                                prtout(howmany(p->fts_statp->st_blocks,
                                    blocksize), p->fts_path, hflag);
                        p->fts_parent->fts_number += p->fts_statp->st_blocks;

Reply via email to