bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

patch, apparent size for ls


From: Joakim Rosqvist (JRO.SE)
Subject: patch, apparent size for ls
Date: Mon, 17 Jan 2005 20:31:24 +0100


Hi,

(I have submitted this before, but do not see my mail in the 
gnu-coreutils archives so I try again)

This is a patch that adds the --apparent-size option found in "du"
to the ls command. It works like --size but prints the file size
instead of the disk usage. Of course, the file size can be had in
the long listing format already, but then with only one file per line.

After upgrading from Redhat9 to the latest Fedora, I found that zero-length
files show up as 4kb using "ls -s", that's what prompted me to implement
--apparent-size. Patches to Changelog and the infopage are also included.

I'm new here, so I hope this is the correct way to submit a patch
and that someone will put it into coreutils if it is approved.



diff -u -p -r coreutils-5.3.0/ChangeLog coreutils-5.3.0a/ChangeLog
--- coreutils-5.3.0/ChangeLog   2005-01-08 10:42:21.000000000 +0100
+++ coreutils-5.3.0a/ChangeLog  2005-01-13 22:29:25.433459753 +0100
@@ -1,3 +1,16 @@
+2005-01-13  Joakim Rosqvist  <address@hidden>
+       * src/ls.c: New option: --apparent-size
+       (enum) [APPARENT_SIZE_OPTION]: New member.
+       (long_options): Add it.
+       (usage): Describe it.
+       new global apparent_size
+       (getopt_long): check new switch and if found also enable -s
+       (decode_switches): initialize
+       (gobble_file): also return filesize
+       New function block_format(), as a wrapper for human_readable()
+       Call block_format instead of human_readable when a block size
+       rather than file size is used
+
 2005-01-08  Jim Meyering  <address@hidden>
 
        * Version 5.3.0.
diff -u -p -r coreutils-5.3.0/doc/coreutils.info 
coreutils-5.3.0a/doc/coreutils.info
--- coreutils-5.3.0/doc/coreutils.info  2005-01-08 11:56:34.000000000 +0100
+++ coreutils-5.3.0a/doc/coreutils.info 2005-01-13 22:49:25.404675740 +0100
@@ -4437,6 +4437,11 @@ File: coreutils.info,  Node: What inform
 These options affect the information that `ls' displays.  By default,
 only file names are shown.
 
+`--apparent-size'
+     Print each file's size to the left of the filename, similar to
+     --size. Filesizes are also printed in the long listing (`-l') format,
+     but then only one file per line.
+
 `--author'
      List each file's author when producing long format directory
      listings.  In GNU/Hurd, file authors can differ from their owners,
diff -u -p -r coreutils-5.3.0/src/ls.c coreutils-5.3.0a/src/ls.c
--- coreutils-5.3.0/src/ls.c    2004-12-17 08:34:35.000000000 +0100
+++ coreutils-5.3.0a/src/ls.c   2005-01-13 21:41:37.698999153 +0100
@@ -234,7 +234,7 @@ static char *make_link_path (const char 
 static int decode_switches (int argc, char **argv);
 static bool file_ignored (char const *name);
 static uintmax_t gobble_file (char const *name, enum filetype type,
-                             bool command_line_arg, char const *dirname);
+                             bool command_line_arg, char const *dirname, 
uintmax_t *filesizeret);
 static void print_color_indicator (const char *name, mode_t mode, int linkok);
 static void put_indicator (const struct bin_str *ind);
 static void add_ignore_pattern (const char *pattern);
@@ -265,6 +265,7 @@ static void queue_directory (char const 
                             bool command_line_arg);
 static void sort_files (void);
 static void parse_ls_color (void);
+static char *block_format (uintmax_t n_usage, uintmax_t n_apparent, char *buf);
 void usage (int status);
 
 /* The name the program was run with, stripped of any leading path.  */
@@ -339,14 +340,14 @@ static int current_time_ns = -1;
    numbers, minor device numbers, and file sizes, respectively.  */
 
 static int inode_number_width;
-static int block_size_width;
+static int block_size_width;   /* --size or --apparent-size */
 static int nlink_width;
 static int owner_width;
 static int group_width;
 static int author_width;
 static int major_device_number_width;
 static int minor_device_number_width;
-static int file_size_width;
+static int file_size_width;    /* width of the filesize column of ls -l */
 
 /* Option flags */
 
@@ -429,6 +430,10 @@ static bool sort_reverse;
 
 static bool print_owner = true;
 
+/* If true, sizes printed by --size are not disk usage of each file,
+      but instead the apparent size (a la stat.st_size).  */
+static bool apparent_size;
+
 /* True means to display author information.  */
 
 static bool print_author;
@@ -701,7 +706,8 @@ enum
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
 {
-  AUTHOR_OPTION = CHAR_MAX + 1,
+  APPARENT_SIZE_OPTION = CHAR_MAX + 1,
+  AUTHOR_OPTION,
   BLOCK_SIZE_OPTION,
   COLOR_OPTION,
   DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
@@ -720,6 +726,7 @@ enum
 static struct option const long_options[] =
 {
   {"all", no_argument, 0, 'a'},
+  {"apparent-size", no_argument, 0, APPARENT_SIZE_OPTION},
   {"escape", no_argument, 0, 'b'},
   {"directory", no_argument, 0, 'd'},
   {"dired", no_argument, 0, 'D'},
@@ -1221,13 +1228,13 @@ main (int argc, char **argv)
   if (n_files <= 0)
     {
       if (immediate_dirs)
-       gobble_file (".", directory, true, "");
+       gobble_file (".", directory, true, "", NULL);
       else
        queue_directory (".", NULL, true);
     }
   else
     do
-      gobble_file (argv[i++], unknown, true, "");
+      gobble_file (argv[i++], unknown, true, "", NULL);
     while (i < argc);
 
   if (files_index)
@@ -1381,6 +1388,7 @@ decode_switches (int argc, char **argv)
   sort_type = sort_name;
   sort_reverse = false;
   numeric_ids = false;
+  apparent_size = false;
   print_block_size = false;
   indicator_style = none;
   print_inode = false;
@@ -1666,6 +1674,11 @@ decode_switches (int argc, char **argv)
            format = one_per_line;
          break;
 
+       case APPARENT_SIZE_OPTION:
+         print_block_size = true;
+         apparent_size = true;
+         break;
+
         case AUTHOR_OPTION:
           print_author = true;
           break;
@@ -2251,6 +2264,7 @@ print_dir (char const *name, char const 
   register DIR *dirp;
   register struct dirent *next;
   register uintmax_t total_blocks = 0;
+  uintmax_t file_size, total_size = 0;
   static bool first = true;
 
   errno = 0;
@@ -2315,7 +2329,8 @@ print_dir (char const *name, char const 
                  || next->d_type == DT_SOCK)
                type = next->d_type;
 #endif
-             total_blocks += gobble_file (next->d_name, type, false, name);
+             total_blocks += gobble_file (next->d_name, type, false, name, 
&file_size);
+             total_size += file_size;
            }
        }
       else if (errno != 0)
@@ -2365,8 +2380,7 @@ print_dir (char const *name, char const 
       p = _("total");
       DIRED_FPUTS (p, stdout, strlen (p));
       DIRED_PUTCHAR (' ');
-      p = human_readable (total_blocks, buf, human_output_opts,
-                         ST_NBLOCKSIZE, output_block_size);
+      p = block_format (total_blocks, total_size, buf);
       DIRED_FPUTS (p, stdout, strlen (p));
       DIRED_PUTCHAR ('\n');
     }
@@ -2459,7 +2473,7 @@ clear_files (void)
 
 static uintmax_t
 gobble_file (char const *name, enum filetype type, bool command_line_arg,
-            char const *dirname)
+            char const *dirname, uintmax_t *file_size_ret)
 {
   register uintmax_t blocks;
   register char *path;
@@ -2546,6 +2560,7 @@ gobble_file (char const *name, enum file
       if (err < 0)
        {
          file_failure (command_line_arg, "%s", path);
+         if (file_size_ret)  *file_size_ret = 0;
          return 0;
        }
 
@@ -2614,9 +2629,10 @@ gobble_file (char const *name, enum file
       blocks = ST_NBLOCKS (f->stat);
       {
        char buf[LONGEST_HUMAN_READABLE + 1];
-       int len = mbswidth (human_readable (blocks, buf, human_output_opts,
-                                           ST_NBLOCKSIZE, output_block_size),
-                           0);
+       int len = mbswidth (block_format (blocks, 
+                                         unsigned_file_size (f->stat.st_size), 
+                                         buf),
+                           0);
        if (block_size_width < len)
          block_size_width = len;
       }
@@ -2685,6 +2701,7 @@ gobble_file (char const *name, enum file
   f->name = xstrdup (name);
   files_index++;
 
+  if (file_size_ret)  *file_size_ret = unsigned_file_size (f->stat.st_size);
   return blocks;
 }
 
@@ -3039,6 +3056,21 @@ print_current_files (void)
     }
 }
 
+/* Wrapper for human_readable that selects the proper type of size
+   to display.  */
+
+char *
+block_format (uintmax_t n_usage, uintmax_t n_apparent, char *buf)
+{
+    if (apparent_size)
+       return human_readable (n_apparent, buf, human_output_opts,
+                              1, file_output_block_size);
+    else
+       return human_readable (n_usage, buf, human_output_opts,
+                              ST_NBLOCKSIZE, output_block_size);
+}
+
+
 /* Return the expected number of columns in a long-format time stamp,
    or zero if it cannot be calculated.  */
 
@@ -3254,8 +3286,7 @@ print_long_format (const struct fileinfo
     {
       char hbuf[LONGEST_HUMAN_READABLE + 1];
       char const *blocks =
-       human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
-                       ST_NBLOCKSIZE, output_block_size);
+       block_format (ST_NBLOCKS (f->stat), unsigned_file_size 
(f->stat.st_size), hbuf);
       int pad;
       for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
        *p++ = ' ';
@@ -3620,8 +3651,7 @@ print_file_name_and_frills (const struct
 
   if (print_block_size)
     printf ("%*s ", format == with_commas ? 0 : block_size_width,
-           human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
-                           ST_NBLOCKSIZE, output_block_size));
+           block_format (ST_NBLOCKS (f->stat), unsigned_file_size 
(f->stat.st_size), buf));
 
   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, NULL);
 
@@ -3746,9 +3776,8 @@ length_of_file_name_and_frills (const st
 
   if (print_block_size)
     len += 1 + (format == with_commas
-               ? strlen (human_readable (ST_NBLOCKS (f->stat), buf,
-                                         human_output_opts, ST_NBLOCKSIZE,
-                                         output_block_size))
+               ? strlen (block_format (ST_NBLOCKS (f->stat), 
+                       unsigned_file_size (f->stat.st_size), buf))
                : block_size_width);
 
   quote_name (NULL, f->name, filename_quoting_options, &name_width);
@@ -4070,6 +4099,8 @@ Mandatory arguments to long options are 
   -a, --all                  do not ignore entries starting with .\n\
   -A, --almost-all           do not list implied . and ..\n\
       --author               with -l, print the author of each file\n\
+      --apparent-size        like -s, but print file size rather than\n\
+                               disk usage\n\
   -b, --escape               print octal escapes for nongraphic characters\n\
 "), stdout);
       fputs (_("\






reply via email to

[Prev in Thread] Current Thread [Next in Thread]