])
+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
psignal.h \
shm.cc \
shm.h \
+ statvfs.h \
+ statvfs.cc \
stdio.h \
stdvarargs.h \
strnstr.cc \
/* 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 */
/*****************************************************/
}
#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)
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 */
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);
--- /dev/null
+#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 */
--- /dev/null
+#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 */
sys/shm.h \
sys/socket.h \
sys/stat.h \
- sys/statvfs.h \
syscall.h \
sys/syscall.h \
sys/time.h \
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 \
socketpair \
srand48 \
srandom \
- statfs \
sysconf \
syslog \
timegm \
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,
#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
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;
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;
}
*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;
}