From d609cf62a036572143e3ae65b6460d51b4fbae9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Wed, 14 May 2025 11:35:25 +0300 Subject: [PATCH] Implement `get_filesystem_type` on macOS and Linux. --- core/io/dir_access.cpp | 2 + doc/classes/DirAccess.xml | 7 ++ drivers/unix/dir_access_unix.cpp | 162 +++++++++++++++++++++++++ drivers/windows/dir_access_windows.cpp | 2 +- editor/editor_file_system.cpp | 2 +- platform/macos/dir_access_macos.h | 2 + platform/macos/dir_access_macos.mm | 9 ++ 7 files changed, 184 insertions(+), 2 deletions(-) diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index 8e29af7d541..0b9a1e3a457 100644 --- a/core/io/dir_access.cpp +++ b/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); diff --git a/doc/classes/DirAccess.xml b/doc/classes/DirAccess.xml index beb57aef2c3..1afc7960d88 100644 --- a/doc/classes/DirAccess.xml +++ b/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]. + + + + 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. + + diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index b8a7e062cc7..30ca040c644 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -40,6 +40,9 @@ #include #include #include +#ifdef __linux__ +#include +#endif #include #include #include @@ -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) { diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 8a93f902337..b1946594384 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/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(""); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 5f48d34f6c5..0fe8ad67cf2 100644 --- a/editor/editor_file_system.cpp +++ b/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 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); diff --git a/platform/macos/dir_access_macos.h b/platform/macos/dir_access_macos.h index de82f366ce2..d69aa0fd903 100644 --- a/platform/macos/dir_access_macos.h +++ b/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; }; diff --git a/platform/macos/dir_access_macos.mm b/platform/macos/dir_access_macos.mm index 39d3f5c154e..b9aa4d9c66d 100644 --- a/platform/macos/dir_access_macos.mm +++ b/platform/macos/dir_access_macos.mm @@ -34,11 +34,20 @@ #include "core/config/project_settings.h" +#include #include #import #import +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) {