File: statvfs.cc

package info (click to toggle)
squid 7.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,440 kB
  • sloc: cpp: 184,513; ansic: 12,442; sh: 5,688; makefile: 5,247; perl: 2,560; sql: 326; python: 240; awk: 141; sed: 1
file content (85 lines) | stat: -rw-r--r-- 2,802 bytes parent folder | download
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 */