10 #ifdef HAVE_SYS_STATFS_H
11 #include <sys/statfs.h>
14 /* freebsd && netbsd */
15 #ifdef HAVE_SYS_PARAM_H
16 #include <sys/param.h>
18 #ifdef HAVE_SYS_MOUNT_H
19 #include <sys/mount.h>
22 /* TODO: benchmark which is faster, fstatvfs() or pre-opened fd and
23 * statvfs() (fstatvfs() would handle mounts I think...) */
25 static struct fs_stat fs_stats_[64];
26 struct fs_stat *fs_stats = fs_stats_;
28 void update_fs_stats()
32 for (i = 0; i < 16; i++) {
33 if (fs_stats[i].fd <= 0)
36 fstatfs(fs_stats[i].fd, &s);
38 fs_stats[i].size = (long long) s.f_blocks * s.f_bsize;
39 /* bfree (root) or bavail (non-roots) ? */
40 fs_stats[i].avail = (long long) s.f_bavail * s.f_bsize;
47 for (i = 0; i < 16; i++) {
49 close(fs_stats[i].fd);
53 if (fs_stats[i].path != NULL) {
54 free(fs_stats[i].path);
55 fs_stats[i].path = NULL;
60 struct fs_stat *prepare_fs_stat(const char *s)
64 for (i = 0; i < 16; i++) {
65 struct fs_stat *fs = &fs_stats[i];
67 if (fs->path && strcmp(fs->path, s) == 0)
71 /* when compiled with icc, it crashes when leaving function and open()
72 * is used, I don't know why */
74 /* this icc workaround didn't seem to work */
77 FILE *fp = fopen(s, "r");
85 fs->fd = open(s, O_RDONLY);
87 if (fs->fd <= 0) { /* 0 isn't error but actually it is :) */
88 ERR("open '%s': %s", s, strerror(errno));
98 ERR("too many fs stats");