Currently we use stafs to determine the information about the filesystem volume we are on.
#include <string>
#include <iostream>
#include <sys/mount.h>
#include <sys/param.h>
void statFileSys(const std::string f)
{
struct statfs fileStat;
if(statfs(f.data(),&fileStat) == 0)
{
std::cout << "File type: " << fileStat.f_type <<'\n';
std::cout << "File system name: "<<fileStat.f_fstypename << '\n';
}
else
{
std::cout << "statfs failed !!!"<<std::endl;
}
}
int main()
{
statFileSys("/some/network/path");
statFileSys("/tmp");
return 0;
}
We rely on
f_type
value to make decisions based on whether its HFS+ or APFS or network file system.
However, we are seeing following weird output on three different macOS systems for above small standalone reproducible code.
1]
macOS 10.12 + HFS+
File type: 25
File system name: autofs
File type: 23
File system name: hfs
2]
macOS 10.13 (beta) + HFS+
File type: 24
File system name: autofs
File type: 23
File system name: hfs
3]
macOS 10.13 (beta) + APFS
File type: 25
File system name: autofs
File type: 24
File system name: apfs
For 2]
we get the f_type
value for the network path (autofs) as 24 and while in 3]
we get f_type
as 24 for APFS whch doesnt seem consistent.
This brings us to the qustion, is statfs
the correct programmatic way to find the filesystem volume info on macOS ?
If its not, then what would be the right way to do the same ?
According to the documentation for vfs_filetype, which is returned by vfs_statfs(), Apple regards the filesystem type numbers as an archaic mechanism. While this is not definitive for statfs(), vfs_statfs() is better documented:
Filesystem type numbers are an old construct; most filesystems just get a number assigned based on the order in which they are registered with the system.
As filesystem type numbers are now assigned at runtime in recent versions of MacOS, you must use f_fstypename
to determine the type. You will note that in the signature for AppKit's getFileSystemInfoForPath
method that filesystem type is represented as a string there as well. It seems the most official you're going to get is Apple's own API.
#include <string>
#include <iostream>
#include <sys/mount.h>
#include <sys/param.h>
void statFileSys(const std::string f)
{
struct statfs fileStat;
if(statfs(f.data(),&fileStat) == 0)
{
if(!strcmp(fileStat.f_fstypename, "apfs") )
std::cout << "File system is APFS << std::endl;
else if(!strcmp(fileStat.f_fstypename, "hfs") )
std::cout << "File system is HFS+ << std::endl;
else if(!strcmp(fileStat.f_fstypename, "nfs") )
std::cout << "File system is NFS << std::endl;
else if(!strcmp(fileStat.f_fstypename, "cd9660") )
std::cout << "File system is CD-ROM << std::endl;
else
std::cout << "We weren't looking for a "
<< fileStat.f_fstypename << " were we?" << std::endl;
}
else
{
std::cout << "statfs failed !!!"<<std::endl;
}
}
int main()
{
statFileSys("/some/network/path");
statFileSys("/tmp");
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With