diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-11 21:15:56 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-11 21:15:56 +0000 |
commit | 618a3027edbfd42e52bfd7680cd24affe7a29b4c (patch) | |
tree | 5493504ca370c90464e3b6550d11b6d51c05c4fc | |
parent | 3b35fbb6323adadf7108e1d32fc4d93b4d89e9c4 (diff) | |
download | busybox-w32-618a3027edbfd42e52bfd7680cd24affe7a29b4c.tar.gz busybox-w32-618a3027edbfd42e52bfd7680cd24affe7a29b4c.tar.bz2 busybox-w32-618a3027edbfd42e52bfd7680cd24affe7a29b4c.zip |
du: fix "du /dir /dir" case
reset_ino_dev_hashtable - 84 +84
du 388 376 -12
du_main 327 301 -26
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/2 up/down: 84/-38) Total: 46 bytes
-rw-r--r-- | coreutils/du.c | 82 | ||||
-rw-r--r-- | libbb/inode_hash.c | 2 |
2 files changed, 36 insertions, 48 deletions
diff --git a/coreutils/du.c b/coreutils/du.c index efc9bb9fa..16c773243 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
@@ -25,19 +25,28 @@ | |||
25 | 25 | ||
26 | #include "libbb.h" | 26 | #include "libbb.h" |
27 | 27 | ||
28 | enum { | ||
29 | OPT_a_files_too = (1 << 0), | ||
30 | OPT_H_follow_links = (1 << 1), | ||
31 | OPT_k_kbytes = (1 << 2), | ||
32 | OPT_L_follow_links = (1 << 3), | ||
33 | OPT_s_total_norecurse = (1 << 4), | ||
34 | OPT_x_one_FS = (1 << 5), | ||
35 | OPT_d_maxdepth = (1 << 6), | ||
36 | OPT_l_hardlinks = (1 << 7), | ||
37 | OPT_c_total = (1 << 8), | ||
38 | OPT_h_for_humans = (1 << 9), | ||
39 | OPT_m_mbytes = (1 << 10), | ||
40 | }; | ||
41 | |||
28 | struct globals { | 42 | struct globals { |
29 | #if ENABLE_FEATURE_HUMAN_READABLE | 43 | #if ENABLE_FEATURE_HUMAN_READABLE |
30 | unsigned long disp_hr; | 44 | unsigned long disp_hr; |
31 | #else | 45 | #else |
32 | unsigned disp_k; | 46 | unsigned disp_k; |
33 | #endif | 47 | #endif |
34 | |||
35 | int max_print_depth; | 48 | int max_print_depth; |
36 | nlink_t count_hardlinks; | ||
37 | |||
38 | bool status; | 49 | bool status; |
39 | bool one_file_system; | ||
40 | int print_files; | ||
41 | int slink_depth; | 50 | int slink_depth; |
42 | int du_depth; | 51 | int du_depth; |
43 | dev_t dir_dev; | 52 | dev_t dir_dev; |
@@ -72,7 +81,7 @@ static unsigned long du(const char *filename) | |||
72 | return 0; | 81 | return 0; |
73 | } | 82 | } |
74 | 83 | ||
75 | if (G.one_file_system) { | 84 | if (option_mask32 & OPT_x_one_FS) { |
76 | if (G.du_depth == 0) { | 85 | if (G.du_depth == 0) { |
77 | G.dir_dev = statbuf.st_dev; | 86 | G.dir_dev = statbuf.st_dev; |
78 | } else if (G.dir_dev != statbuf.st_dev) { | 87 | } else if (G.dir_dev != statbuf.st_dev) { |
@@ -83,7 +92,7 @@ static unsigned long du(const char *filename) | |||
83 | sum = statbuf.st_blocks; | 92 | sum = statbuf.st_blocks; |
84 | 93 | ||
85 | if (S_ISLNK(statbuf.st_mode)) { | 94 | if (S_ISLNK(statbuf.st_mode)) { |
86 | if (G.slink_depth > G.du_depth) { /* -H or -L */ | 95 | if (G.slink_depth > G.du_depth) { /* -H or -L */ |
87 | if (stat(filename, &statbuf) != 0) { | 96 | if (stat(filename, &statbuf) != 0) { |
88 | bb_simple_perror_msg(filename); | 97 | bb_simple_perror_msg(filename); |
89 | G.status = EXIT_FAILURE; | 98 | G.status = EXIT_FAILURE; |
@@ -91,12 +100,15 @@ static unsigned long du(const char *filename) | |||
91 | } | 100 | } |
92 | sum = statbuf.st_blocks; | 101 | sum = statbuf.st_blocks; |
93 | if (G.slink_depth == 1) { | 102 | if (G.slink_depth == 1) { |
94 | G.slink_depth = INT_MAX; /* Convert -H to -L. */ | 103 | /* Convert -H to -L */ |
104 | G.slink_depth = INT_MAX; | ||
95 | } | 105 | } |
96 | } | 106 | } |
97 | } | 107 | } |
98 | 108 | ||
99 | if (statbuf.st_nlink > G.count_hardlinks) { | 109 | if (!(option_mask32 & OPT_l_hardlinks) |
110 | && statbuf.st_nlink > 1 | ||
111 | ) { | ||
100 | /* Add files/directories with links only once */ | 112 | /* Add files/directories with links only once */ |
101 | if (is_in_ino_dev_hashtable(&statbuf)) { | 113 | if (is_in_ino_dev_hashtable(&statbuf)) { |
102 | return 0; | 114 | return 0; |
@@ -115,14 +127,8 @@ static unsigned long du(const char *filename) | |||
115 | return sum; | 127 | return sum; |
116 | } | 128 | } |
117 | 129 | ||
118 | newfile = last_char_is(filename, '/'); | ||
119 | if (newfile) | ||
120 | *newfile = '\0'; | ||
121 | |||
122 | while ((entry = readdir(dir))) { | 130 | while ((entry = readdir(dir))) { |
123 | char *name = entry->d_name; | 131 | newfile = concat_subpath_file(filename, entry->d_name); |
124 | |||
125 | newfile = concat_subpath_file(filename, name); | ||
126 | if (newfile == NULL) | 132 | if (newfile == NULL) |
127 | continue; | 133 | continue; |
128 | ++G.du_depth; | 134 | ++G.du_depth; |
@@ -131,8 +137,9 @@ static unsigned long du(const char *filename) | |||
131 | free(newfile); | 137 | free(newfile); |
132 | } | 138 | } |
133 | closedir(dir); | 139 | closedir(dir); |
134 | } else if (G.du_depth > G.print_files) { | 140 | } else { |
135 | return sum; | 141 | if (!(option_mask32 & OPT_a_files_too) && G.du_depth != 0) |
142 | return sum; | ||
136 | } | 143 | } |
137 | if (G.du_depth <= G.max_print_depth) { | 144 | if (G.du_depth <= G.max_print_depth) { |
138 | print(sum, filename); | 145 | print(sum, filename); |
@@ -145,7 +152,6 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
145 | { | 152 | { |
146 | unsigned long total; | 153 | unsigned long total; |
147 | int slink_depth_save; | 154 | int slink_depth_save; |
148 | bool print_final_total; | ||
149 | unsigned opt; | 155 | unsigned opt; |
150 | 156 | ||
151 | #if ENABLE_FEATURE_HUMAN_READABLE | 157 | #if ENABLE_FEATURE_HUMAN_READABLE |
@@ -158,7 +164,6 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
158 | /* SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ | 164 | /* SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ |
159 | #endif | 165 | #endif |
160 | G.max_print_depth = INT_MAX; | 166 | G.max_print_depth = INT_MAX; |
161 | G.count_hardlinks = 1; | ||
162 | 167 | ||
163 | /* Note: SUSv3 specifies that -a and -s options cannot be used together | 168 | /* Note: SUSv3 specifies that -a and -s options cannot be used together |
164 | * in strictly conforming applications. However, it also says that some | 169 | * in strictly conforming applications. However, it also says that some |
@@ -170,16 +175,13 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
170 | opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+"; | 175 | opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+"; |
171 | opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth); | 176 | opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth); |
172 | argv += optind; | 177 | argv += optind; |
173 | if (opt & (1 << 9)) { | 178 | if (opt & OPT_h_for_humans) { |
174 | /* -h opt */ | ||
175 | G.disp_hr = 0; | 179 | G.disp_hr = 0; |
176 | } | 180 | } |
177 | if (opt & (1 << 10)) { | 181 | if (opt & OPT_m_mbytes) { |
178 | /* -m opt */ | ||
179 | G.disp_hr = 1024*1024; | 182 | G.disp_hr = 1024*1024; |
180 | } | 183 | } |
181 | if (opt & (1 << 2)) { | 184 | if (opt & OPT_k_kbytes) { |
182 | /* -k opt */ | ||
183 | G.disp_hr = 1024; | 185 | G.disp_hr = 1024; |
184 | } | 186 | } |
185 | #else | 187 | #else |
@@ -187,34 +189,20 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
187 | opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth); | 189 | opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth); |
188 | argv += optind; | 190 | argv += optind; |
189 | #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K | 191 | #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K |
190 | if (opt & (1 << 2)) { | 192 | if (opt & OPT_k_kbytes) { |
191 | /* -k opt */ | ||
192 | G.disp_k = 1; | 193 | G.disp_k = 1; |
193 | } | 194 | } |
194 | #endif | 195 | #endif |
195 | #endif | 196 | #endif |
196 | if (opt & (1 << 0)) { | 197 | if (opt & OPT_H_follow_links) { |
197 | /* -a opt */ | ||
198 | G.print_files = INT_MAX; | ||
199 | } | ||
200 | if (opt & (1 << 1)) { | ||
201 | /* -H opt */ | ||
202 | G.slink_depth = 1; | 198 | G.slink_depth = 1; |
203 | } | 199 | } |
204 | if (opt & (1 << 3)) { | 200 | if (opt & OPT_L_follow_links) { |
205 | /* -L opt */ | ||
206 | G.slink_depth = INT_MAX; | 201 | G.slink_depth = INT_MAX; |
207 | } | 202 | } |
208 | if (opt & (1 << 4)) { | 203 | if (opt & OPT_s_total_norecurse) { |
209 | /* -s opt */ | ||
210 | G.max_print_depth = 0; | 204 | G.max_print_depth = 0; |
211 | } | 205 | } |
212 | G.one_file_system = opt & (1 << 5); /* -x opt */ | ||
213 | if (opt & (1 << 7)) { | ||
214 | /* -l opt */ | ||
215 | G.count_hardlinks = MAXINT(nlink_t); | ||
216 | } | ||
217 | print_final_total = opt & (1 << 8); /* -c opt */ | ||
218 | 206 | ||
219 | /* go through remaining args (if any) */ | 207 | /* go through remaining args (if any) */ |
220 | if (!*argv) { | 208 | if (!*argv) { |
@@ -228,12 +216,12 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
228 | total = 0; | 216 | total = 0; |
229 | do { | 217 | do { |
230 | total += du(*argv); | 218 | total += du(*argv); |
219 | /* otherwise du /dir /dir won't show /dir twice: */ | ||
220 | reset_ino_dev_hashtable(); | ||
231 | G.slink_depth = slink_depth_save; | 221 | G.slink_depth = slink_depth_save; |
232 | } while (*++argv); | 222 | } while (*++argv); |
233 | 223 | ||
234 | if (ENABLE_FEATURE_CLEAN_UP) | 224 | if (opt & OPT_c_total) |
235 | reset_ino_dev_hashtable(); | ||
236 | if (print_final_total) | ||
237 | print(total, "total"); | 225 | print(total, "total"); |
238 | 226 | ||
239 | fflush_stdout_and_exit(G.status); | 227 | fflush_stdout_and_exit(G.status); |
diff --git a/libbb/inode_hash.c b/libbb/inode_hash.c index 4469671dd..b32bd26bf 100644 --- a/libbb/inode_hash.c +++ b/libbb/inode_hash.c | |||
@@ -67,7 +67,7 @@ void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char * | |||
67 | ino_dev_hashtable[i] = bucket; | 67 | ino_dev_hashtable[i] = bucket; |
68 | } | 68 | } |
69 | 69 | ||
70 | #if ENABLE_FEATURE_CLEAN_UP | 70 | #if ENABLE_DU || ENABLE_FEATURE_CLEAN_UP |
71 | /* Clear statbuf hash table */ | 71 | /* Clear statbuf hash table */ |
72 | void FAST_FUNC reset_ino_dev_hashtable(void) | 72 | void FAST_FUNC reset_ino_dev_hashtable(void) |
73 | { | 73 | { |