Skip to content

Commit d255811

Browse files
committed
Merge pull request #80404 from bruvzg/file_attribs
[FileAccess] Add methods to get/set "hidden" and "read-only" attributes on macOS/BSD and Windows.
2 parents 08e5dea + 8aa6f29 commit d255811

16 files changed

+438
-37
lines changed

core/io/file_access.cpp

+70-4
Original file line numberDiff line numberDiff line change
@@ -583,19 +583,18 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
583583
return mt;
584584
}
585585

586-
uint32_t FileAccess::get_unix_permissions(const String &p_file) {
586+
BitField<FileAccess::UnixPermissionFlags> FileAccess::get_unix_permissions(const String &p_file) {
587587
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
588588
return 0;
589589
}
590590

591591
Ref<FileAccess> fa = create_for_path(p_file);
592592
ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'.");
593593

594-
uint32_t mt = fa->_get_unix_permissions(p_file);
595-
return mt;
594+
return fa->_get_unix_permissions(p_file);
596595
}
597596

598-
Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
597+
Error FileAccess::set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
599598
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
600599
return ERR_UNAVAILABLE;
601600
}
@@ -607,6 +606,52 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi
607606
return err;
608607
}
609608

609+
bool FileAccess::get_hidden_attribute(const String &p_file) {
610+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
611+
return false;
612+
}
613+
614+
Ref<FileAccess> fa = create_for_path(p_file);
615+
ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'.");
616+
617+
return fa->_get_hidden_attribute(p_file);
618+
}
619+
620+
Error FileAccess::set_hidden_attribute(const String &p_file, bool p_hidden) {
621+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
622+
return ERR_UNAVAILABLE;
623+
}
624+
625+
Ref<FileAccess> fa = create_for_path(p_file);
626+
ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
627+
628+
Error err = fa->_set_hidden_attribute(p_file, p_hidden);
629+
return err;
630+
}
631+
632+
bool FileAccess::get_read_only_attribute(const String &p_file) {
633+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
634+
return false;
635+
}
636+
637+
Ref<FileAccess> fa = create_for_path(p_file);
638+
ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'.");
639+
640+
return fa->_get_read_only_attribute(p_file);
641+
}
642+
643+
Error FileAccess::set_read_only_attribute(const String &p_file, bool p_ro) {
644+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
645+
return ERR_UNAVAILABLE;
646+
}
647+
648+
Ref<FileAccess> fa = create_for_path(p_file);
649+
ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
650+
651+
Error err = fa->_set_read_only_attribute(p_file, p_ro);
652+
return err;
653+
}
654+
610655
void FileAccess::store_string(const String &p_string) {
611656
if (p_string.length() == 0) {
612657
return;
@@ -865,6 +910,14 @@ void FileAccess::_bind_methods() {
865910
ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists);
866911
ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time);
867912

913+
ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions);
914+
ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions);
915+
916+
ClassDB::bind_static_method("FileAccess", D_METHOD("get_hidden_attribute", "file"), &FileAccess::get_hidden_attribute);
917+
ClassDB::bind_static_method("FileAccess", D_METHOD("set_hidden_attribute", "file", "hidden"), &FileAccess::set_hidden_attribute);
918+
ClassDB::bind_static_method("FileAccess", D_METHOD("set_read_only_attribute", "file", "ro"), &FileAccess::set_read_only_attribute);
919+
ClassDB::bind_static_method("FileAccess", D_METHOD("get_read_only_attribute", "file"), &FileAccess::get_read_only_attribute);
920+
868921
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian");
869922

870923
BIND_ENUM_CONSTANT(READ);
@@ -877,4 +930,17 @@ void FileAccess::_bind_methods() {
877930
BIND_ENUM_CONSTANT(COMPRESSION_ZSTD);
878931
BIND_ENUM_CONSTANT(COMPRESSION_GZIP);
879932
BIND_ENUM_CONSTANT(COMPRESSION_BROTLI);
933+
934+
BIND_BITFIELD_FLAG(UNIX_READ_OWNER);
935+
BIND_BITFIELD_FLAG(UNIX_WRITE_OWNER);
936+
BIND_BITFIELD_FLAG(UNIX_EXECUTE_OWNER);
937+
BIND_BITFIELD_FLAG(UNIX_READ_GROUP);
938+
BIND_BITFIELD_FLAG(UNIX_WRITE_GROUP);
939+
BIND_BITFIELD_FLAG(UNIX_EXECUTE_GROUP);
940+
BIND_BITFIELD_FLAG(UNIX_READ_OTHER);
941+
BIND_BITFIELD_FLAG(UNIX_WRITE_OTHER);
942+
BIND_BITFIELD_FLAG(UNIX_EXECUTE_OTHER);
943+
BIND_BITFIELD_FLAG(UNIX_SET_USER_ID);
944+
BIND_BITFIELD_FLAG(UNIX_SET_GROUP_ID);
945+
BIND_BITFIELD_FLAG(UNIX_RESTRICTED_DELETE);
880946
}

core/io/file_access.h

+30-4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ class FileAccess : public RefCounted {
6060
WRITE_READ = 7,
6161
};
6262

63+
enum UnixPermissionFlags {
64+
UNIX_EXECUTE_OTHER = 0x001,
65+
UNIX_WRITE_OTHER = 0x002,
66+
UNIX_READ_OTHER = 0x004,
67+
UNIX_EXECUTE_GROUP = 0x008,
68+
UNIX_WRITE_GROUP = 0x010,
69+
UNIX_READ_GROUP = 0x020,
70+
UNIX_EXECUTE_OWNER = 0x040,
71+
UNIX_WRITE_OWNER = 0x080,
72+
UNIX_READ_OWNER = 0x100,
73+
UNIX_RESTRICTED_DELETE = 0x200,
74+
UNIX_SET_GROUP_ID = 0x400,
75+
UNIX_SET_USER_ID = 0x800,
76+
};
77+
6378
enum CompressionMode {
6479
COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
6580
COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
@@ -74,8 +89,13 @@ class FileAccess : public RefCounted {
7489
bool big_endian = false;
7590
bool real_is_double = false;
7691

77-
virtual uint32_t _get_unix_permissions(const String &p_file) = 0;
78-
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0;
92+
virtual BitField<UnixPermissionFlags> _get_unix_permissions(const String &p_file) = 0;
93+
virtual Error _set_unix_permissions(const String &p_file, BitField<UnixPermissionFlags> p_permissions) = 0;
94+
95+
virtual bool _get_hidden_attribute(const String &p_file) = 0;
96+
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) = 0;
97+
virtual bool _get_read_only_attribute(const String &p_file) = 0;
98+
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) = 0;
7999

80100
protected:
81101
static void _bind_methods();
@@ -185,8 +205,13 @@ class FileAccess : public RefCounted {
185205
static CreateFunc get_create_func(AccessType p_access);
186206
static bool exists(const String &p_name); ///< return true if a file exists
187207
static uint64_t get_modified_time(const String &p_file);
188-
static uint32_t get_unix_permissions(const String &p_file);
189-
static Error set_unix_permissions(const String &p_file, uint32_t p_permissions);
208+
static BitField<FileAccess::UnixPermissionFlags> get_unix_permissions(const String &p_file);
209+
static Error set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions);
210+
211+
static bool get_hidden_attribute(const String &p_file);
212+
static Error set_hidden_attribute(const String &p_file, bool p_hidden);
213+
static bool get_read_only_attribute(const String &p_file);
214+
static Error set_read_only_attribute(const String &p_file, bool p_ro);
190215

191216
static void set_backup_save(bool p_enable) { backup_save = p_enable; };
192217
static bool is_backup_save_enabled() { return backup_save; };
@@ -212,5 +237,6 @@ class FileAccess : public RefCounted {
212237

213238
VARIANT_ENUM_CAST(FileAccess::CompressionMode);
214239
VARIANT_ENUM_CAST(FileAccess::ModeFlags);
240+
VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags);
215241

216242
#endif // FILE_ACCESS_H

core/io/file_access_compressed.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -365,20 +365,48 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
365365
}
366366
}
367367

368-
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
368+
BitField<FileAccess::UnixPermissionFlags> FileAccessCompressed::_get_unix_permissions(const String &p_file) {
369369
if (f.is_valid()) {
370370
return f->_get_unix_permissions(p_file);
371371
}
372372
return 0;
373373
}
374374

375-
Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
375+
Error FileAccessCompressed::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
376376
if (f.is_valid()) {
377377
return f->_set_unix_permissions(p_file, p_permissions);
378378
}
379379
return FAILED;
380380
}
381381

382+
bool FileAccessCompressed::_get_hidden_attribute(const String &p_file) {
383+
if (f.is_valid()) {
384+
return f->_get_hidden_attribute(p_file);
385+
}
386+
return false;
387+
}
388+
389+
Error FileAccessCompressed::_set_hidden_attribute(const String &p_file, bool p_hidden) {
390+
if (f.is_valid()) {
391+
return f->_set_hidden_attribute(p_file, p_hidden);
392+
}
393+
return FAILED;
394+
}
395+
396+
bool FileAccessCompressed::_get_read_only_attribute(const String &p_file) {
397+
if (f.is_valid()) {
398+
return f->_get_read_only_attribute(p_file);
399+
}
400+
return false;
401+
}
402+
403+
Error FileAccessCompressed::_set_read_only_attribute(const String &p_file, bool p_ro) {
404+
if (f.is_valid()) {
405+
return f->_set_read_only_attribute(p_file, p_ro);
406+
}
407+
return FAILED;
408+
}
409+
382410
void FileAccessCompressed::close() {
383411
_close();
384412
}

core/io/file_access_compressed.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,13 @@ class FileAccessCompressed : public FileAccess {
9494
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
9595

9696
virtual uint64_t _get_modified_time(const String &p_file) override;
97-
virtual uint32_t _get_unix_permissions(const String &p_file) override;
98-
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
97+
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
98+
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
99+
100+
virtual bool _get_hidden_attribute(const String &p_file) override;
101+
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
102+
virtual bool _get_read_only_attribute(const String &p_file) override;
103+
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
99104

100105
virtual void close() override;
101106

core/io/file_access_encrypted.cpp

+37-4
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,46 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
285285
return 0;
286286
}
287287

288-
uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
288+
BitField<FileAccess::UnixPermissionFlags> FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
289+
if (file.is_valid()) {
290+
return file->_get_unix_permissions(p_file);
291+
}
289292
return 0;
290293
}
291294

292-
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
293-
ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet.");
294-
return ERR_UNAVAILABLE;
295+
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
296+
if (file.is_valid()) {
297+
return file->_set_unix_permissions(p_file, p_permissions);
298+
}
299+
return FAILED;
300+
}
301+
302+
bool FileAccessEncrypted::_get_hidden_attribute(const String &p_file) {
303+
if (file.is_valid()) {
304+
return file->_get_hidden_attribute(p_file);
305+
}
306+
return false;
307+
}
308+
309+
Error FileAccessEncrypted::_set_hidden_attribute(const String &p_file, bool p_hidden) {
310+
if (file.is_valid()) {
311+
return file->_set_hidden_attribute(p_file, p_hidden);
312+
}
313+
return FAILED;
314+
}
315+
316+
bool FileAccessEncrypted::_get_read_only_attribute(const String &p_file) {
317+
if (file.is_valid()) {
318+
return file->_get_read_only_attribute(p_file);
319+
}
320+
return false;
321+
}
322+
323+
Error FileAccessEncrypted::_set_read_only_attribute(const String &p_file, bool p_ro) {
324+
if (file.is_valid()) {
325+
return file->_set_read_only_attribute(p_file, p_ro);
326+
}
327+
return FAILED;
295328
}
296329

297330
void FileAccessEncrypted::close() {

core/io/file_access_encrypted.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,13 @@ class FileAccessEncrypted : public FileAccess {
8585
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
8686

8787
virtual uint64_t _get_modified_time(const String &p_file) override;
88-
virtual uint32_t _get_unix_permissions(const String &p_file) override;
89-
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
88+
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
89+
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
90+
91+
virtual bool _get_hidden_attribute(const String &p_file) override;
92+
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
93+
virtual bool _get_read_only_attribute(const String &p_file) override;
94+
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
9095

9196
virtual void close() override;
9297

core/io/file_access_memory.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,13 @@ class FileAccessMemory : public FileAccess {
6868
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
6969

7070
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
71-
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
72-
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
71+
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
72+
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
73+
74+
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
75+
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
76+
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
77+
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
7378

7479
virtual void close() override {}
7580

core/io/file_access_pack.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,13 @@ class FileAccessPack : public FileAccess {
150150
Ref<FileAccess> f;
151151
virtual Error open_internal(const String &p_path, int p_mode_flags) override;
152152
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
153-
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
154-
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
153+
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
154+
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
155+
156+
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
157+
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
158+
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
159+
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
155160

156161
public:
157162
virtual bool is_open() const override;

core/io/file_access_zip.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,13 @@ class FileAccessZip : public FileAccess {
106106
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
107107

108108
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo
109-
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
110-
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
109+
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
110+
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
111+
112+
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
113+
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
114+
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
115+
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
111116

112117
virtual void close() override;
113118

0 commit comments

Comments
 (0)