bug-coreutils
[Top][All Lists]
Advanced

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

Re: current coreutils on MacOS X


From: Paul Eggert
Subject: Re: current coreutils on MacOS X
Date: Fri, 01 Sep 2006 12:42:41 -0700
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Bruno Haible <address@hidden> writes:

> 2006-08-31  Bruno Haible  <address@hidden>
>
>       * src/stat.c (print_statfs): Use memcpy to copy the fsid into an
>       uintmax_t.

Thanks for the problem report.  Since you mentioned glibc does it
a certain way I suspect we should probably be compatible, so that
coreutils behaves the same way regardless of whether it uses
glibc or not.

There are several other problems with porting stat, too (some that
I noticed on Solaris 8 while testing this).  I installed this to try
to fix them all, but quite possibly some remain on MacOS since I
haven't tested it there.

2006-09-01  Paul Eggert  <address@hidden>

        * m4/jm-macros.m4 (gl_MACROS): Call cu_PREREQ_STAT_PROG rather
        than AC_REQUIREing, so that sys/mount.h isn't tested for after
        the test result.  I'm not sure why this fix is needed, but it
        works.
        * m4/stat-prog.m4 (cu_PREREQ_STAT_PROG): Revamp to reflect better
        what stat.c actually needs.
        * src/stat.c: Include <stddef.h>
        (alignof): New macro.
        (HAVE_STRUCT_STATXFS_F_FSID___VAL, HAVE_STRUCT_STATXFS_F_FSID_VAL):
        Remove.
        (STRUCT_STATXFS_F_FSID_IS_INTEGER): New macro.
        (FSID_VAL): Remove.
        (print_statfs): If f_fsid isn't an integer, grab its words one
        at a time in little-endian order.  This is a bit easier to configure
        and should avoid a compilation failure on MacOS reported by Bruno
        Haible.

Index: m4/jm-macros.m4
===================================================================
RCS file: /fetish/cu/m4/jm-macros.m4,v
retrieving revision 1.243
diff -p -u -r1.243 jm-macros.m4
--- m4/jm-macros.m4     21 Aug 2006 07:30:47 -0000      1.243
+++ m4/jm-macros.m4     1 Sep 2006 19:39:47 -0000
@@ -79,7 +79,8 @@ AC_DEFUN([gl_MACROS],
     tcgetpgrp \
   )
 
-  AC_REQUIRE([cu_PREREQ_STAT_PROG])
+  dnl This can't use AC_REQUIRE; I'm not quite sure why.
+  cu_PREREQ_STAT_PROG
 
   # for dd.c and shred.c
   coreutils_saved_libs=$LIBS
Index: m4/stat-prog.m4
===================================================================
RCS file: /fetish/cu/m4/stat-prog.m4,v
retrieving revision 1.8
diff -p -u -r1.8 stat-prog.m4
--- m4/stat-prog.m4     29 Aug 2006 21:53:30 -0000      1.8
+++ m4/stat-prog.m4     1 Sep 2006 19:39:47 -0000
@@ -1,4 +1,4 @@
-# stat-prog.m4 serial 4
+# stat-prog.m4 serial 5
 # Record the prerequisites of src/stat.c from the coreutils package.
 
 # Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
@@ -21,59 +21,67 @@
 
 AC_DEFUN([cu_PREREQ_STAT_PROG],
 [
-  AC_CHECK_HEADERS_ONCE(sys/param.h sys/statvfs.h sys/vfs.h)
-  AC_CHECK_HEADERS(sys/mount.h, [], [],
-    [AC_INCLUDES_DEFAULT
-     [#if HAVE_SYS_PARAM_H
-       #include <sys/param.h>
-      #endif]])
-
-  # For `struct statfs' on Ultrix 4.4.
-  AC_CHECK_HEADERS_ONCE([netinet/in.h nfs/nfs_clnt.h nfs/vfs.h])
-
-  statxfs_includes="\
-$ac_includes_default
-#if HAVE_SYS_STATVFS_H
-# include <sys/statvfs.h>
-#endif
+  AC_REQUIRE([gl_FSUSAGE])
+  AC_REQUIRE([gl_FSTYPENAME])
+  AC_CHECK_HEADERS_ONCE([OS.h netinet/in.h sys/param.h sys/vfs.h])
+
+  dnl Check for vfs.h first, since this avoids a warning with nfs_client.h
+  dnl on Solaris 8.
+  test $ac_cv_header_sys_param_h = yes &&
+  test $ac_cv_header_sys_mount_h = yes &&
+  AC_CHECK_HEADERS([nfs/vfs.h],
+    [AC_CHECK_HEADERS([nfs/nfs_client.h])])
+
+  statvfs_includes="\
+AC_INCLUDES_DEFAULT
+#include <sys/statvfs.h>
+"
+  statfs_includes="\
+AC_INCLUDES_DEFAULT
 #if HAVE_SYS_VFS_H
 # include <sys/vfs.h>
-#endif
-#if !HAVE_SYS_STATVFS_H && !HAVE_SYS_VFS_H
-# if HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
-/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
-#  include <sys/param.h>
-#  include <sys/mount.h>
-# elif HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H
-/* Ultrix 4.4 needs these for the declaration of struct statfs.  */
+#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# include <sys/mount.h>
+# if HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H
 #  include <netinet/in.h>
 #  include <nfs/nfs_clnt.h>
 #  include <nfs/vfs.h>
 # endif
+#elif HAVE_OS_H
+# include <fs_info.h>
 #endif
 "
-  AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$statxfs_includes])
   dnl Keep this long conditional in sync with the USE_STATVFS conditional
   dnl in ../src/stat.c.
-  if test $ac_cv_header_sys_statvfs_h = yes &&
-    { AC_CHECK_MEMBERS(
-       [struct statvfs.f_basetype,
-        struct statvfs.f_fstypename,
-        struct statvfs.f_type],,,
-       [$statxfs_includes])
-      test $ac_cv_member_struct_statvfs_f_basetype = yes ||
-      test $ac_cv_member_struct_statvfs_f_fstypename = yes ||
-      { test $ac_cv_member_struct_statvfs_f_type = yes &&
-       test $ac_cv_member_struct_statfs_f_fstypename != yes; }; }; then
-    AC_CHECK_MEMBERS(
-      [struct statvfs.f_fsid.__val, struct statvfs.f_fsid.val,
-       struct statvfs.f_namelen, struct statvfs.f_namemax],,,
-      [$statxfs_includes])
+  if test "$fu_cv_sys_stat_statvfs" = yes &&
+     { AC_CHECK_MEMBERS([struct statvfs.f_basetype],,, [$statvfs_includes])
+       test $ac_cv_member_struct_statvfs_f_basetype = yes ||
+       { AC_CHECK_MEMBERS([struct statvfs.f_fstypename],,, [$statvfs_includes])
+        test $ac_cv_member_struct_statvfs_f_fstypename = yes ||
+        { test $ac_cv_member_struct_statfs_f_fstypename != yes &&
+          { AC_CHECK_MEMBERS([struct statvfs.f_type],,, [$statvfs_includes])
+            test $ac_cv_member_struct_statvfs_f_type = yes; }; }; }; }
+  then
+    AC_CHECK_MEMBERS([struct statvfs.f_namemax],,, [$statvfs_includes])
+    AC_COMPILE_IFELSE(
+      [AC_LANG_PROGRAM(
+        [$statvfs_includes],
+        [static statvfs s;
+         return (s.s_fsid ^ 0) == 0;])],
+      [AC_DEFINE([STRUCT_STATVFS_F_FSID_IS_INTEGER], 1,
+        [Define to 1 if the f_fsid member of struct statvfs is an integer.])])
   else
-    AC_CHECK_MEMBERS(
-      [struct statfs.f_basetype, struct statfs.f_fsid.__val,
-       struct statfs.f_fsid.val, struct statfs.f_namelen,
-       struct statfs.f_namemax, struct statfs.f_type],,,
-      [$statxfs_includes])
+    AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_type],,,
+      [$statfs_includes])
+    if test $ac_cv_header_OS_h != yes; then
+      AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [$statfs_includes],
+          [static statfs s;
+           return (s.s_fsid ^ 0) == 0;])],
+       [AC_DEFINE([STRUCT_STATFS_F_FSID_IS_INTEGER], 1,
+          [Define to 1 if the f_fsid member of struct statfs is an integer.])])
+    fi
   fi
 ])
Index: src/stat.c
===================================================================
RCS file: /fetish/cu/src/stat.c,v
retrieving revision 1.100
diff -p -u -r1.100 stat.c
--- src/stat.c  29 Aug 2006 21:53:30 -0000      1.100
+++ src/stat.c  1 Sep 2006 19:39:47 -0000
@@ -29,6 +29,7 @@
 # define USE_STATVFS 0
 #endif
 
+#include <stddef.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <pwd.h>
@@ -68,10 +69,11 @@
 #include "strftime.h"
 #include "xreadlink.h"
 
+#define alignof(type) offsetof (struct { char c; type x; }, x)
+
 #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_FSID_VAL HAVE_STRUCT_STATVFS_F_FSID_VAL
+# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER
 # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE
 # if HAVE_STRUCT_STATVFS_F_NAMEMAX
 #  define SB_F_NAMEMAX(S) ((S)->f_namemax)
@@ -113,23 +115,15 @@ statfs (char const *filename, struct fs_
 #  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 HAVE_STRUCT_STATXFS_F_FSID_VAL 0
+#  define STRUCT_STATXFS_F_FSID_IS_INTEGER true
 #  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 HAVE_STRUCT_STATXFS_F_FSID_VAL HAVE_STRUCT_STATFS_F_FSID_VAL
+#  define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATFS_F_FSID_IS_INTEGER
 #  define STATFS_FRSIZE(S) 0
 # endif
 #endif
 
-#if HAVE_STRUCT_STATXFS_F_FSID___VAL
-# define FSID_VAL __val
-#elif HAVE_STRUCT_STATXFS_F_FSID_VAL
-# define FSID_VAL val
-#endif
-
 #ifdef SB_F_NAMEMAX
 # define OUT_NAMEMAX out_uint
 #else
@@ -415,16 +409,22 @@ print_statfs (char *pformat, size_t pref
 
     case 'i':
       {
-#ifdef FSID_VAL
-       uintmax_t val0 = statfsbuf->f_fsid.FSID_VAL[0];
-       uintmax_t val1 = statfsbuf->f_fsid.FSID_VAL[1];
-       uintmax_t fsid =
-         (val1
-          + (sizeof statfsbuf->f_fsid.FSID_VAL[1] < sizeof fsid
-             ? val0 << (CHAR_BIT * sizeof statfsbuf->f_fsid.FSID_VAL[1])
-             : 0));
-#else
+#if STRUCT_STATXFS_F_FSID_IS_INTEGER
        uintmax_t fsid = statfsbuf->f_fsid;
+#else
+       typedef unsigned int fsid_word;
+       verify (alignof (STRUCT_STATVFS) % alignof (fsid_word) == 0);
+       verify (offsetof (STRUCT_STATVFS, f_fsid) % alignof (fsid_word) == 0);
+       verify (sizeof statfsbuf->f_fsid % alignof (fsid_word) == 0);
+       fsid_word const *p = (fsid_word *) &statfsbuf->f_fsid;
+
+       /* Assume a little-endian word order, as that is compatible
+          with glibc's statvfs implementation.  */
+       uintmax_t fsid = 0;
+       int words = sizeof statfsbuf->f_fsid / sizeof *p;
+       int i;
+       for (i = 0; i < words && i * sizeof *p < sizeof fsid; i++)
+         fsid |= p[words - 1 - i] << (i * CHAR_BIT * sizeof *p);
 #endif
        out_uint_x (pformat, prefix_len, fsid);
       }




reply via email to

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