]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 23 Aug 2006 23:40:21 +0000 (23:40 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 23 Aug 2006 23:40:21 +0000 (23:40 +0000)
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove.  All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len.  All uses changed.  Output '?', not '*', for unknown
data or errors.  Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.

ChangeLog
src/stat.c

index 4b9b1ae77b78885124c66d94a7721d93cc061216..1ae6fb79c70afa862bb326eb10da06471f13abb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
+2006-08-23  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define.  This
+       macro was being used without being defined.
+       (SB_F_NAMEMAX): Remove cast.
+       (f_fsid) [BeOS]: Likewise.
+       (OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
+       All uses changed.
+       (out_string, out_int, out_uint, out_uint_o, out_uint_x): New
+       functions.
+       (xstrcat): Remove.  All uses changed to use the above functions.
+       (print_statfs, print_stat): 2nd arg is now the prefix len, not the
+       buffer len.  All uses changed.  Output '?', not '*', for unknown
+       data or errors.  Do not assume signed values can be interchanged
+       with unsigned when printing.
+       (print_statfs): For %i, print the fsid as a single int, not as a
+       pair.
+       (print_it): Quote invalid format better.
+
+       * NEWS: printf supports the I flag.
+       * src/printf.c (print_formatted) [glibc 2.2 or later]: Likewise.
+
 2006-08-23  Bruno Haible  <bruno@clisp.org>
 
+       * src/stat.c (STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
+       (f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
+       (STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
+
        * src/ls.c (SA_RESTART): Fallback define.
 
 2006-08-23  Paul Eggert  <eggert@cs.ucla.edu>
index 777266ea3aaf5bd23e3a0edf29bd6dbee9975c55..83291f5ec9e757c431e56c3206d3cfc3b1200b8a 100644 (file)
@@ -48,6 +48,8 @@
 #  include <nfs/nfs_clnt.h>
 #  include <nfs/vfs.h>
 # endif
+#elif HAVE_OS_H /* BeOS */
+# include <fs_info.h>
 #endif
 
 #include "system.h"
 
 #if USE_STATVFS
 # define STRUCT_STATVFS struct statvfs
+# define HAVE_STRUCT_STATXFS_F_FSID___VAL HAVE_STRUCT_STATVFS_F_FSID___VAL
 # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE
 # if HAVE_STRUCT_STATVFS_F_NAMEMAX
-#  define SB_F_NAMEMAX(S) ((uintmax_t) ((S)->f_namemax))
+#  define SB_F_NAMEMAX(S) ((S)->f_namemax)
 # endif
 # define STATFS statvfs
 # define STATFS_FRSIZE(S) ((S)->f_frsize)
 #else
-# define STRUCT_STATVFS struct statfs
 # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS_F_TYPE
 # if HAVE_STRUCT_STATFS_F_NAMELEN
-#  define SB_F_NAMEMAX(S) ((uintmax_t) ((S)->f_namelen))
+#  define SB_F_NAMEMAX(S) ((S)->f_namelen)
 # endif
 # define STATFS statfs
-# define STATFS_FRSIZE(S) 0
+# if HAVE_OS_H /* BeOS */
+/* BeOS has a statvfs function, but it does not return sensible values
+   for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and
+   f_fstypename.  Use 'struct fs_info' instead.  */
+static int
+statfs (char const *filename, struct fs_info *buf)
+{
+  dev_t device = dev_for_path (filename);
+  if (device < 0)
+    {
+      errno = (device == B_ENTRY_NOT_FOUND ? ENOENT
+              : device == B_BAD_VALUE ? EINVAL
+              : device == B_NAME_TOO_LONG ? ENAMETOOLONG
+              : device == B_NO_MEMORY ? ENOMEM
+              : device == B_FILE_ERROR ? EIO
+              : 0);
+      return -1;
+    }
+  /* If successful, buf->dev will be == device.  */
+  return fs_stat_dev (device, buf);
+}
+#  define f_fsid dev
+#  define f_blocks total_blocks
+#  define f_bfree free_blocks
+#  define f_bavail free_blocks
+#  define f_bsize io_size
+#  define f_files total_nodes
+#  define f_ffree free_nodes
+#  define STRUCT_STATVFS struct fs_info
+#  define HAVE_STRUCT_STATXFS_F_FSID___VAL 0
+#  define STATFS_FRSIZE(S) ((S)->block_size)
+# else
+#  define STRUCT_STATVFS struct statfs
+#  define HAVE_STRUCT_STATXFS_F_FSID___VAL HAVE_STRUCT_STATFS_F_FSID___VAL
+#  define STATFS_FRSIZE(S) 0
+# endif
 #endif
 
 #ifdef SB_F_NAMEMAX
-# define NAMEMAX_FORMAT PRIuMAX
+# define OUT_NAMEMAX out_uint
 #else
 /* NetBSD 1.5.2 has neither f_namemax nor f_namelen.  */
 # define SB_F_NAMEMAX(S) "*"
-# define NAMEMAX_FORMAT "s"
+# define OUT_NAMEMAX out_string
 #endif
 
 #if HAVE_STRUCT_STATVFS_F_BASETYPE
 #else
 # if HAVE_STRUCT_STATVFS_F_FSTYPENAME || HAVE_STRUCT_STATFS_F_FSTYPENAME
 #  define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename
+# elif HAVE_OS_H /* BeOS */
+#  define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME fsh_name
 # endif
 #endif
 
@@ -319,22 +358,40 @@ human_time (struct timespec t)
   return str;
 }
 
-/* Like strcat, but don't return anything and do check that
-   DEST_BUFSIZE is at least a long as strlen (DEST) + strlen (SRC) + 1.
-   The signature is deliberately different from that of strncat.  */
 static void
-xstrcat (char *dest, size_t dest_bufsize, char const *src)
+out_string (char *pformat, size_t prefix_len, char const *arg)
+{
+  strcpy (pformat + prefix_len, "s");
+  printf (pformat, arg);
+}
+static void
+out_int (char *pformat, size_t prefix_len, intmax_t arg)
+{
+  strcpy (pformat + prefix_len, PRIdMAX);
+  printf (pformat, arg);
+}
+static void
+out_uint (char *pformat, size_t prefix_len, uintmax_t arg)
+{
+  strcpy (pformat + prefix_len, PRIuMAX);
+  printf (pformat, arg);
+}
+static void
+out_uint_o (char *pformat, size_t prefix_len, uintmax_t arg)
+{
+  strcpy (pformat + prefix_len, PRIoMAX);
+  printf (pformat, arg);
+}
+static void
+out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg)
 {
-  size_t dest_len = strlen (dest);
-  size_t src_len = strlen (src);
-  if (dest_bufsize < dest_len + src_len + 1)
-    abort ();
-  memcpy (dest + dest_len, src, src_len + 1);
+  strcpy (pformat + prefix_len, PRIxMAX);
+  printf (pformat, arg);
 }
 
 /* print statfs info */
 static void
-print_statfs (char *pformat, size_t buf_len, char m, char const *filename,
+print_statfs (char *pformat, size_t prefix_len, char m, char const *filename,
              void const *data)
 {
   STRUCT_STATVFS const *statfsbuf = data;
@@ -342,82 +399,75 @@ print_statfs (char *pformat, size_t buf_len, char m, char const *filename,
   switch (m)
     {
     case 'n':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, filename);
+      out_string (pformat, prefix_len, filename);
       break;
 
     case 'i':
+      {
 #if HAVE_STRUCT_STATXFS_F_FSID___VAL
-      xstrcat (pformat, buf_len, "x %-8x");
-      printf (pformat, statfsbuf->f_fsid.__val[0], /* u_long */
-             statfsbuf->f_fsid.__val[1]);
+       uintmax_t val0 = statfsbuf->f_fsid.__val[0];
+       uintmax_t val1 = statfsbuf->f_fsid.__val[1];
+       uintmax_t fsid =
+         (val1
+          + (sizeof statfsbuf->f_fsid.__val[1] < sizeof fsid
+             ? val0 << (CHAR_BIT * sizeof sizeof statfsbuf->f_fsid.__val[1])
+             : 0));
 #else
-      xstrcat (pformat, buf_len, "Lx");
-      printf (pformat, statfsbuf->f_fsid);
+       uintmax_t fsid = statfsbuf->f_fsid;
 #endif
+       out_uint_x (pformat, prefix_len, fsid);
+      }
       break;
 
     case 'l':
-      xstrcat (pformat, buf_len, NAMEMAX_FORMAT);
-      printf (pformat, SB_F_NAMEMAX (statfsbuf));
+      OUT_NAMEMAX (pformat, prefix_len, SB_F_NAMEMAX (statfsbuf));
       break;
     case 't':
 #if HAVE_STRUCT_STATXFS_F_TYPE
-      xstrcat (pformat, buf_len, "lx");
-      printf (pformat,
-             (unsigned long int) (statfsbuf->f_type));  /* no equiv. */
+      out_uint_x (pformat, prefix_len, statfsbuf->f_type);
 #else
-      fputc ('*', stdout);
+      fputc ('?', stdout);
 #endif
       break;
     case 'T':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, human_fstype (statfsbuf));
+      out_string (pformat, prefix_len, human_fstype (statfsbuf));
       break;
     case 'b':
-      xstrcat (pformat, buf_len, PRIdMAX);
-      printf (pformat, (intmax_t) (statfsbuf->f_blocks));
+      out_int (pformat, prefix_len, statfsbuf->f_blocks);
       break;
     case 'f':
-      xstrcat (pformat, buf_len, PRIdMAX);
-      printf (pformat, (intmax_t) (statfsbuf->f_bfree));
+      out_int (pformat, prefix_len, statfsbuf->f_bfree);
       break;
     case 'a':
-      xstrcat (pformat, buf_len, PRIdMAX);
-      printf (pformat, (intmax_t) (statfsbuf->f_bavail));
+      out_int (pformat, prefix_len, statfsbuf->f_bavail);
       break;
     case 's':
-      xstrcat (pformat, buf_len, "lu");
-      printf (pformat, (unsigned long int) (statfsbuf->f_bsize));
+      out_uint (pformat, prefix_len, statfsbuf->f_bsize);
       break;
     case 'S':
       {
-       unsigned long int frsize = STATFS_FRSIZE (statfsbuf);
+       uintmax_t frsize = STATFS_FRSIZE (statfsbuf);
        if (! frsize)
          frsize = statfsbuf->f_bsize;
-       xstrcat (pformat, buf_len, "lu");
-       printf (pformat, frsize);
+       out_uint (pformat, prefix_len, frsize);
       }
       break;
     case 'c':
-      xstrcat (pformat, buf_len, PRIdMAX);
-      printf (pformat, (intmax_t) (statfsbuf->f_files));
+      out_int (pformat, prefix_len, statfsbuf->f_files);
       break;
     case 'd':
-      xstrcat (pformat, buf_len, PRIdMAX);
-      printf (pformat, (intmax_t) (statfsbuf->f_ffree));
+      out_int (pformat, prefix_len, statfsbuf->f_ffree);
       break;
 
     default:
-      xstrcat (pformat, buf_len, "c");
-      printf (pformat, m);
+      fputc ('?', stdout);
       break;
     }
 }
 
 /* print stat info */
 static void
-print_stat (char *pformat, size_t buf_len, char m,
+print_stat (char *pformat, size_t prefix_len, char m,
            char const *filename, void const *data)
 {
   struct stat *statbuf = (struct stat *) data;
@@ -427,11 +477,10 @@ print_stat (char *pformat, size_t buf_len, char m,
   switch (m)
     {
     case 'n':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, filename);
+      out_string (pformat, prefix_len, filename);
       break;
     case 'N':
-      xstrcat (pformat, buf_len, "s");
+      out_string (pformat, prefix_len, quote (filename));
       if (S_ISLNK (statbuf->st_mode))
        {
          char *linkname = xreadlink (filename, statbuf->st_size);
@@ -441,120 +490,99 @@ print_stat (char *pformat, size_t buf_len, char m,
                     quote (filename));
              return;
            }
-         /*printf("\"%s\" -> \"%s\"", filename, linkname); */
-         printf (pformat, quote (filename));
          printf (" -> ");
-         printf (pformat, quote (linkname));
-       }
-      else
-       {
-         printf (pformat, quote (filename));
+         out_string (pformat, prefix_len, quote (linkname));
        }
       break;
     case 'd':
-      xstrcat (pformat, buf_len, PRIuMAX);
-      printf (pformat, (uintmax_t) statbuf->st_dev);
+      out_uint (pformat, prefix_len, statbuf->st_dev);
       break;
     case 'D':
-      xstrcat (pformat, buf_len, PRIxMAX);
-      printf (pformat, (uintmax_t) statbuf->st_dev);
+      out_uint_x (pformat, prefix_len, statbuf->st_dev);
       break;
     case 'i':
-      xstrcat (pformat, buf_len, PRIuMAX);
-      printf (pformat, (uintmax_t) statbuf->st_ino);
+      out_uint (pformat, prefix_len, statbuf->st_ino);
       break;
     case 'a':
-      xstrcat (pformat, buf_len, "lo");
-      printf (pformat,
-             (unsigned long int) (statbuf->st_mode & CHMOD_MODE_BITS));
+      out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS);
       break;
     case 'A':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, human_access (statbuf));
+      out_string (pformat, prefix_len, human_access (statbuf));
       break;
     case 'f':
-      xstrcat (pformat, buf_len, "lx");
-      printf (pformat, (unsigned long int) statbuf->st_mode);
+      out_uint_x (pformat, prefix_len, statbuf->st_mode);
       break;
     case 'F':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, file_type (statbuf));
+      out_string (pformat, prefix_len, file_type (statbuf));
       break;
     case 'h':
-      xstrcat (pformat, buf_len, "lu");
-      printf (pformat, (unsigned long int) statbuf->st_nlink);
+      out_uint (pformat, prefix_len, statbuf->st_nlink);
       break;
     case 'u':
-      xstrcat (pformat, buf_len, "lu");
-      printf (pformat, (unsigned long int) statbuf->st_uid);
+      out_uint (pformat, prefix_len, statbuf->st_uid);
       break;
     case 'U':
-      xstrcat (pformat, buf_len, "s");
       setpwent ();
       pw_ent = getpwuid (statbuf->st_uid);
-      printf (pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
+      out_string (pformat, prefix_len,
+                 pw_ent ? pw_ent->pw_name : "UNKNOWN");
       break;
     case 'g':
-      xstrcat (pformat, buf_len, "lu");
-      printf (pformat, (unsigned long int) statbuf->st_gid);
+      out_uint (pformat, prefix_len, statbuf->st_gid);
       break;
     case 'G':
-      xstrcat (pformat, buf_len, "s");
       setgrent ();
       gw_ent = getgrgid (statbuf->st_gid);
-      printf (pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
+      out_string (pformat, prefix_len,
+                 gw_ent ? gw_ent->gr_name : "UNKNOWN");
       break;
     case 't':
-      xstrcat (pformat, buf_len, "lx");
-      printf (pformat, (unsigned long int) major (statbuf->st_rdev));
+      out_uint_x (pformat, prefix_len, major (statbuf->st_rdev));
       break;
     case 'T':
-      xstrcat (pformat, buf_len, "lx");
-      printf (pformat, (unsigned long int) minor (statbuf->st_rdev));
+      out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev));
       break;
     case 's':
-      xstrcat (pformat, buf_len, PRIuMAX);
-      printf (pformat, (uintmax_t) (statbuf->st_size));
+      out_uint (pformat, prefix_len, statbuf->st_size);
       break;
     case 'B':
-      xstrcat (pformat, buf_len, "lu");
-      printf (pformat, (unsigned long int) ST_NBLOCKSIZE);
+      out_uint (pformat, prefix_len, ST_NBLOCKSIZE);
       break;
     case 'b':
-      xstrcat (pformat, buf_len, PRIuMAX);
-      printf (pformat, (uintmax_t) ST_NBLOCKS (*statbuf));
+      out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf));
       break;
     case 'o':
-      xstrcat (pformat, buf_len, "lu");
-      printf (pformat, (unsigned long int) statbuf->st_blksize);
+      out_uint (pformat, prefix_len, statbuf->st_blksize);
       break;
     case 'x':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, human_time (get_stat_atime (statbuf)));
+      out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf)));
       break;
     case 'X':
-      xstrcat (pformat, buf_len, TYPE_SIGNED (time_t) ? "ld" : "lu");
-      printf (pformat, (unsigned long int) statbuf->st_atime);
+      if (TYPE_SIGNED (time_t))
+       out_int (pformat, prefix_len, statbuf->st_atime);
+      else
+       out_uint (pformat, prefix_len, statbuf->st_atime);
       break;
     case 'y':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, human_time (get_stat_mtime (statbuf)));
+      out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf)));
       break;
     case 'Y':
-      xstrcat (pformat, buf_len, TYPE_SIGNED (time_t) ? "ld" : "lu");
-      printf (pformat, (unsigned long int) statbuf->st_mtime);
+      if (TYPE_SIGNED (time_t))
+       out_int (pformat, prefix_len, statbuf->st_mtime);
+      else
+       out_uint (pformat, prefix_len, statbuf->st_mtime);
       break;
     case 'z':
-      xstrcat (pformat, buf_len, "s");
-      printf (pformat, human_time (get_stat_ctime (statbuf)));
+      out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf)));
       break;
     case 'Z':
-      xstrcat (pformat, buf_len, TYPE_SIGNED (time_t) ? "ld" : "lu");
-      printf (pformat, (unsigned long int) statbuf->st_ctime);
+      if (TYPE_SIGNED (time_t))
+       out_int (pformat, prefix_len, statbuf->st_ctime);
+      else
+       out_uint (pformat, prefix_len, statbuf->st_ctime);
       break;
     default:
-      xstrcat (pformat, buf_len, "c");
-      printf (pformat, m);
+      fputc ('?', stdout);
       break;
     }
 }
@@ -604,7 +632,14 @@ print_it (char const *format, char const *filename,
 {
   /* Add 2 to accommodate our conversion of the stat `%s' format string
      to the longer printf `%llu' one.  */
-  size_t n_alloc = strlen (format) + 2 + 1;
+  enum
+    {
+      MAX_ADDITIONAL_BYTES =
+       (MAX (sizeof PRIdMAX,
+             MAX (sizeof PRIoMAX, MAX (sizeof PRIuMAX, sizeof PRIxMAX)))
+        - 1)
+    };
+  size_t n_alloc = strlen (format) + MAX_ADDITIONAL_BYTES + 1;
   char *dest = xmalloc (n_alloc);
   char const *b;
   for (b = format; *b; b++)
@@ -614,9 +649,8 @@ print_it (char const *format, char const *filename,
        case '%':
          {
            size_t len = strspn (b + 1, "#-+.I 0123456789");
-           char const *fmt_char = b + 1 + len;
-           memcpy (dest, b, 1 + len);
-           dest[1 + len] = 0;
+           char const *fmt_char = b + len + 1;
+           memcpy (dest, b, len + 1);
 
            b = fmt_char;
            switch (*fmt_char)
@@ -626,12 +660,16 @@ print_it (char const *format, char const *filename,
                /* fall through */
              case '%':
                if (0 < len)
-                 error (EXIT_FAILURE, 0, _("%s%s: invalid directive"),
-                        quotearg_colon (dest), *fmt_char ? "%" : "");
+                 {
+                   dest[len + 1] = *fmt_char;
+                   dest[len + 2] = '\0';
+                   error (EXIT_FAILURE, 0, _("%s: invalid directive"),
+                          quotearg_colon (dest));
+                 }
                putchar ('%');
                break;
              default:
-               print_func (dest, n_alloc, *fmt_char, filename, data);
+               print_func (dest, len + 1, *fmt_char, filename, data);
                break;
              }
            break;