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