Mercurial > hg > toybox
annotate toys/posix/du.c @ 1746:b11f536bac74 draft
install -D bugfix from David Halls.
(I tweaked some comment text while I was there.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 21 Mar 2015 15:49:38 -0500 |
parents | a016421051e4 |
children |
rev | line source |
---|---|
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
1 /* du.c - disk usage program. |
658 | 2 * |
3 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com> | |
4 * | |
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/du.html | |
6 | |
1010 | 7 USE_DU(NEWTOY(du, "d#<0hmlcaHkKLsx[-HL][-kKmh]", TOYFLAG_USR|TOYFLAG_BIN)) |
658 | 8 |
9 config DU | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
10 bool "du" |
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
11 default y |
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
12 help |
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
13 usage: du [-d N] [-askxHLlmc] [file...] |
658 | 14 |
1010 | 15 Show disk usage, space consumed by files and directories. |
16 | |
17 Size in: | |
18 -k 1024 byte blocks (default) | |
19 -K 512 byte blocks (posix) | |
20 -m megabytes | |
21 -h human readable format (e.g., 1K 243M 2G ) | |
22 | |
23 What to show: | |
24 -a all files, not just directories | |
25 -H follow symlinks on cmdline | |
26 -L follow all symlinks | |
27 -s only total size of each argument | |
28 -x don't leave this filesystem | |
29 -c cumulative total | |
30 -d N only depth < N | |
31 -l disable hardlink filter | |
658 | 32 */ |
33 | |
674
7e846e281e38
New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents:
658
diff
changeset
|
34 #define FOR_du |
658 | 35 #include "toys.h" |
36 | |
674
7e846e281e38
New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents:
658
diff
changeset
|
37 GLOBALS( |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
38 long maxdepth; |
1010 | 39 |
40 long depth, total; | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
41 dev_t st_dev; |
1010 | 42 void *inodes; |
658 | 43 ) |
44 | |
45 typedef struct node_size { | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
46 struct dirtree *node; |
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
47 long size; |
1010 | 48 } node_size; |
658 | 49 |
1010 | 50 // Print the size and name, given size in bytes |
51 static void print(long long size, struct dirtree *node) | |
658 | 52 { |
1010 | 53 char *name = "total"; |
54 | |
55 if (TT.maxdepth && TT.depth > TT.maxdepth) return; | |
56 | |
1261
9e105bab92e5
Revert lots of half-finished local debris I didn't mean to check in with Isaac's roadmap update.
Rob Landley <rob@landley.net>
parents:
1251
diff
changeset
|
57 if (toys.optflags & FLAG_h) { |
1276
d48bdc1cb017
Switch human_readable() to just outputing decimal kilo/mega/gigabytes, make du use it, move it from lib/pending.c to lib.c.
Rob Landley <rob@landley.net>
parents:
1261
diff
changeset
|
58 human_readable(toybuf, size); |
d48bdc1cb017
Switch human_readable() to just outputing decimal kilo/mega/gigabytes, make du use it, move it from lib/pending.c to lib.c.
Rob Landley <rob@landley.net>
parents:
1261
diff
changeset
|
59 printf("%s", toybuf); |
1261
9e105bab92e5
Revert lots of half-finished local debris I didn't mean to check in with Isaac's roadmap update.
Rob Landley <rob@landley.net>
parents:
1251
diff
changeset
|
60 } else { |
1010 | 61 int bits = 10; |
62 | |
63 if (toys.optflags & FLAG_K) bits = 9; | |
64 else if (toys.optflags & FLAG_m) bits = 20; | |
65 | |
66 printf("%llu", (size>>bits)+!!(size&((1<<bits)-1))); | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
67 } |
1010 | 68 if (node) name = dirtree_path(node, NULL); |
69 xprintf("\t%s\n", name); | |
70 if (node) free(name); | |
658 | 71 } |
72 | |
1010 | 73 // Return whether or not we've seen this inode+dev, adding it to the list if |
74 // we haven't. | |
75 static int seen_inode(void **list, struct stat *st) | |
658 | 76 { |
1010 | 77 if (!st) llist_traverse(st, free); |
658 | 78 |
1010 | 79 // Skipping dir nodes isn't _quite_ right. They're not hardlinked, but could |
80 // be bind mounted. Still, it's more efficient and the archivers can't use | |
81 // hardlinked directory info anyway. (Note that we don't catch bind mounted | |
82 // _files_ because it doesn't change st_nlink.) | |
83 else if (!S_ISDIR(st->st_mode) && st->st_nlink > 1) { | |
84 struct inode_list { | |
85 struct inode_list *next; | |
86 ino_t ino; | |
87 dev_t dev; | |
88 } *new; | |
658 | 89 |
1010 | 90 for (new = *list; new; new = new->next) |
91 if(new->ino == st->st_ino && new->dev == st->st_dev) | |
92 return 1; | |
93 | |
94 new = xzalloc(sizeof(*new)); | |
95 new->ino = st->st_ino; | |
96 new->dev = st->st_dev; | |
97 new->next = *list; | |
98 *list = new; | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
99 } |
1010 | 100 |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
101 return 0; |
658 | 102 } |
103 | |
1010 | 104 // dirtree callback, comput/display size of node |
105 static int do_du(struct dirtree *node) | |
658 | 106 { |
1010 | 107 if (node->parent && !dirtree_notdotdot(node)) return 0; |
108 | |
109 // detect swiching filesystems | |
110 if ((toys.optflags & FLAG_x) && (TT.st_dev != node->st.st_dev)) | |
111 return 0; | |
658 | 112 |
1591
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
113 // Don't loop endlessly on recursive directory symlink |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
114 if (toys.optflags & FLAG_L) { |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
115 struct dirtree *try = node; |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
116 |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
117 while ((try = try->parent)) |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
118 if (node->st.st_dev==try->st.st_dev && node->st.st_ino==try->st.st_ino) |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
119 return 0; |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
120 } |
a016421051e4
Ashwini Sharma pointed out that "mkdir sub; ln -s . sub/up; du -L sub" shouldn't loop endlessly.
Rob Landley <rob@landley.net>
parents:
1404
diff
changeset
|
121 |
1010 | 122 // Don't count hard links twice |
1404
ffc7f606ce5b
Move DIRTREE_COMEAGAIN second callback up to when the filehandle is still open, and add dir->again variable to distinguish second call instead of checking for -1 filehandle.
Rob Landley <rob@landley.net>
parents:
1276
diff
changeset
|
123 if (!(toys.optflags & FLAG_l) && !node->again) |
1010 | 124 if (seen_inode(&TT.inodes, &node->st)) return 0; |
125 | |
126 // Collect child info before printing directory size | |
127 if (S_ISDIR(node->st.st_mode)) { | |
1404
ffc7f606ce5b
Move DIRTREE_COMEAGAIN second callback up to when the filehandle is still open, and add dir->again variable to distinguish second call instead of checking for -1 filehandle.
Rob Landley <rob@landley.net>
parents:
1276
diff
changeset
|
128 if (!node->again) { |
1010 | 129 TT.depth++; |
130 return DIRTREE_COMEAGAIN | (DIRTREE_SYMFOLLOW*!!(toys.optflags & FLAG_L)); | |
131 } else TT.depth--; | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
132 } |
658 | 133 |
1010 | 134 node->extra += node->st.st_blocks; |
135 if (node->parent) node->parent->extra += node->extra; | |
136 else TT.total += node->extra; | |
137 | |
138 if ((toys.optflags & FLAG_a) || !node->parent | |
139 || (S_ISDIR(node->st.st_mode) && !(toys.optflags & FLAG_s))) | |
140 { | |
141 print(node->extra*512, node); | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
142 } |
1010 | 143 |
144 return 0; | |
658 | 145 } |
146 | |
147 void du_main(void) | |
148 { | |
1010 | 149 char *noargs[] = {".", 0}; |
150 struct dirtree *root; | |
151 | |
152 if (!toys.optc) toys.optargs = noargs; | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
153 |
1010 | 154 // Loop over command line arguments, recursing through children |
155 while (*toys.optargs) { | |
156 root = dirtree_add_node(0, *toys.optargs, toys.optflags & (FLAG_H|FLAG_L)); | |
157 | |
158 if (root) { | |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
159 TT.st_dev = root->st.st_dev; |
1010 | 160 dirtree_handle_callback(root, do_du); |
658 | 161 } |
694
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
162 toys.optargs++; |
786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
163 } |
1010 | 164 if (toys.optflags & FLAG_c) print(TT.total*512, 0); |
165 | |
166 if (CFG_TOYBOX_FREE) seen_inode(TT.inodes, 0); | |
658 | 167 } |