Add -x support for du(1)

This commit is contained in:
Quentin Rameau 2015-02-18 18:24:21 +01:00 committed by sin
parent 9d2b94dbb0
commit 593effc7c8
2 changed files with 16 additions and 7 deletions

3
du.1
View File

@ -11,6 +11,7 @@
.Op Fl h .Op Fl h
.Op Fl k .Op Fl k
.Op Fl H | L | P .Op Fl H | L | P
.Op Fl x
.Op Ar file ... .Op Ar file ...
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
@ -43,4 +44,6 @@ recursively traversing directories.
Always dereference symbolic links while recursively traversing directories. Always dereference symbolic links while recursively traversing directories.
.It Fl P .It Fl P
Don't dereference symbolic links. This is the default. Don't dereference symbolic links. This is the default.
.It Fl x
Do not traverse file systems mount points.
.El .El

20
du.c
View File

@ -21,6 +21,7 @@ static int dflag = 0;
static int sflag = 0; static int sflag = 0;
static int kflag = 0; static int kflag = 0;
static int hflag = 0; static int hflag = 0;
static int xflag = 0;
static int HLPflag = 'P'; static int HLPflag = 'P';
static char * static char *
@ -72,19 +73,19 @@ static size_t
du(const char *path, char follow) du(const char *path, char follow)
{ {
struct dirent *dent; struct dirent *dent;
struct stat st; struct stat pst, st;
DIR *dp; DIR *dp;
size_t n = 0, m, t; size_t n = 0, m, t;
int r; int r;
char *cwd; char *cwd;
if (lstat(path, &st) < 0) if (lstat(path, &pst) < 0)
eprintf("stat: %s:", path); eprintf("stat: %s:", path);
n = nblks(&st); n = nblks(&pst);
if (!(S_ISDIR(st.st_mode) || if (!(S_ISDIR(pst.st_mode) ||
(follow != 'P' && S_ISLNK(st.st_mode) && (follow != 'P' && S_ISLNK(pst.st_mode) &&
stat(path, &st) == 0 && S_ISDIR(st.st_mode)))) stat(path, &pst) == 0 && S_ISDIR(pst.st_mode))))
goto done; goto done;
follow = follow == 'H' ? 'P' : follow; follow = follow == 'H' ? 'P' : follow;
@ -102,6 +103,8 @@ du(const char *path, char follow)
continue; continue;
if (lstat(dent->d_name, &st) < 0) if (lstat(dent->d_name, &st) < 0)
eprintf("stat: %s:", dent->d_name); eprintf("stat: %s:", dent->d_name);
if (xflag && st.st_dev != pst.st_dev)
continue;
if (S_ISDIR(st.st_mode) || if (S_ISDIR(st.st_mode) ||
(follow != 'P' && S_ISLNK(st.st_mode) && (follow != 'P' && S_ISLNK(st.st_mode) &&
stat(dent->d_name, &st) == 0 && S_ISDIR(st.st_mode))) { stat(dent->d_name, &st) == 0 && S_ISDIR(st.st_mode))) {
@ -138,7 +141,7 @@ done:
static void static void
usage(void) usage(void)
{ {
eprintf("usage: %s [-a | -s] [-d depth] [-h] [-k] [-H | -L | -P] [file ...]\n", argv0); eprintf("usage: %s [-a | -s] [-d depth] [-h] [-k] [-H | -L | -P] [-x] [file ...]\n", argv0);
} }
int int
@ -169,6 +172,9 @@ main(int argc, char *argv[])
case 'P': case 'P':
HLPflag = ARGC(); HLPflag = ARGC();
break; break;
case 'x':
xflag = 1;
break;
default: default:
usage(); usage();
} ARGEND; } ARGEND;