void INTERNAL_STATVFS (const char *name, struct STATVFS *buf, struct STATFS *fsbuf, struct stat64 *st) { /* Now fill in the fields we have information for. */ buf->f_bsize = fsbuf->f_bsize; /* Linux has the f_frsize size only in later version of the kernel. If the value is not filled in use f_bsize. */ buf->f_frsize = fsbuf->f_frsize ?: fsbuf->f_bsize; buf->f_blocks = fsbuf->f_blocks; buf->f_bfree = fsbuf->f_bfree; buf->f_bavail = fsbuf->f_bavail; buf->f_files = fsbuf->f_files; buf->f_ffree = fsbuf->f_ffree; if (sizeof (buf->f_fsid) == sizeof (fsbuf->f_fsid)) /* The shifting uses 'unsigned long long int' even though the target field might only have 32 bits. This is OK since the 'if' branch is not used in this case but the compiler would still generate warnings. */ buf->f_fsid = ((fsbuf->f_fsid.__val[0] & ((1ULL << (8 * sizeof (fsbuf->f_fsid.__val[0]))) - 1)) | ((unsigned long long int) fsbuf->f_fsid.__val[1] << (8 * (sizeof (buf->f_fsid) - sizeof (fsbuf->f_fsid.__val[0]))))); else /* We cannot help here. The statvfs element is not large enough to contain both words of the statfs f_fsid field. */ buf->f_fsid = fsbuf->f_fsid.__val[0]; #ifdef _STATVFSBUF_F_UNUSED buf->__f_unused = 0; #endif buf->f_namemax = fsbuf->f_namelen; memset (buf->__f_spare, '\0', sizeof (buf->__f_spare)); /* What remains to do is to fill the fields f_favail and f_flag. */ /* XXX I have no idea how to compute f_favail. Any idea??? */ buf->f_favail = buf->f_ffree; #ifndef __ASSUME_STATFS_F_FLAGS if ((fsbuf->f_flags & ST_VALID) == 0) /* Determining the flags is tricky. We have to read /proc/mounts or the /etc/mtab file and search for the entry which matches the given file. The way we can test for matching filesystem is using the device number. */ buf->f_flag = __statvfs_getflags (name, fsbuf->f_type, st); else #endif buf->f_flag = fsbuf->f_flags ^ ST_VALID; }
void INTERNAL_STATVFS (const char *name, struct STATVFS *buf, struct STATFS *fsbuf, struct stat64 *st) { /* Now fill in the fields we have information for. */ buf->f_bsize = fsbuf->f_bsize; /* Linux has the f_frsize size only in later version of the kernel. If the value is not filled in use f_bsize. */ buf->f_frsize = fsbuf->f_frsize ?: fsbuf->f_bsize; buf->f_blocks = fsbuf->f_blocks; buf->f_bfree = fsbuf->f_bfree; buf->f_bavail = fsbuf->f_bavail; buf->f_files = fsbuf->f_files; buf->f_ffree = fsbuf->f_ffree; if (sizeof (buf->f_fsid) == sizeof (fsbuf->f_fsid)) buf->f_fsid = (fsbuf->f_fsid.__val[0] | ((unsigned long int) fsbuf->f_fsid.__val[1] << (8 * (sizeof (buf->f_fsid) - sizeof (fsbuf->f_fsid.__val[0]))))); else /* We cannot help here. The statvfs element is not large enough to contain both words of the statfs f_fsid field. */ buf->f_fsid = fsbuf->f_fsid.__val[0]; #ifdef _STATVFSBUF_F_UNUSED buf->__f_unused = 0; #endif buf->f_namemax = fsbuf->f_namelen; memset (buf->__f_spare, '\0', sizeof (buf->__f_spare)); /* What remains to do is to fill the fields f_favail and f_flag. */ /* XXX I have no idea how to compute f_favail. Any idea??? */ buf->f_favail = buf->f_ffree; /* Determining the flags is tricky. We have to read /proc/mounts or the /etc/mtab file and search for the entry which matches the given file. The way we can test for matching filesystem is using the device number. */ buf->f_flag = __statvfs_getflags (name, fsbuf->f_type, st); }