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;