master
c 87 lines 2.62 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "libnetdata/libnetdata.h"
4
5 #if defined(OS_LINUX)
6 #include <sys/statvfs.h>
7
8 OS_SYSTEM_DISK_SPACE os_disk_space(const char *path) {
9 OS_SYSTEM_DISK_SPACE space = OS_SYSTEM_DISK_SPACE_EMPTY;
10 struct statvfs buf;
11
12 if (statvfs(path, &buf) != 0) {
13 // Error occurred; errno is set
14 return space;
15 }
16
17 // Use f_frsize (fragment size) for accurate byte calculations.
18 space.total_bytes = buf.f_blocks * buf.f_frsize;
19 space.free_bytes = buf.f_bavail * buf.f_frsize;
20 space.total_inodes = buf.f_files;
21 space.free_inodes = buf.f_favail;
22 space.is_read_only = (buf.f_flag & ST_RDONLY) != 0;
23 return space;
24 }
25 #endif
26
27 #if defined(OS_FREEBSD) || defined(OS_MACOS)
28 #include <sys/param.h>
29 #include <sys/mount.h>
30
31 OS_SYSTEM_DISK_SPACE os_disk_space(const char *path) {
32 OS_SYSTEM_DISK_SPACE space = OS_SYSTEM_DISK_SPACE_EMPTY;
33 struct statfs buf;
34
35 if (statfs(path, &buf) != 0) {
36 // Error occurred; errno is set
37 return space;
38 }
39
40 space.total_bytes = buf.f_blocks * buf.f_bsize;
41 space.free_bytes = buf.f_bavail * buf.f_bsize;
42 space.total_inodes = buf.f_files;
43 space.free_inodes = buf.f_ffree;
44 space.is_read_only = (buf.f_flags & MNT_RDONLY) != 0;
45 return space;
46 }
47 #endif
48
49 #if defined(OS_WINDOWS)
50 #include <windows.h>
51
52 OS_SYSTEM_DISK_SPACE os_disk_space(const char *path_utf8) {
53 OS_SYSTEM_DISK_SPACE space = OS_SYSTEM_DISK_SPACE_EMPTY;
54
55 ssize_t wpath_size = cygwin_conv_path(CCP_POSIX_TO_WIN_W, path_utf8, NULL, 0);
56 if(wpath_size < 0)
57 return space;
58
59 wchar_t *wpath = mallocz(wpath_size);
60 if(cygwin_conv_path(CCP_POSIX_TO_WIN_W, path_utf8, wpath, wpath_size) != 0) {
61 freez(wpath);
62 return space;
63 }
64
65 // Use the wide-character version of GetDiskFreeSpaceEx.
66 ULARGE_INTEGER freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes;
67 if (!GetDiskFreeSpaceExW(wpath, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes)) {
68 // API call failed; optionally, GetLastError() can provide more details.
69 freez(wpath);
70 return space;
71 }
72
73 // Get the drive type and attributes
74 DWORD attributes = GetFileAttributesW(wpath);
75 if (attributes != INVALID_FILE_ATTRIBUTES) {
76 space.is_read_only = (attributes & FILE_ATTRIBUTE_READONLY) != 0;
77 }
78
79 freez(wpath);
80
81 space.total_bytes = totalNumberOfBytes.QuadPart;
82 space.free_bytes = totalNumberOfFreeBytes.QuadPart;
83 space.total_inodes = 0; // Windows does not have inodes
84 space.free_inodes = 0; // Windows does not have inodes
85 return space;
86 }
87 #endif