improve [f]stat[v]fs functions, and possibly work around old kernels
[musl] / src / stat / statvfs.c
1 #include <sys/statvfs.h>
2 #include <sys/statfs.h>
3 #include "syscall.h"
4 #include "libc.h"
5
6 int __statfs(const char *path, struct statfs *buf)
7 {
8         *buf = (struct statfs){0};
9 #ifdef SYS_statfs64
10         return syscall(SYS_statfs64, path, sizeof *buf, buf);
11 #else
12         return syscall(SYS_statfs, path, buf);
13 #endif
14 }
15
16 int __fstatfs(int fd, struct statfs *buf)
17 {
18         *buf = (struct statfs){0};
19 #ifdef SYS_fstatfs64
20         return syscall(SYS_fstatfs64, fd, sizeof *buf, buf);
21 #else
22         return syscall(SYS_fstatfs, fd, buf);
23 #endif
24 }
25
26 weak_alias(__statfs, statfs);
27 weak_alias(__fstatfs, fstatfs);
28
29 static void fixup(struct statvfs *out, const struct statfs *in)
30 {
31         *out = (struct statvfs){0};
32         out->f_bsize = in->f_bsize;
33         out->f_frsize = in->f_frsize ? in->f_frsize : in->f_bsize;
34         out->f_blocks = in->f_blocks;
35         out->f_bfree = in->f_bfree;
36         out->f_bavail = in->f_bavail;
37         out->f_files = in->f_files;
38         out->f_ffree = in->f_ffree;
39         out->f_favail = in->f_ffree;
40         out->f_fsid = in->f_fsid.__val[0];
41         out->f_flag = in->f_flags;
42         out->f_namemax = in->f_namelen;
43 }
44
45 int statvfs(const char *restrict path, struct statvfs *restrict buf)
46 {
47         struct statfs kbuf;
48         if (__statfs(path, &kbuf)<0) return -1;
49         fixup(buf, &kbuf);
50         return 0;
51 }
52
53 int fstatvfs(int fd, struct statvfs *buf)
54 {
55         struct statfs kbuf;
56         if (__fstatfs(fd, &kbuf)<0) return -1;
57         fixup(buf, &kbuf);
58         return 0;
59 }
60
61 LFS64(statvfs);
62 LFS64(statfs);
63 LFS64(fstatvfs);
64 LFS64(fstatfs);