Additions to du, take 2
Kim Ahlström <[email protected]>
| Newsgroups | gmane.comp.gnu.fileutils.bugs |
|---|---|
| Message-ID | <[email protected]> |
Hi, i sent you some additions to du.c a few days ago. I found an off-by-one malloc:ing error and one place were " were used instead of ' and have fixed this. I have attached the new diff-file here. This diff should be applied to the 4.1.11 version availabe on your aplha-release server and not to a version patched with the earlier diff-file I sent you. Here is the ChangeLog entry for the changes: 2002-09-22 Kim Ahlström <[email protected]> * src/du.c: Changed " to ' for -p flag in long name initialization. (print_size): Off-by-one error in malloc:ing path fixed. Best Regards Kim Ahlstrom [email protected] http://kim.animanga.nu/ (Swedish only)
du.4111.c.diff
(application/octet-stream, 6.1 KB)
--- du.4111.orig.c Wed Jul 10 10:09:05 2002
+++ du.4111.c Sun Sep 22 01:55:00 2002
@@ -99,6 +99,31 @@
int stat ();
int lstat ();
+/* Linked list structure to hold filepaths and n_blocks,
+ to be used with the -p flag for percentage. */
+
+struct list_def
+{
+ char * path; /* Filepath (dynamically allocated) */
+ uintmax_t size; /* Number of n_blocks ( print_size()'s first argument ) */
+ struct list_def *next; /* Next node */
+};
+
+/* Nodes in the linked list of filepaths and n_blocks. */
+struct list_def *first_node, *last_node, *now_node = NULL;
+
+/* If nonzero, suppress printing. */
+static int suppress = 0;
+
+/* If nonzero, calculate percentages (-p). */
+static int display_percentage = 0;
+
+/* If nonzero, one of the -kmbB flags has been provided. */
+static int display_byte_kilo_mega = 0;
+
+/* Holds the output_block_size for human numbers (-h or -H). */
+static int h_block_size = 0;
+
/* Name under which this program was invoked. */
char *program_name;
@@ -168,6 +193,7 @@
{"kilobytes", no_argument, NULL, 'k'}, /* long form is obsolescent */
{"max-depth", required_argument, NULL, MAX_DEPTH_OPTION},
{"megabytes", no_argument, NULL, 'm'}, /* obsolescent */
+ {"percent", no_argument, NULL, 'p'},
{"one-file-system", no_argument, NULL, 'x'},
{"separate-dirs", no_argument, NULL, 'S'},
{"summarize", no_argument, NULL, 's'},
@@ -353,20 +379,94 @@
}
}
-/* Print N_BLOCKS followed by STRING on a line. NBLOCKS is the number of
- ST_NBLOCKSIZE-byte blocks; convert it to OUTPUT_BLOCK_SIZE units before
- printing. If OUTPUT_BLOCK_SIZE is negative, use a human readable
- notation instead. */
+/* If -p flag was provided we start by accumulating file data and not printing.
+ Printing will be requested by the du_files function after accumulation.
+ Print N_BLOCKS[\thuman_readable\tpercentage]\tSTRING on a line.
+ N_BLOCKS is the number of ST_NBLOCKSIZE-byte blocks; convert it to
+ OUTPUT_BLOCK_SIZE units before printing. If OUTPUT_BLOCK_SIZE is negative,
+ use a human readable notation instead. */
static void
print_size (uintmax_t n_blocks, const char *string)
{
char buf[LONGEST_HUMAN_READABLE + 1];
- printf ("%s\t%s\n",
- human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
- output_block_size, human_ceiling),
- string);
- fflush (stdout);
+ double prcnt; /* Temporary variable to hold the percent. */
+
+ if (suppress != 0)
+ {
+ /* The p flag is on and we are accumulating file data.
+ Thus we don't want to print. */
+
+ now_node = malloc (sizeof (struct list_def));
+ if (now_node == NULL)
+ {
+ fprintf (stderr, "%s: %s", program_name, strerror (errno));
+ exit (1);
+ }
+
+ if (first_node == NULL)
+ {
+ first_node = now_node;
+ now_node->next = NULL;
+ }
+ else
+ {
+ last_node->next = now_node;
+ now_node->next = NULL;
+ }
+
+ last_node = now_node;
+
+ now_node->path = malloc (strlen (string) + 1);
+ if (now_node->path == NULL)
+ {
+ fprintf (stderr, "%s: %s", program_name, strerror (errno));
+ exit (1);
+ }
+
+ strncpy (now_node->path, string, strlen (string) + 1);
+ now_node->size = n_blocks;
+ }
+ else
+ {
+ /* Print. */
+ if (display_byte_kilo_mega != 0)
+ {
+ /* Bytes, Kilobytes, Megabytes (-kmbB). */
+ printf ("%s\t",
+ human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+ output_block_size, human_ceiling));
+ }
+ if (h_block_size != 0)
+ {
+ /* Human form (-hH). */
+ printf ("%s\t",
+ human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+ h_block_size, human_ceiling));
+ }
+ if (display_percentage != 0)
+ {
+ /* Percentage (-p). */
+ prcnt = ( (double)n_blocks / (double)tot_size) * 100;
+ printf ("%.2f%%\t", prcnt);
+ }
+
+ if (display_byte_kilo_mega == 0 && h_block_size == 0 && display_percentage == 0)
+ {
+ /* No output flags were provided. */
+ printf ("%s\t%s\n",
+ human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+ output_block_size, human_ceiling),
+ string);
+ }
+ else
+ {
+ /* Filepath. */
+ printf ("%s\n", string);
+ }
+
+ fflush (stdout);
+ }
}
/* Restore the previous working directory or exit.
@@ -553,6 +653,17 @@
count_entry (arg, 1, 0, 0);
}
+ /* If the -p flag was provided,
+ stop suppressing printing and print the accumulated data. */
+ if (display_percentage != 0)
+ {
+ suppress = 0;
+ for (now_node = first_node; now_node != NULL; now_node = now_node->next)
+ {
+ print_size (now_node->size, now_node->path);
+ }
+ }
+
if (print_totals)
print_size (tot_size, _("total"));
}
@@ -582,7 +693,7 @@
human_block_size (getenv ("DU_BLOCK_SIZE"), 0, &output_block_size);
- while ((c = getopt_long (argc, argv, "abchHklmsxB:DLSX:", long_options, NULL))
+ while ((c = getopt_long (argc, argv, "abchHklmpsxB:DLSX:", long_options, NULL))
!= -1)
{
long int tmp_long;
@@ -597,22 +708,33 @@
case 'b':
output_block_size = 1;
+ display_byte_kilo_mega = 1;
break;
case 'c':
print_totals = 1;
break;
+ case 'p':
+ suppress = 1;
+ display_percentage = 1;
+ break;
+
case 'h':
- output_block_size = -1024;
+ h_block_size = -1024;
+ if(!display_byte_kilo_mega)
+ output_block_size = -1024;
break;
case 'H':
- output_block_size = -1000;
+ h_block_size = -1000;
+ if(!display_byte_kilo_mega)
+ output_block_size = -1000;
break;
case 'k':
output_block_size = 1024;
+ display_byte_kilo_mega = 1;
break;
case MAX_DEPTH_OPTION: /* --max-depth=N */
@@ -626,6 +748,7 @@
case 'm': /* obsolescent */
output_block_size = 1024 * 1024;
+ display_byte_kilo_mega = 1;
break;
case 'l':
@@ -642,6 +765,7 @@
case 'B':
human_block_size (optarg, 1, &output_block_size);
+ display_byte_kilo_mega = 1;
break;
case 'D':