]>
Commit | Line | Data |
---|---|---|
bead4a89 | 1 | /* |
bde978a6 | 2 | * Copyright (C) 1996-2015 The Squid Software Foundation and contributors |
bead4a89 AJ |
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 | ||
615540cd AJ |
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 */ | |
f53969cc | 85 |