summaryrefslogtreecommitdiffstats
path: root/usr.bin/du
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1997-12-29 20:56:21 +0000
committerjkh <jkh@FreeBSD.org>1997-12-29 20:56:21 +0000
commit1034d83c4db94bf5e9e6c95ee9f414f1de8feb5d (patch)
tree45761b56021dce8464d4a80b99ebce6344fa64b5 /usr.bin/du
parent974e4200297fde7cb55b0e1f3009cb254b49d526 (diff)
downloadFreeBSD-src-1034d83c4db94bf5e9e6c95ee9f414f1de8feb5d.zip
FreeBSD-src-1034d83c4db94bf5e9e6c95ee9f414f1de8feb5d.tar.gz
* add a -c option which displays the grand total of all files
counted. * re-word parts of the man page which I felt were badly worded or ambiguous. * change the behaviour of argument processing so that when more than one of the -P, -H and -L options are specified it will print an error message, rather than choosing the last option specified, this behaviour is more logical and consistent with other utilities. * change the behaviour of argument processing so that negative arguments to the -d option are not allowed. PR: 5388 Submitted by: Niall Smart <rotel@indigo.ie>
Diffstat (limited to 'usr.bin/du')
-rw-r--r--usr.bin/du/du.155
-rw-r--r--usr.bin/du/du.c212
2 files changed, 144 insertions, 123 deletions
diff --git a/usr.bin/du/du.1 b/usr.bin/du/du.1
index e84a710..0934fca 100644
--- a/usr.bin/du/du.1
+++ b/usr.bin/du/du.1
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)du.1 8.2 (Berkeley) 4/1/94
-.\" $Id: du.1,v 1.8 1997/02/22 19:54:52 peter Exp $
+.\" $Id: du.1,v 1.9 1997/06/30 06:50:06 charnier Exp $
.\"
.Dd April 1, 1994
.Dt DU 1
@@ -40,8 +40,9 @@
.Nd display disk usage statistics
.Sh SYNOPSIS
.Nm du
-.Op Fl H | Fl L | Fl P
+.Op Fl P | Fl H | Fl L
.Op Fl a | s | d Ar depth
+.Op Fl c
.Op Fl k
.Op Fl x
.Op Ar file ...
@@ -53,37 +54,37 @@ and for each directory in the file hierarchy rooted in each directory
argument.
If no file is specified, the block usage of the hierarchy rooted in
the current directory is displayed.
-The number of blocks are in the same units as that returned by the
-.Xr stat 2
-system call, i.e. 512-byte blocks.
If the
.Fl k
-flag is specified, the number displayed is the number of 1024-byte
-blocks.
+flag is specified, the number of 1024-byte
+blocks used by the file is displayed, otherwise
+.Xr getbsize 3
+is used to determine the preferred block size.
Partial numbers of blocks are rounded up.
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl P
+No symbolic links are followed. (default)
.It Fl H
-Symbolic links on the command line are followed.
-(Symbolic links encountered in the tree traversal are not followed.)
+Symbolic links on the command line are followed, symbolic links in file
+hierarchies are not followed.
.It Fl L
-All symbolic links are followed.
-.It Fl P
-No symbolic links are followed.
+Symbolic links on the command line and in file hierarchies are followed.
.It Fl a
-Display an entry for each file in the file hierarchy.
+Display an entry for each file in a file hierarchy.
+.It Fl s
+Display an entry for each specified file. (Equivalent to
+.Fl d
+0 )
.It Fl d Ar depth
-Displays all directories only
+Display an entry for all files and directories
.Ar depth
directories deep.
+.It Fl c
+Display a grand total.
.It Fl k
-Report in 1024-byte (1-Kbyte) blocks rather than the default. Note that
-this overrides the
-.Ev BLOCKSIZE
-setting from the environment.
-.It Fl s
-Display only the grand total for the specified files.
+Display block counts in 1024-byte (1-Kbyte) blocks.
.It Fl x
Filesystem mount points are not traversed.
.El
@@ -101,13 +102,6 @@ or
.Fl L
options are specified, storage used by any symbolic links which are
followed is not counted or displayed.
-The
-.Fl H ,
-.Fl L
-and
-.Fl P
-options override each other and the command's actions are determined
-by the last one specified.
.Pp
Files having multiple hard links are counted (and displayed) a single
time per
@@ -120,8 +114,11 @@ If the environment variable
.Ev BLOCKSIZE
is set, and the
.Fl k
-option is not specified, the block counts will be displayed in units of that
-size block.
+option is not specified, the block counts will be displayed in 1024-byte blocks. If
+.Ev BLOCKSIZE
+is not set, and the
+.Fl k
+option is not specified, the block counts will be displayed in 512-byte blocks.
.El
.Sh SEE ALSO
.Xr df 1 ,
diff --git a/usr.bin/du/du.c b/usr.bin/du/du.c
index 8c0724c..4c81e62 100644
--- a/usr.bin/du/du.c
+++ b/usr.bin/du/du.c
@@ -44,6 +44,7 @@ static char copyright[] =
static char sccsid[] = "@(#)du.c 8.5 (Berkeley) 5/4/95";
#endif /* not lint */
+
#include <sys/param.h>
#include <sys/stat.h>
@@ -56,63 +57,75 @@ static char sccsid[] = "@(#)du.c 8.5 (Berkeley) 5/4/95";
#include <string.h>
#include <unistd.h>
-int linkchk __P((FTSENT *));
-static void usage __P((void));
+int linkchk __P((FTSENT *));
+static void usage __P((void));
int
main(argc, argv)
int argc;
char *argv[];
{
- FTS *fts;
- FTSENT *p;
- long blocksize;
- int ftsoptions, listdirs, listfiles, depth;
- int Hflag, Lflag, Pflag, aflag, ch, notused, rval, sflag, dflag;
- char **save;
+ FTS *fts;
+ FTSENT *p;
+ FTSENT *savedp;
+ long blocksize;
+ int ftsoptions;
+ int listall;
+ int depth;
+ int Hflag, Lflag, Pflag, aflag, sflag, dflag, cflag, ch, notused, rval;
+ char **save;
+ Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = 0;
+
save = argv;
- Hflag = Lflag = Pflag = aflag = sflag = dflag = 0;
+ ftsoptions = 0;
depth = INT_MAX;
- ftsoptions = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "HLPad:ksx")) != -1)
+
+ while ((ch = getopt(argc, argv, "HLPad:ksxc")) != -1)
switch (ch) {
- case 'H':
- Hflag = 1;
- Lflag = Pflag = 0;
- break;
- case 'L':
- Lflag = 1;
- Hflag = Pflag = 0;
- break;
- case 'P':
- Pflag = 1;
- Hflag = Lflag = 0;
- break;
- case 'a':
- aflag = 1;
- break;
- case 'k':
- putenv("BLOCKSIZE=1024");
- break;
- case 's':
- sflag = 1;
- break;
- case 'x':
- ftsoptions |= FTS_XDEV;
- break;
- case 'd':
- dflag = 1;
- depth=atoi(optarg);
- if(errno == ERANGE) {
- (void)fprintf(stderr, "Invalid argument to option d: %s", optarg);
+ case 'H':
+ Hflag = 1;
+ break;
+ case 'L':
+ if (Pflag)
+ usage();
+ Lflag = 1;
+ break;
+ case 'P':
+ if (Lflag)
+ usage();
+ Pflag = 1;
+ break;
+ case 'a':
+ aflag = 1;
+ break;
+ case 'k':
+ putenv("BLOCKSIZE=1024");
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 'x':
+ ftsoptions |= FTS_XDEV;
+ break;
+ case 'd':
+ dflag = 1;
+ errno = 0;
+ depth = atoi(optarg);
+ if (errno == ERANGE || depth < 0) {
+ (void) fprintf(stderr, "Invalid argument to option d: %s", optarg);
+ usage();
+ }
+ break;
+ case 'c':
+ cflag = 1;
+ break;
+ case '?':
+ case 'h':
+ default:
usage();
- }
- break;
- case '?':
- default:
- usage();
}
+
argc -= optind;
argv += optind;
@@ -128,27 +141,32 @@ main(argc, argv)
* very nasty, very fast. The bottom line is that it's documented in
* the man page, so it's a feature.
*/
+
+ if (Hflag + Lflag + Pflag > 1)
+ usage();
+
+ if (Hflag + Lflag + Pflag == 0)
+ Pflag = 1; /* -P (physical) is default */
+
if (Hflag)
ftsoptions |= FTS_COMFOLLOW;
- if (Lflag) {
- ftsoptions &= ~FTS_PHYSICAL;
+
+ if (Lflag)
ftsoptions |= FTS_LOGICAL;
- }
+
+ if (Pflag)
+ ftsoptions |= FTS_PHYSICAL;
+
+ listall = 0;
if (aflag) {
if (sflag || dflag)
usage();
- listdirs = listfiles = 1;
+ listall = 1;
} else if (sflag) {
if (dflag)
usage();
- listdirs = listfiles = 0;
- } else if (dflag) {
- listfiles = 0;
- listdirs = 1;
- } else {
- listfiles = 0;
- listdirs = 1;
+ depth = 0;
}
if (!*argv) {
@@ -157,61 +175,67 @@ main(argc, argv)
argv[1] = NULL;
}
- (void)getbsize(&notused, &blocksize);
+ (void) getbsize(&notused, &blocksize);
blocksize /= 512;
+ rval = 0;
+
if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
- err(1, NULL);
+ err(1, "fts_open");
- for (rval = 0; (p = fts_read(fts)) != NULL;)
+ while ((p = fts_read(fts)) != NULL) {
+ savedp = p;
switch (p->fts_info) {
- case FTS_D: /* Ignore. */
- break;
- case FTS_DP:
- p->fts_parent->fts_number +=
- p->fts_number += p->fts_statp->st_blocks;
- /*
- * If listing each directory, or not listing files
- * or directories and this is post-order of the
- * root of a traversal, display the total.
- */
- if ((p->fts_level <= depth && listdirs) ||
- (!listfiles && !p->fts_level))
- (void)printf("%ld\t%s\n",
- howmany(p->fts_number, blocksize),
- p->fts_path);
- break;
- case FTS_DC: /* Ignore. */
- break;
- case FTS_DNR: /* Warn, continue. */
- case FTS_ERR:
- case FTS_NS:
- warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
- rval = 1;
- break;
- default:
- if (p->fts_statp->st_nlink > 1 && linkchk(p))
+ case FTS_D: /* Ignore. */
break;
- /*
- * If listing each file, or a non-directory file was
- * the root of a traversal, display the total.
- */
- if (listfiles || !p->fts_level)
- (void)printf("%qd\t%s\n",
- howmany(p->fts_statp->st_blocks, blocksize),
- p->fts_path);
- p->fts_parent->fts_number += p->fts_statp->st_blocks;
+ case FTS_DP:
+ p->fts_parent->fts_number +=
+ p->fts_number += p->fts_statp->st_blocks;
+
+ if (p->fts_level <= depth)
+ (void) printf("%ld\t%s\n",
+ howmany(p->fts_number, blocksize),
+ p->fts_path);
+ break;
+ case FTS_DC: /* Ignore. */
+ break;
+ case FTS_DNR: /* Warn, continue. */
+ case FTS_ERR:
+ case FTS_NS:
+ warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
+ rval = 1;
+ break;
+ default:
+ if (p->fts_statp->st_nlink > 1 && linkchk(p))
+ break;
+
+ if (listall || p->fts_level == 0)
+ (void) printf("%qd\t%s\n",
+ howmany(p->fts_statp->st_blocks, blocksize),
+ p->fts_path);
+
+ p->fts_parent->fts_number += p->fts_statp->st_blocks;
}
+ }
+
if (errno)
err(1, "fts_read");
+
+ if (cflag) {
+ p = savedp->fts_parent;
+ (void) printf("%ld\ttotal\n", howmany(p->fts_number, blocksize));
+ }
+
exit(rval);
}
+
typedef struct _ID {
dev_t dev;
ino_t inode;
} ID;
+
int
linkchk(p)
FTSENT *p;
OpenPOWER on IntegriCloud