]> git.ipfire.org Git - thirdparty/squid.git/blob - compat/statvfs.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / compat / statvfs.cc
1 /*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "compat/statvfs.h"
11
12 #if !HAVE_STATVFS
13
14 // struct statfs has some member differences between OS versions
15 #if HAVE_F_FRSIZE_IN_STATFS
16 #define STATFS_FRSIZE(x) (x).f_frsize
17 #else
18 #define STATFS_FRSIZE(x) (x).f_bsize
19 #endif
20
21 int
22 xstatvfs(const char *path, struct statvfs *sfs)
23 {
24 #if !HAVE_STATFS && _SQUID_WINDOWS_
25 char drive[4];
26 DWORD spc, bps, freec, totalc;
27 DWORD vsn, maxlen, flags;
28
29 if (!sfs) {
30 errno = EINVAL;
31 return -1;
32 }
33 strncpy(drive, path, 2);
34 drive[2] = '\0';
35 strcat(drive, "\\");
36
37 if (!GetDiskFreeSpace(drive, &spc, &bps, &freec, &totalc)) {
38 errno = ENOENT;
39 return -1;
40 }
41 if (!GetVolumeInformation(drive, NULL, 0, &vsn, &maxlen, &flags, NULL, 0)) {
42 errno = ENOENT;
43 return -1;
44 }
45
46 memset(sfs, 0, sizeof(*sfs));
47
48 sfs->f_bsize = sfs->f_frsize = spc * bps; /* file system block size, fragment size */
49 sfs->f_blocks = totalc; /* size of fs in f_frsize units */
50 sfs->f_bfree = sfs->f_bavail = freec; /* # free blocks total, and available for unprivileged users */
51 sfs->f_files = sfs->f_ffree = sfs->f_favail = -1; /* # inodes total, free, and available for unprivileged users */
52 sfs->f_fsid = vsn; /* file system ID */
53 sfs->f_namemax = maxlen; /* maximum filename length */
54 return 0;
55
56 #elif HAVE_STATFS
57 // use statfs() and map results from struct statfs to struct statvfs
58 struct statfs tmpSfs;
59
60 if (int x = statfs(path, &tmpSfs))
61 return x;
62
63 memset(sfs, 0, sizeof(*sfs));
64
65 sfs->f_bsize = tmpSfs.f_bsize; /* file system block size */
66 sfs->f_frsize = STATFS_FRSIZE(tmpSfs); /* fragment size */
67 sfs->f_blocks = tmpSfs.f_blocks; /* size of fs in f_frsize units */
68 sfs->f_bfree = tmpSfs.f_bfree; /* # free blocks */
69 sfs->f_bavail = tmpSfs.f_bavail; /* # free blocks for unprivileged users */
70 sfs->f_files = tmpSfs.f_files; /* # inodes */
71 sfs->f_ffree = tmpSfs.f_ffree; /* # free inodes */
72 sfs->f_favail = tmpSfs.f_ffree; /* # free inodes for unprivileged users */
73 sfs->f_fsid = tmpSfs.f_fsid; /* file system ID */
74 sfs->f_namemax = tmpSfs.f_namelen; /* maximum filename length */
75
76 #else
77 #error Both statvfs() and statfs() system calls are missing.
78 errno = ENOSYS;
79 return -1;
80
81 #endif
82 }
83
84 #endif /* HAVE_STATVFS */
85