bug-gnulib
[Top][All Lists]
Advanced

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

coreutils-6.0 on BeOS (9)


From: Bruno Haible
Subject: coreutils-6.0 on BeOS (9)
Date: Wed, 23 Aug 2006 20:09:39 +0200
User-agent: KMail/1.9.1

The 'df' program needs a small adjustment so that the 'struct statvfs' of
BeOS can be used. And the 'stat' program needs porting too; here the
'struct statvfs' cannot be used, because it does not have a f_type
or f_fstypename or similar field.

Btw, the "#ifdef __GLIBC__" in m4/fsusage.m4 looks wrong also for the Hurd,
because glibc/sysdeps/mach/hurd/statfs64.c does not appear to access /proc.

After producing this patch, I noticed that the replacement 'statfs' that I
put into stat.c would also be useful for "df -i" (because the f_files, f_ffree
numbers in 'struct statvfs' are only dummies whereas those in 'struct fs_info'
are real ones).

So, more unification between lib/fsusage.c and src/stat.c seems desirable.
I propose to create a 'struct gnu_statvfs' that contains the usual POSIX
fields plus 'char f_fstypename[]', containing the filesystem name, and a few
minor fields that src/stat.c uses, and to transform the lib/fsusage.c code
into a gnu_statvfs function that could be used by both "df" and "stat".
Does this seem worthwhile? Can the SVR2 code (this is the only code in
lib/fsusage.c that makes use of the 'disk' argument) be dropped in the process?


2006-08-19  Bruno Haible  <address@hidden>

        * m4/fsusage.m4 (gl_FILE_SYSTEM_USAGE): Don't consider BeOS statvfs
        as unusable.
        * src/stat.c (USE_STATVFS) [BeOS]: Set to 0.
        (STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree, f_bavail, f_bsize,
        STATFS_FRSIZE, f_files, f_ffree, STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME)
        [BeOS]: Define.

--- m4/fsusage.m4.bak   2006-04-26 17:34:42.000000000 +0200
+++ m4/fsusage.m4       2006-08-19 17:00:54.000000000 +0200
@@ -1,4 +1,4 @@
-#serial 18
+#serial 19
 # Obtaining file system usage information.
 
 # Copyright (C) 1997, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software
@@ -50,10 +50,12 @@
   # SVR4
   AC_CACHE_CHECK([for statvfs function (SVR4)], fu_cv_sys_stat_statvfs,
                 [AC_TRY_LINK([#include <sys/types.h>
-#ifdef __GLIBC__
+#if defined __GLIBC__ && !defined __BEOS__
 Do not use statvfs on systems with GNU libc, because that function stats
 all preceding entries in /proc/mounts, and that makes df hang if even
 one of the corresponding file systems is hard-mounted, but not available.
+statvfs in GNU libc on BeOS operates differently: it only makes a system
+call.
 #endif
 #include <sys/statvfs.h>],
                              [struct statvfs fsd; statvfs (0, &fsd);],
--- src/stat.c.bak      2006-07-09 19:20:43.000000000 +0200
+++ src/stat.c  2006-08-19 20:23:04.000000000 +0200
@@ -20,7 +20,8 @@
 #include <config.h>
 
 #if (STAT_STATVFS \
-     && (HAVE_STRUCT_STATVFS_F_BASETYPE || ! HAVE_STRUCT_STATFS_F_FSTYPENAME))
+     && (HAVE_STRUCT_STATVFS_F_BASETYPE \
+        || (! HAVE_STRUCT_STATFS_F_FSTYPENAME && ! HAVE_OS_H)))
 # define USE_STATVFS 1
 #else
 # define USE_STATVFS 0
@@ -47,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"
@@ -79,6 +82,41 @@
 # 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
+   in the f_files, f_ffree, f_favail fields, and also does not have a
+   f_type/f_basetype/f_fstypename field.  So we use 'struct fs_info'
+   instead.  */
+#  undef STRUCT_STATVFS
+#  define STRUCT_STATVFS struct fs_info
+static int statfs (const char *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);
+}
+   /* The printf below expects f_fsid to be a 64-bit integer, but dev is only
+      32-bit.  So convert it to 'unsigned long long'.  */
+#  define f_fsid dev + (unsigned long long) 0
+#  define f_blocks total_blocks
+#  define f_bfree free_blocks
+#  define f_bavail free_blocks
+#  define f_bsize io_size
+#  undef STATFS_FRSIZE
+#  define STATFS_FRSIZE(S) ((S)->block_size)
+#  define f_files total_nodes
+#  define f_ffree free_nodes
+# endif
 #endif
 
 #ifdef SB_F_NAMEMAX
@@ -94,6 +132,8 @@
 #else
 # if 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
 




reply via email to

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