From 3cf76f69bfe61041c10916947c95244365e9283a Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Thu, 7 Jun 2012 10:22:04 +0400 Subject: [PATCH] Ticket #2825: obtain FS name from stat info: sync with coreutils. src/filemanager/filegui.c does not compile on Solaris due to missing macros. AVE_STRUCT_STATVFS_F_BASETYPE and HAVE_STRUCT_STATVFS_F_FSTYPENAME macros are not set or even defined in config.h. configure scrips does not even check for those members. Signed-off-by: Andrew Borodin --- configure.ac | 2 +- m4.include/mc-get-fs-info.m4 | 77 ++++++++++++++++++++++++- src/filemanager/filegui.c | 131 +++++++++++++++++++++++++++++++------------ 3 files changed, 173 insertions(+), 37 deletions(-) diff --git a/configure.ac b/configure.ac index 4be6ac814..9fc6b7d74 100644 --- a/configure.ac +++ b/configure.ac @@ -208,7 +208,7 @@ AC_TYPE_UID_T AC_FUNC_STRCOLL -AC_MC_GET_FS_INFO +mc_AC_GET_FS_INFO dnl dnl X11 support. diff --git a/m4.include/mc-get-fs-info.m4 b/m4.include/mc-get-fs-info.m4 index b1474d806..6962c645f 100644 --- a/m4.include/mc-get-fs-info.m4 +++ b/m4.include/mc-get-fs-info.m4 @@ -21,12 +21,85 @@ AC_DEFUN([gl_POSIX_FALLOCATE], [ ]) dnl +dnl Get from the coreutils package (stat-prog.m4 serial 7) +dnl + +AC_DEFUN([mc_cu_PREREQ_STAT_PROG], +[ + 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 +" + statfs_includes="\ +AC_INCLUDES_DEFAULT +#if HAVE_SYS_VFS_H +# include +#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H +# include +# include +# if HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H +# include +# include +# include +# endif +#elif HAVE_OS_H +# include +#endif +" + dnl Keep this long conditional in sync with the USE_STATVFS conditional + dnl in src/filemanager/filegui.c. + if case "$fu_cv_sys_stat_statvfs$fu_cv_sys_stat_statvfs64" in + *yes*) ;; *) false;; esac && + { 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_namelen, struct statfs.f_type, + struct statfs.f_frsize],,, [$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 +]) + + +dnl dnl Filesystem information detection dnl dnl To get information about the disk, mount points, etc. dnl -AC_DEFUN([AC_MC_GET_FS_INFO], [ +AC_DEFUN([mc_AC_GET_FS_INFO], [ gl_MOUNTLIST if test $gl_cv_list_mounted_fs = yes; then gl_PREREQ_MOUNTLIST_EXTRA @@ -46,4 +119,6 @@ AC_DEFUN([AC_MC_GET_FS_INFO], [ gl_FSTYPENAME gl_POSIX_FALLOCATE + + mc_cu_PREREQ_STAT_PROG ]) diff --git a/src/filemanager/filegui.c b/src/filemanager/filegui.c index a7ad2d191..be9a2edec 100644 --- a/src/filemanager/filegui.c +++ b/src/filemanager/filegui.c @@ -11,7 +11,7 @@ in an interactive program. Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2009, 2011 + 2004, 2005, 2006, 2007, 2009, 2011, 2012 The Free Software Foundation, Inc. Written by: @@ -21,7 +21,8 @@ Jakub Jelinek, 1995, 1996 Norbert Warmuth, 1997 Pavel Machek, 1998 - Slava Zanko, 2009 + Slava Zanko, 2009-2012 + Andrew Borodin, 2009-2012 This file is part of the Midnight Commander. @@ -52,6 +53,15 @@ #include +/* Keep this conditional in sync with the similar conditional in m4.include/mc-get-fs-info. */ +#if ((STAT_STATVFS || STAT_STATVFS64) \ + && (HAVE_STRUCT_STATVFS_F_BASETYPE || HAVE_STRUCT_STATVFS_F_FSTYPENAME \ + || (! HAVE_STRUCT_STATFS_F_FSTYPENAME))) +# define USE_STATVFS 1 +#else +# define USE_STATVFS 0 +#endif + #include #include #include @@ -59,23 +69,73 @@ #include #include -#if defined(STAT_STATVFS) \ - && (defined(HAVE_STRUCT_STATVFS_F_BASETYPE) \ - || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)) -#include -#define STRUCT_STATFS struct statvfs -#define STATFS statvfs -#elif defined(HAVE_STATFS) && !defined(STAT_STATFS4) -#ifdef HAVE_SYS_VFS_H -#include -#elif defined(HAVE_SYS_MOUNT_H) && defined(HAVE_SYS_PARAM_H) -#include -#include -#elif defined(HAVE_SYS_STATFS_H) -#include +#if USE_STATVFS +# include +#elif HAVE_SYS_VFS_H +# include +#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H +/* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs. + It does have statvfs.h, but shouldn't use it, since it doesn't + HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */ +/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */ +# include +# include +# if HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H +/* Ultrix 4.4 needs these for the declaration of struct statfs. */ +# include +# include +# include +# endif +#elif HAVE_OS_H /* BeOS */ +# include +#endif + +#if USE_STATVFS +# define STRUCT_STATVFS struct statvfs +# if ! STAT_STATVFS && STAT_STATVFS64 +# define STATFS statvfs64 +# else +# define STATFS statvfs +# endif +#else +# define STATFS statfs +# 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 STRUCT_STATVFS struct fs_info +# else +# define STRUCT_STATVFS struct statfs +# endif #endif -#define STRUCT_STATFS struct statfs -#define STATFS statfs + +#if HAVE_STRUCT_STATVFS_F_BASETYPE +# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME 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 #include @@ -119,7 +179,7 @@ int classic_progressbar = 1; typedef enum { MSDOS_SUPER_MAGIC = 0x4d44, NTFS_SB_MAGIC = 0x5346544e, - FUSE_MAGIC = 0x65735546, + FUSE_MAGIC = 0x65735546, PROC_SUPER_MAGIC = 0x9fa0, SMB_SUPER_MAGIC = 0x517B, NCP_SUPER_MAGIC = 0x564c, @@ -179,13 +239,13 @@ typedef struct static gboolean filegui__check_attrs_on_fs (const char *fs_path) { -#ifdef STATFS - STRUCT_STATFS stfs; +#ifdef USE_STATVFS + STRUCT_STATVFS stfs; if (!setup_copymove_persistent_attr) return FALSE; - if (STATFS (fs_path, &stfs) != 0) + if (statfs (fs_path, &stfs) != 0) return TRUE; #ifdef __linux__ @@ -203,20 +263,22 @@ filegui__check_attrs_on_fs (const char *fs_path) } #elif defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) \ || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) - if (!strcmp (stfs.f_fstypename, "msdos") - || !strcmp (stfs.f_fstypename, "msdosfs") - || !strcmp (stfs.f_fstypename, "ntfs") - || !strcmp (stfs.f_fstypename, "procfs") - || !strcmp (stfs.f_fstypename, "smbfs") || strstr (stfs.f_fstypename, "fusefs")) + if (strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "msdos") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "msdosfs") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "ntfs") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "procfs") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "smbfs") == 0 + || strstr (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "fusefs") != NULL) return FALSE; #elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) - if (!strcmp (stfs.f_basetype, "pcfs") - || !strcmp (stfs.f_basetype, "ntfs") - || !strcmp (stfs.f_basetype, "proc") - || !strcmp (stfs.f_basetype, "smbfs") || !strcmp (stfs.f_basetype, "fuse")) + if (strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "pcfs") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "ntfs") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "proc") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "smbfs") == 0 + || strcmp (stfs.STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME, "fuse") == 0) return FALSE; #endif -#endif /* STATFS */ +#endif /* USE_STATVFS */ return TRUE; } @@ -545,7 +607,7 @@ file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta, buttons_width = abort_button_width + skip_button_width + 2; dlg_width = max (58, buttons_width + 6); - dlg_height = 17; /* to make compiler happy :) */ + dlg_height = 17; /* to make compiler happy :) */ ui = g_new0 (FileOpContextUI, 1); ctx->ui = ui; @@ -591,8 +653,7 @@ file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_eta, add_widget (ui->op_dlg, ui->progress_total_gauge = gauge_new (7 + dy, 3 + 3, 0, 100, 0)); - add_widget (ui->op_dlg, ui->total_files_processed_label = - label_new (9 + dy, 3, "")); + add_widget (ui->op_dlg, ui->total_files_processed_label = label_new (9 + dy, 3, "")); add_widget (ui->op_dlg, ui->time_label = label_new (10 + dy, 3, "")); -- 2.11.4.GIT