1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
/*
* Copyright (C) 1996-2025 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
* Please see the COPYING and CONTRIBUTORS files for details.
*/
#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_MINGW_ || _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, nullptr, 0, &vsn, &maxlen, &flags, nullptr, 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 */
|