]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Portability: provide xstatvfs() shim for system call statvfs()
authorAmos Jeffries <squid3@treenet.co.nz>
Thu, 2 Oct 2014 12:07:26 +0000 (05:07 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 2 Oct 2014 12:07:26 +0000 (05:07 -0700)
statfs() and struct statfs have been deprecated for years. Hoewver the
POSIX statvfs replacements are still not universally available.

Remove deprecated statfs() and struct statfs usage from Squid. Although
they may still be used by the xstatvfs() compatibility wrapper if they
are the only available API.

acinclude/os-deps.m4
compat/Makefile.am
compat/compat.h
compat/mswindows.cc
compat/os/mswindows.h
compat/statvfs.cc [new file with mode: 0644]
compat/statvfs.h [new file with mode: 0644]
configure.ac
src/store_dir.cc

index 14e5a583b33780c4f35fb7227c4a21cc44e5e3fb..0e13eaf5f0f0553c466d706e5822f01c30248831 100644 (file)
@@ -619,6 +619,27 @@ SQUID_DEFINE_BOOL(HAVE_STATVFS,$ac_cv_func_statvfs,[set to 1 if our system has s
 ])
 
 
+dnl Check whether this OS defines f_frsize as a member of struct statfs
+AC_DEFUN([SQUID_CHECK_F_FRSIZE_IN_STATFS],[
+AC_CACHE_CHECK([for f_frsize field in struct statfs],
+                ac_cv_have_f_frsize_in_struct_statfs, [
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if HAVE_SYS_STATFS_H
+#include <sts/statfs.h>
+#endif
+#if HAVE_SYS_STATVFS_H
+#include <sts/statvfs.h>
+#endif
+#if HAVE_SYS_VFS_H
+#include <sts/vfs.h>
+#endif
+                ]], [[ struct statfs s; s.f_frsize = 0; ]])],[ ac_cv_have_f_frsize_in_struct_statfs="yes" ],[ ac_cv_have_f_frsize_in_struct_statfs="no" 
+        ])
+])
+SQUID_DEFINE_BOOL(HAVE_F_FRSIZE_IN_STATFS,$ac_cv_have_f_frsize_in_struct_statfs,[Define if struct statfs has field f_frsize (Linux 2.6 or later)])
+])
+
+
 dnl check that we can use the libresolv _dns_ttl_ hack
 dnl sets the ac_cv_libresolv_dns_ttl_hack shell variable and defines LIBRESOLV_DNS_TTL_HACK
 
index bde70b54d8ecf4f700c409f8593618f3f5f47003..80669a21eb46e2a15af6e3107f937932916977d4 100644 (file)
@@ -44,6 +44,8 @@ libcompat_squid_la_SOURCES = \
        psignal.h \
        shm.cc \
        shm.h \
+       statvfs.h \
+       statvfs.cc \
        stdio.h \
        stdvarargs.h \
        strnstr.cc \
index 8b689dd93e21a34ad1013118aa24f380bbc44539..e0218e86ffd5488022d53d2f177d604aee99c682 100644 (file)
@@ -92,6 +92,9 @@
 /* cstdio has a bunch of problems with 64-bit definitions */
 #include "compat/stdio.h"
 
+/* POSIX statvfs() is still not universal */
+#include "compat/statvfs.h"
+
 /*****************************************************/
 /* component-specific portabilities                  */
 /*****************************************************/
index 2db599f85353c5ad211ba5a8bda54a50ca002199..c348e5cbf299d6c332102ef03e22e6d4a18c9228 100644 (file)
@@ -125,42 +125,6 @@ gettimeofday(struct timeval *pcur_time, void *tzp)
 }
 #endif /* !HAVE_GETTIMEOFDAY */
 
-#if !_SQUID_MINGW_
-int
-statfs(const char *path, struct statfs *sfs)
-{
-    char drive[4];
-    DWORD spc, bps, freec, totalc;
-    DWORD vsn, maxlen, flags;
-
-    if (!sfs) {
-        errno = EINVAL;
-        return -1;
-    }
-    strncpy(drive, path, 2);
-    drive[2] = '\0';
-    strcat(drive, "\\");
-
-    if (!GetDiskFreeSpace(drive, &spc, &bps, &freec, &totalc)) {
-        errno = ENOENT;
-        return -1;
-    }
-    if (!GetVolumeInformation(drive, NULL, 0, &vsn, &maxlen, &flags, NULL, 0)) {
-        errno = ENOENT;
-        return -1;
-    }
-    sfs->f_type = flags;
-    sfs->f_bsize = spc * bps;
-    sfs->f_blocks = totalc;
-    sfs->f_bfree = sfs->f_bavail = freec;
-    sfs->f_files = -1;
-    sfs->f_ffree = -1;
-    sfs->f_fsid = vsn;
-    sfs->f_namelen = maxlen;
-    return 0;
-}
-#endif
-
 #if !_SQUID_MINGW_
 int
 WIN32_ftruncate(int fd, off_t size)
index ff06137af2f8b431b89893ebc0af6575bd7db62d..dfe053b1c30217938ac743b59a62a53987dd4b11 100644 (file)
@@ -245,21 +245,6 @@ struct group {
     char    **gr_mem;      /* group members */
 };
 
-#if !_SQUID_MINGW_
-struct statfs {
-    long    f_type;     /* type of filesystem (see below) */
-    long    f_bsize;    /* optimal transfer block size */
-    long    f_blocks;   /* total data blocks in file system */
-    long    f_bfree;    /* free blocks in fs */
-    long    f_bavail;   /* free blocks avail to non-superuser */
-    long    f_files;    /* total file nodes in file system */
-    long    f_ffree;    /* free file nodes in fs */
-    long    f_fsid;     /* file system id */
-    long    f_namelen;  /* maximum length of filenames */
-    long    f_spare[6]; /* spare for later */
-};
-#endif
-
 #if !HAVE_GETTIMEOFDAY
 struct timezone {
     int        tz_minuteswest; /* minutes west of Greenwich */
@@ -865,9 +850,6 @@ struct rusage {
 
 SQUIDCEXTERN int chroot(const char *dirname);
 SQUIDCEXTERN int kill(pid_t, int);
-#if !_SQUID_MINGW_
-SQUIDCEXTERN int statfs(const char *, struct statfs *);
-#endif
 SQUIDCEXTERN struct passwd * getpwnam(char *unused);
 SQUIDCEXTERN struct group * getgrnam(char *unused);
 
diff --git a/compat/statvfs.cc b/compat/statvfs.cc
new file mode 100644 (file)
index 0000000..8f83f20
--- /dev/null
@@ -0,0 +1,76 @@
+#include "squid.h"
+#include "compat/statvfs.h"
+
+#if !HAVE_STATVFS
+
+// struct statfs has some member differences between OS versions
+#if HAVE_F_FRSIZE_IN_STATFS
+#define STATFS_FRSIZE(x) (x).f_frsize
+#else
+#define STATFS_FRSIZE(x) (x).f_bsize
+#endif
+
+int
+xstatvfs(const char *path, struct statvfs *sfs)
+{
+#if !HAVE_STATFS && _SQUID_WINDOWS_
+    char drive[4];
+    DWORD spc, bps, freec, totalc;
+    DWORD vsn, maxlen, flags;
+
+    if (!sfs) {
+        errno = EINVAL;
+        return -1;
+    }
+    strncpy(drive, path, 2);
+    drive[2] = '\0';
+    strcat(drive, "\\");
+
+    if (!GetDiskFreeSpace(drive, &spc, &bps, &freec, &totalc)) {
+        errno = ENOENT;
+        return -1;
+    }
+    if (!GetVolumeInformation(drive, NULL, 0, &vsn, &maxlen, &flags, NULL, 0)) {
+        errno = ENOENT;
+        return -1;
+    }
+
+    memset(sfs, 0, sizeof(*sfs));
+
+    sfs->f_bsize = sfs->f_frsize = spc * bps;         /* file system block size, fragment size */
+    sfs->f_blocks = totalc;                           /* size of fs in f_frsize units */
+    sfs->f_bfree = sfs->f_bavail = freec;             /* # free blocks total, and available for unprivileged users */
+    sfs->f_files = sfs->f_ffree = sfs->f_favail = -1; /* # inodes total, free, and available for unprivileged users */
+    sfs->f_fsid = vsn;                                /* file system ID */
+    sfs->f_namemax = maxlen;                          /* maximum filename length */
+    return 0;
+
+#elif HAVE_STATFS
+    // use statfs() and map results from struct statfs to struct statvfs
+    struct statfs tmpSfs;
+
+    if (int x = statfs(path, &tmpSfs))
+        return x;
+
+    memset(sfs, 0, sizeof(*sfs));
+
+    sfs->f_bsize = tmpSfs.f_bsize;         /* file system block size */
+    sfs->f_frsize = STATFS_FRSIZE(tmpSfs); /* fragment size */
+    sfs->f_blocks = tmpSfs.f_blocks;       /* size of fs in f_frsize units */
+    sfs->f_bfree = tmpSfs.f_bfree;         /* # free blocks */
+    sfs->f_bavail = tmpSfs.f_bavail;       /* # free blocks for unprivileged users */
+    sfs->f_files = tmpSfs.f_files;         /* # inodes */
+    sfs->f_ffree = tmpSfs.f_ffree;         /* # free inodes */
+    sfs->f_favail = tmpSfs.f_ffree;        /* # free inodes for unprivileged users */
+    sfs->f_fsid = tmpSfs.f_fsid;           /* file system ID */
+    sfs->f_namemax = tmpSfs.f_namelen;     /* maximum filename length */
+
+#else
+#error Both statvfs() and statfs() system calls are missing.
+    errno = ENOSYS;
+    return -1;
+
+#endif
+}
+
+#endif /* HAVE_STATVFS */
diff --git a/compat/statvfs.h b/compat/statvfs.h
new file mode 100644 (file)
index 0000000..3b292ad
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _SQUID_COMPAT_XSTATVFS_H
+#define _SQUID_COMPAT_XSTATVFS_H
+
+#if HAVE_SYS_STATVFS_H && HAVE_STATVFS
+#include <sys/statvfs.h>
+#endif
+
+/* Windows and Linux use sys/vfs.h */
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+
+/* BSD and old Linux use sys/statfs.h */
+#if !HAVE_STATVFS
+#if HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+/* statfs() needs <sys/param.h> and <sys/mount.h> on BSD systems */
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#endif /* !HAVE_STATVFS */
+
+
+#if HAVE_STATVFS
+#define xstatvfs statvfs
+
+#else
+
+typedef unsigned long fsblkcnt_t;
+typedef unsigned long fsfilcnt_t;
+
+struct statvfs {
+    unsigned long  f_bsize;    /* file system block size */
+    unsigned long  f_frsize;   /* fragment size */
+    fsblkcnt_t     f_blocks;   /* size of fs in f_frsize units */
+    fsblkcnt_t     f_bfree;    /* # free blocks */
+    fsblkcnt_t     f_bavail;   /* # free blocks for unprivileged users */
+    fsfilcnt_t     f_files;    /* # inodes */
+    fsfilcnt_t     f_ffree;    /* # free inodes */
+    fsfilcnt_t     f_favail;   /* # free inodes for unprivileged users */
+    unsigned long  f_fsid;     /* file system ID */
+    unsigned long  f_flag;     /* mount flags */
+    unsigned long  f_namemax;  /* maximum filename length */
+};
+
+#if defined(__cplusplus)
+extern "C"
+#endif
+int xstatvfs(const char *path, struct statvfs *buf);
+
+#endif
+
+#endif /* _SQUID_COMPAT_XSTATVFS_H */
index 0256b9286fcd4235b2f9cd651e5fdfac2e6612fd..e4e85c420a243eac531cf5541b73409f0ad75776 100644 (file)
@@ -2804,7 +2804,6 @@ AC_CHECK_HEADERS( \
   sys/shm.h \
   sys/socket.h \
   sys/stat.h \
-  sys/statvfs.h \
   syscall.h \
   sys/syscall.h \
   sys/time.h \
@@ -3300,11 +3299,6 @@ if test "x$ac_cv_func_poll" = "x" ; then
   esac
 fi
 
-dnl Override statfs() detect on MinGW because it is emulated in source code
-if test "x$squid_host_os" = "xmingw" ; then
-  ac_cv_func_statfs='yes'
-fi
-
 dnl Check for library functions
 AC_CHECK_FUNCS(\
        backtrace_symbols_fd \
@@ -3361,7 +3355,6 @@ AC_CHECK_FUNCS(\
        socketpair \
        srand48 \
        srandom \
-       statfs \
        sysconf \
        syslog \
        timegm \
@@ -3666,10 +3659,15 @@ SQUID_CHECK_MAXPATHLEN
 SQUID_CHECK_LIBRESOLV_DNS_TTL_HACK
 SQUID_CHECK_RESOLVER_FIELDS
 
+AC_CHECK_HEADERS(sys/statvfs.h)
 if test "x$ac_cv_header_sys_statvfs_h" = "xyes" ; then
   SQUID_CHECK_WORKING_STATVFS
 fi
-
+if test "x$ac_cv_func_statvfs" != "xyes" ; then
+  AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/vfs.h sys/statfs.h)
+  AC_CHECK_FUNCS(statfs)
+  SQUID_CHECK_F_FRSIZE_IN_STATFS
+fi
 
 dnl Squid will not usually attempt to translate templates when building
 AC_ARG_ENABLE(translation,
index 812466665ccf40a37792da60b3418318806ef4bc..c79954102e8b267d3cac0b84fb98848b2599b233 100644 (file)
 
 #include <cerrno>
 #include <climits>
-#if HAVE_STATVFS
-#if HAVE_SYS_STATVFS_H
-#include <sys/statvfs.h>
-#endif
-#endif /* HAVE_STATVFS */
-/* statfs() needs <sys/param.h> and <sys/mount.h> on BSD systems */
-#if HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#if HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
-/* Windows and Linux use sys/vfs.h */
-#if HAVE_SYS_VFS_H
-#include <sys/vfs.h>
-#endif
 #if HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
@@ -556,33 +540,17 @@ StoreController::callback()
 int
 storeDirGetBlkSize(const char *path, int *blksize)
 {
-#if HAVE_STATVFS
-
     struct statvfs sfs;
 
-    if (statvfs(path, &sfs)) {
+    if (xstatvfs(path, &sfs)) {
         debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
         *blksize = 2048;
         return 1;
     }
 
     *blksize = (int) sfs.f_frsize;
-#else
-
-    struct statfs sfs;
-
-    if (statfs(path, &sfs)) {
-        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
-        *blksize = 2048;
-        return 1;
-    }
-
-    *blksize = (int) sfs.f_bsize;
-#endif
-    /*
-     * Sanity check; make sure we have a meaningful value.
-     */
 
+    // Sanity check; make sure we have a meaningful value.
     if (*blksize < 512)
         *blksize = 2048;
 
@@ -595,11 +563,9 @@ storeDirGetBlkSize(const char *path, int *blksize)
 int
 storeDirGetUFSStats(const char *path, int *totl_kb, int *free_kb, int *totl_in, int *free_in)
 {
-#if HAVE_STATVFS
-
     struct statvfs sfs;
 
-    if (statvfs(path, &sfs)) {
+    if (xstatvfs(path, &sfs)) {
         debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
         return 1;
     }
@@ -608,21 +574,6 @@ storeDirGetUFSStats(const char *path, int *totl_kb, int *free_kb, int *totl_in,
     *free_kb = (int) fsbtoblk(sfs.f_bfree, sfs.f_frsize, 1024);
     *totl_in = (int) sfs.f_files;
     *free_in = (int) sfs.f_ffree;
-#else
-
-    struct statfs sfs;
-
-    if (statfs(path, &sfs)) {
-        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
-        return 1;
-    }
-
-    *totl_kb = (int) fsbtoblk(sfs.f_blocks, sfs.f_bsize, 1024);
-    *free_kb = (int) fsbtoblk(sfs.f_bfree, sfs.f_bsize, 1024);
-    *totl_in = (int) sfs.f_files;
-    *free_in = (int) sfs.f_ffree;
-#endif
-
     return 0;
 }