Browse Source

Implement `get_filesystem_type` on macOS and Linux.

Pāvels Nadtočajevs 2 months ago
parent
commit
d609cf62a0

+ 2 - 0
core/io/dir_access.cpp

@@ -672,6 +672,8 @@ void DirAccess::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_include_hidden", "enable"), &DirAccess::set_include_hidden);
 	ClassDB::bind_method(D_METHOD("get_include_hidden"), &DirAccess::get_include_hidden);
 
+	ClassDB::bind_method(D_METHOD("get_filesystem_type"), &DirAccess::get_filesystem_type);
+
 	ClassDB::bind_method(D_METHOD("is_case_sensitive", "path"), &DirAccess::is_case_sensitive);
 	ClassDB::bind_method(D_METHOD("is_equivalent", "path_a", "path_b"), &DirAccess::is_equivalent);
 

+ 7 - 0
doc/classes/DirAccess.xml

@@ -213,6 +213,13 @@
 				[b]Note:[/b] When used on a [code]res://[/code] path in an exported project, only the files included in the PCK at the given folder level are returned. In practice, this means that since imported resources are stored in a top-level [code].godot/[/code] folder, only paths to [code].gd[/code] and [code].import[/code] files are returned (plus a few other files, such as [code]project.godot[/code] or [code]project.binary[/code] and the project icon). In an exported project, the list of returned files will also vary depending on [member ProjectSettings.editor/export/convert_text_resources_to_binary].
 			</description>
 		</method>
+		<method name="get_filesystem_type" qualifiers="const">
+			<return type="String" />
+			<description>
+				Returns file system type name of the current directory's disk. Returned values are uppercase strings like [code]NTFS[/code], [code]FAT32[/code], [code]EXFAT[/code], [code]APFS[/code], [code]EXT4[/code], [code]BTRFS[/code], and so on.
+				[b]Note:[/b] This method is implemented on macOS, Linux, Windows and for PCK virtual file system.
+			</description>
+		</method>
 		<method name="get_next">
 			<return type="String" />
 			<description>

+ 162 - 0
drivers/unix/dir_access_unix.cpp

@@ -40,6 +40,9 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#ifdef __linux__
+#include <sys/statfs.h>
+#endif
 #include <sys/statvfs.h>
 #include <cerrno>
 #include <cstdio>
@@ -516,7 +519,166 @@ uint64_t DirAccessUnix::get_space_left() {
 }
 
 String DirAccessUnix::get_filesystem_type() const {
+#ifdef __linux__
+	struct statfs fs;
+	if (statfs(current_dir.utf8().get_data(), &fs) != 0) {
+		return "";
+	}
+	switch (fs.f_type) {
+		case 0x0000adf5:
+			return "ADFS";
+		case 0x0000adff:
+			return "AFFS";
+		case 0x5346414f:
+			return "AFS";
+		case 0x00000187:
+			return "AUTOFS";
+		case 0x00c36400:
+			return "CEPH";
+		case 0x73757245:
+			return "CODA";
+		case 0x28cd3d45:
+			return "CRAMFS";
+		case 0x453dcd28:
+			return "CRAMFS";
+		case 0x64626720:
+			return "DEBUGFS";
+		case 0x73636673:
+			return "SECURITYFS";
+		case 0xf97cff8c:
+			return "SELINUX";
+		case 0x43415d53:
+			return "SMACK";
+		case 0x858458f6:
+			return "RAMFS";
+		case 0x01021994:
+			return "TMPFS";
+		case 0x958458f6:
+			return "HUGETLBFS";
+		case 0x73717368:
+			return "SQUASHFS";
+		case 0x0000f15f:
+			return "ECRYPTFS";
+		case 0x00414a53:
+			return "EFS";
+		case 0xe0f5e1e2:
+			return "EROFS";
+		case 0x0000ef53:
+			return "EXTFS";
+		case 0xabba1974:
+			return "XENFS";
+		case 0x9123683e:
+			return "BTRFS";
+		case 0x00003434:
+			return "NILFS";
+		case 0xf2f52010:
+			return "F2FS";
+		case 0xf995e849:
+			return "HPFS";
+		case 0x00009660:
+			return "ISOFS";
+		case 0x000072b6:
+			return "JFFS2";
+		case 0x58465342:
+			return "XFS";
+		case 0x6165676c:
+			return "PSTOREFS";
+		case 0xde5e81e4:
+			return "EFIVARFS";
+		case 0x00c0ffee:
+			return "HOSTFS";
+		case 0x794c7630:
+			return "OVERLAYFS";
+		case 0x65735546:
+			return "FUSE";
+		case 0xca451a4e:
+			return "BCACHEFS";
+		case 0x00004d44:
+			return "FAT32";
+		case 0x2011bab0:
+			return "EXFAT";
+		case 0x0000564c:
+			return "NCP";
+		case 0x00006969:
+			return "NFS";
+		case 0x7461636f:
+			return "OCFS2";
+		case 0x00009fa1:
+			return "OPENPROM";
+		case 0x0000002f:
+			return "QNX4";
+		case 0x68191122:
+			return "QNX6";
+		case 0x6b414653:
+			return "AFS";
+		case 0x52654973:
+			return "REISERFS";
+		case 0x0000517b:
+			return "SMB";
+		case 0xff534d42:
+			return "CIFS";
+		case 0x0027e0eb:
+			return "CGROUP";
+		case 0x63677270:
+			return "CGROUP2";
+		case 0x07655821:
+			return "RDTGROUP";
+		case 0x74726163:
+			return "TRACEFS";
+		case 0x01021997:
+			return "V9FS";
+		case 0x62646576:
+			return "BDEVFS";
+		case 0x64646178:
+			return "DAXFS";
+		case 0x42494e4d:
+			return "BINFMTFS";
+		case 0x00001cd1:
+			return "DEVPTS";
+		case 0x6c6f6f70:
+			return "BINDERFS";
+		case 0x0bad1dea:
+			return "FUTEXFS";
+		case 0x50495045:
+			return "PIPEFS";
+		case 0x00009fa0:
+			return "PROC";
+		case 0x534f434b:
+			return "SOCKFS";
+		case 0x62656572:
+			return "SYSFS";
+		case 0x00009fa2:
+			return "USBDEVICE";
+		case 0x11307854:
+			return "MTD_INODE";
+		case 0x09041934:
+			return "ANON_INODE";
+		case 0x73727279:
+			return "BTRFS";
+		case 0x6e736673:
+			return "NSFS";
+		case 0xcafe4a11:
+			return "BPF_FS";
+		case 0x5a3c69f0:
+			return "AAFS";
+		case 0x5a4f4653:
+			return "ZONEFS";
+		case 0x15013346:
+			return "UDF";
+		case 0x444d4142:
+			return "DMA_BUF";
+		case 0x454d444d:
+			return "DEVMEM";
+		case 0x5345434d:
+			return "SECRETMEM";
+		case 0x50494446:
+			return "PID_FS";
+		default:
+			return "";
+	}
+#else
 	return ""; //TODO this should be implemented
+#endif
 }
 
 bool DirAccessUnix::is_hidden(const String &p_name) {

+ 1 - 1
drivers/windows/dir_access_windows.cpp

@@ -362,7 +362,7 @@ String DirAccessWindows::get_filesystem_type() const {
 				&dwFileSystemFlags,
 				szFileSystemName,
 				sizeof(szFileSystemName)) == TRUE) {
-		return String::utf16((const char16_t *)szFileSystemName);
+		return String::utf16((const char16_t *)szFileSystemName).to_upper();
 	}
 
 	ERR_FAIL_V("");

+ 1 - 1
editor/editor_file_system.cpp

@@ -3660,7 +3660,7 @@ EditorFileSystem::EditorFileSystem() {
 
 	// This should probably also work on Unix and use the string it returns for FAT32 or exFAT
 	Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-	using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "exFAT");
+	using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "EXFAT");
 
 	scan_total = 0;
 	ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);

+ 2 - 0
platform/macos/dir_access_macos.h

@@ -52,6 +52,8 @@ protected:
 	virtual bool is_hidden(const String &p_name) override;
 	virtual bool is_case_sensitive(const String &p_path) const override;
 
+	virtual String get_filesystem_type() const override;
+
 	virtual bool is_bundle(const String &p_file) const override;
 };
 

+ 9 - 0
platform/macos/dir_access_macos.mm

@@ -34,11 +34,20 @@
 
 #include "core/config/project_settings.h"
 
+#include <sys/mount.h>
 #include <cerrno>
 
 #import <AppKit/NSWorkspace.h>
 #import <Foundation/Foundation.h>
 
+String DirAccessMacOS::get_filesystem_type() const {
+	struct statfs fs;
+	if (statfs(current_dir.utf8().get_data(), &fs) != 0) {
+		return "";
+	}
+	return String::utf8(fs.f_fstypename).to_upper();
+}
+
 String DirAccessMacOS::fix_unicode_name(const char *p_name) const {
 	String fname;
 	if (p_name != nullptr) {