Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/coreutils/du.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 25  Line 25 
25    
26  #include "libbb.h"  #include "libbb.h"
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    
42  struct globals {  struct globals {
43  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
44   unsigned long disp_hr;   unsigned long disp_hr;
45  #else  #else
46   unsigned disp_k;   unsigned disp_k;
47  #endif  #endif
   
48   int max_print_depth;   int max_print_depth;
  nlink_t count_hardlinks;  
   
49   bool status;   bool status;
  bool one_file_system;  
  int print_files;  
50   int slink_depth;   int slink_depth;
51   int du_depth;   int du_depth;
52   dev_t dir_dev;   dev_t dir_dev;
# Line 49  static void print(unsigned long size, co Line 58  static void print(unsigned long size, co
58  {  {
59   /* TODO - May not want to defer error checking here. */   /* TODO - May not want to defer error checking here. */
60  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
61   printf("%s\t%s\n", make_human_readable_str(size, 512, G.disp_hr),   printf("%s\t%s\n",
62     /* size x 512 / G.disp_hr, show one fractional,
63     * use suffixes if G.disp_hr == 0 */
64     make_human_readable_str(size, 512, G.disp_hr),
65   filename);   filename);
66  #else  #else
67   if (G.disp_k) {   if (G.disp_k) {
68   size++;   size++;
69   size >>= 1;   size >>= 1;
70   }   }
71   printf("%ld\t%s\n", size, filename);   printf("%lu\t%s\n", size, filename);
72  #endif  #endif
73  }  }
74    
# Line 72  static unsigned long du(const char *file Line 84  static unsigned long du(const char *file
84   return 0;   return 0;
85   }   }
86    
87   if (G.one_file_system) {   if (option_mask32 & OPT_x_one_FS) {
88   if (G.du_depth == 0) {   if (G.du_depth == 0) {
89   G.dir_dev = statbuf.st_dev;   G.dir_dev = statbuf.st_dev;
90   } else if (G.dir_dev != statbuf.st_dev) {   } else if (G.dir_dev != statbuf.st_dev) {
# Line 83  static unsigned long du(const char *file Line 95  static unsigned long du(const char *file
95   sum = statbuf.st_blocks;   sum = statbuf.st_blocks;
96    
97   if (S_ISLNK(statbuf.st_mode)) {   if (S_ISLNK(statbuf.st_mode)) {
98   if (G.slink_depth > G.du_depth) { /* -H or -L */   if (G.slink_depth > G.du_depth) { /* -H or -L */
99   if (stat(filename, &statbuf) != 0) {   if (stat(filename, &statbuf) != 0) {
100   bb_simple_perror_msg(filename);   bb_simple_perror_msg(filename);
101   G.status = EXIT_FAILURE;   G.status = EXIT_FAILURE;
# Line 91  static unsigned long du(const char *file Line 103  static unsigned long du(const char *file
103   }   }
104   sum = statbuf.st_blocks;   sum = statbuf.st_blocks;
105   if (G.slink_depth == 1) {   if (G.slink_depth == 1) {
106   G.slink_depth = INT_MAX; /* Convert -H to -L. */   /* Convert -H to -L */
107     G.slink_depth = INT_MAX;
108   }   }
109   }   }
110   }   }
111    
112   if (statbuf.st_nlink > G.count_hardlinks) {   if (!(option_mask32 & OPT_l_hardlinks)
113     && statbuf.st_nlink > 1
114     ) {
115   /* Add files/directories with links only once */   /* Add files/directories with links only once */
116   if (is_in_ino_dev_hashtable(&statbuf)) {   if (is_in_ino_dev_hashtable(&statbuf)) {
117   return 0;   return 0;
# Line 115  static unsigned long du(const char *file Line 130  static unsigned long du(const char *file
130   return sum;   return sum;
131   }   }
132    
  newfile = last_char_is(filename, '/');  
  if (newfile)  
  *newfile = '\0';  
   
133   while ((entry = readdir(dir))) {   while ((entry = readdir(dir))) {
134   char *name = entry->d_name;   newfile = concat_subpath_file(filename, entry->d_name);
   
  newfile = concat_subpath_file(filename, name);  
135   if (newfile == NULL)   if (newfile == NULL)
136   continue;   continue;
137   ++G.du_depth;   ++G.du_depth;
# Line 131  static unsigned long du(const char *file Line 140  static unsigned long du(const char *file
140   free(newfile);   free(newfile);
141   }   }
142   closedir(dir);   closedir(dir);
143   } else if (G.du_depth > G.print_files) {   } else {
144   return sum;   if (!(option_mask32 & OPT_a_files_too) && G.du_depth != 0)
145     return sum;
146   }   }
147   if (G.du_depth <= G.max_print_depth) {   if (G.du_depth <= G.max_print_depth) {
148   print(sum, filename);   print(sum, filename);
# Line 145  int du_main(int argc UNUSED_PARAM, char Line 155  int du_main(int argc UNUSED_PARAM, char
155  {  {
156   unsigned long total;   unsigned long total;
157   int slink_depth_save;   int slink_depth_save;
  bool print_final_total;  
158   unsigned opt;   unsigned opt;
159    
160  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
161   USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;)   IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;)
162   SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;)   IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;)
163   if (getenv("POSIXLY_CORRECT"))  /* TODO - a new libbb function? */   if (getenv("POSIXLY_CORRECT"))  /* TODO - a new libbb function? */
164   G.disp_hr = 512;   G.disp_hr = 512;
165  #else  #else
166   USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;)   IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;)
167   /* SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */   /* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */
168  #endif  #endif
169   G.max_print_depth = INT_MAX;   G.max_print_depth = INT_MAX;
  G.count_hardlinks = 1;  
170    
171   /* Note: SUSv3 specifies that -a and -s options cannot be used together   /* Note: SUSv3 specifies that -a and -s options cannot be used together
172   * in strictly conforming applications.  However, it also says that some   * in strictly conforming applications.  However, it also says that some
# Line 170  int du_main(int argc UNUSED_PARAM, char Line 178  int du_main(int argc UNUSED_PARAM, char
178   opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+";   opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+";
179   opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);   opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);
180   argv += optind;   argv += optind;
181   if (opt & (1 << 9)) {   if (opt & OPT_h_for_humans) {
  /* -h opt */  
182   G.disp_hr = 0;   G.disp_hr = 0;
183   }   }
184   if (opt & (1 << 10)) {   if (opt & OPT_m_mbytes) {
  /* -m opt */  
185   G.disp_hr = 1024*1024;   G.disp_hr = 1024*1024;
186   }   }
187   if (opt & (1 << 2)) {   if (opt & OPT_k_kbytes) {
  /* -k opt */  
188   G.disp_hr = 1024;   G.disp_hr = 1024;
189   }   }
190  #else  #else
# Line 187  int du_main(int argc UNUSED_PARAM, char Line 192  int du_main(int argc UNUSED_PARAM, char
192   opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth);   opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth);
193   argv += optind;   argv += optind;
194  #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K  #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
195   if (opt & (1 << 2)) {   if (opt & OPT_k_kbytes) {
  /* -k opt */  
196   G.disp_k = 1;   G.disp_k = 1;
197   }   }
198  #endif  #endif
199  #endif  #endif
200   if (opt & (1 << 0)) {   if (opt & OPT_H_follow_links) {
  /* -a opt */  
  G.print_files = INT_MAX;  
  }  
  if (opt & (1 << 1)) {  
  /* -H opt */  
201   G.slink_depth = 1;   G.slink_depth = 1;
202   }   }
203   if (opt & (1 << 3)) {   if (opt & OPT_L_follow_links) {
  /* -L opt */  
204   G.slink_depth = INT_MAX;   G.slink_depth = INT_MAX;
205   }   }
206   if (opt & (1 << 4)) {   if (opt & OPT_s_total_norecurse) {
  /* -s opt */  
207   G.max_print_depth = 0;   G.max_print_depth = 0;
208   }   }
  G.one_file_system = opt & (1 << 5); /* -x opt */  
  if (opt & (1 << 7)) {  
  /* -l opt */  
  G.count_hardlinks = MAXINT(nlink_t);  
  }  
  print_final_total = opt & (1 << 8); /* -c opt */  
209    
210   /* go through remaining args (if any) */   /* go through remaining args (if any) */
211   if (!*argv) {   if (!*argv) {
# Line 228  int du_main(int argc UNUSED_PARAM, char Line 219  int du_main(int argc UNUSED_PARAM, char
219   total = 0;   total = 0;
220   do {   do {
221   total += du(*argv);   total += du(*argv);
222     /* otherwise du /dir /dir won't show /dir twice: */
223     reset_ino_dev_hashtable();
224   G.slink_depth = slink_depth_save;   G.slink_depth = slink_depth_save;
225   } while (*++argv);   } while (*++argv);
226    
227   if (ENABLE_FEATURE_CLEAN_UP)   if (opt & OPT_c_total)
  reset_ino_dev_hashtable();  
  if (print_final_total)  
228   print(total, "total");   print(total, "total");
229    
230   fflush_stdout_and_exit(G.status);   fflush_stdout_and_exit(G.status);

Legend:
Removed from v.983  
changed lines
  Added in v.984