X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fdu.c;h=b6ebaca7a067c0dceabe19e8bb17c0e053e6a792;hb=298854f02963bd8e43dfeb7224d88cfeb0c932cb;hp=7b5acb490dd6a58c878b6455cd5693297e00e20a;hpb=08c965a0a10cb28a0be30cf257b0ca9852e7ffef;p=oweals%2Fbusybox.git diff --git a/coreutils/du.c b/coreutils/du.c index 7b5acb490..b6ebaca7a 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -37,17 +37,21 @@ typedef void (Display) (long, char *); static const char du_usage[] = - "du [OPTION]... [FILE]...\n\n" + "Summarize disk space used for each FILE and/or directory.\n" + "Disk space is printed in units of 1024 bytes.\n\n" + "Options:\n" + "\t-l\tcount sizes many times if hard linked\n" "\t-s\tdisplay only a total for each argument\n"; static int du_depth = 0; +static int count_hardlinks = 0; static Display *print; static void print_normal(long size, char *filename) { - fprintf(stdout, "%-7ld %s\n", size, filename); + fprintf(stdout, "%ld\t%s\n", size, filename); } static void print_summary(long size, char *filename) @@ -57,24 +61,26 @@ static void print_summary(long size, char *filename) } } - /* tiny recursive du */ static long du(char *filename) { struct stat statbuf; long sum; + int len; if ((lstat(filename, &statbuf)) != 0) { - fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); + printf("du: %s: %s\n", filename, strerror(errno)); return 0; } du_depth++; sum = (statbuf.st_blocks >> 1); - /* Don't add in stuff pointed to by links */ + /* Don't add in stuff pointed to by symbolic links */ if (S_ISLNK(statbuf.st_mode)) { - return 0; + sum = 0L; + if (du_depth == 1) + print(sum, filename); } if (S_ISDIR(statbuf.st_mode)) { DIR *dir; @@ -82,8 +88,14 @@ static long du(char *filename) dir = opendir(filename); if (!dir) { + du_depth--; return 0; } + + len = strlen(filename); + if (filename[len - 1] == '/') + filename[--len] = '\0'; + while ((entry = readdir(dir))) { char newfile[PATH_MAX + 1]; char *name = entry->d_name; @@ -93,8 +105,9 @@ static long du(char *filename) continue; } - if (strlen(filename) + strlen(name) + 1 > PATH_MAX) { + if (len + strlen(name) + 1 > PATH_MAX) { fprintf(stderr, name_too_long, "du"); + du_depth--; return 0; } sprintf(newfile, "%s/%s", filename, name); @@ -104,6 +117,17 @@ static long du(char *filename) closedir(dir); print(sum, filename); } + else if (statbuf.st_nlink > 1 && !count_hardlinks) { + /* Add files with hard links only once */ + if (is_in_ino_dev_hashtable(&statbuf, NULL)) { + sum = 0L; + if (du_depth == 1) + print(sum, filename); + } + else { + add_to_ino_dev_hashtable(&statbuf, NULL); + } + } du_depth--; return sum; } @@ -124,7 +148,11 @@ int du_main(int argc, char **argv) case 's': print = print_summary; break; + case 'l': + count_hardlinks = 1; + break; case 'h': + case '-': usage(du_usage); break; default: @@ -144,13 +172,21 @@ int du_main(int argc, char **argv) for (; i < argc; i++) { sum = du(argv[i]); - if ((sum) && (isDirectory(argv[i], FALSE, NULL))) { + if (sum && isDirectory(argv[i], FALSE, NULL)) { print_normal(sum, argv[i]); } + reset_ino_dev_hashtable(); } } exit(0); } -/* $Id: du.c,v 1.13 2000/02/13 04:10:57 beppu Exp $ */ +/* $Id: du.c,v 1.16 2000/03/04 21:19:32 erik Exp $ */ +/* +Local Variables: +c-file-style: "linux" +c-basic-offset: 4 +tab-width: 4 +End: +*/