* 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>
This commit is contained in:
parent
de92741516
commit
1aa8a0a95b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=32097
@ -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 H
|
||||
Symbolic links on the command line are followed.
|
||||
(Symbolic links encountered in the tree traversal are not followed.)
|
||||
.It Fl L
|
||||
All symbolic links are followed.
|
||||
.It Fl P
|
||||
No symbolic links are followed.
|
||||
No symbolic links are followed. (default)
|
||||
.It Fl H
|
||||
Symbolic links on the command line are followed, symbolic links in file
|
||||
hierarchies are not followed.
|
||||
.It Fl L
|
||||
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 ,
|
||||
|
212
usr.bin/du/du.c
212
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(¬used, &blocksize);
|
||||
(void) getbsize(¬used, &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;
|
||||
|
Loading…
Reference in New Issue
Block a user