Merge pull request #80404 from bruvzg/file_attribs

[FileAccess] Add methods to get/set "hidden" and "read-only" attributes on macOS/BSD and Windows.
This commit is contained in:
Rémi Verschelde 2023-08-09 15:20:32 +02:00
commit d255811443
No known key found for this signature in database
GPG Key ID: C3336907360768E1
16 changed files with 438 additions and 37 deletions

View File

@ -583,7 +583,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
return mt;
}
uint32_t FileAccess::get_unix_permissions(const String &p_file) {
BitField<FileAccess::UnixPermissionFlags> FileAccess::get_unix_permissions(const String &p_file) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return 0;
}
@ -591,11 +591,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) {
Ref<FileAccess> fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'.");
uint32_t mt = fa->_get_unix_permissions(p_file);
return mt;
return fa->_get_unix_permissions(p_file);
}
Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
Error FileAccess::set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return ERR_UNAVAILABLE;
}
@ -607,6 +606,52 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi
return err;
}
bool FileAccess::get_hidden_attribute(const String &p_file) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return false;
}
Ref<FileAccess> fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'.");
return fa->_get_hidden_attribute(p_file);
}
Error FileAccess::set_hidden_attribute(const String &p_file, bool p_hidden) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return ERR_UNAVAILABLE;
}
Ref<FileAccess> fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
Error err = fa->_set_hidden_attribute(p_file, p_hidden);
return err;
}
bool FileAccess::get_read_only_attribute(const String &p_file) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return false;
}
Ref<FileAccess> fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'.");
return fa->_get_read_only_attribute(p_file);
}
Error FileAccess::set_read_only_attribute(const String &p_file, bool p_ro) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return ERR_UNAVAILABLE;
}
Ref<FileAccess> fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
Error err = fa->_set_read_only_attribute(p_file, p_ro);
return err;
}
void FileAccess::store_string(const String &p_string) {
if (p_string.length() == 0) {
return;
@ -865,6 +910,14 @@ void FileAccess::_bind_methods() {
ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists);
ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time);
ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions);
ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions);
ClassDB::bind_static_method("FileAccess", D_METHOD("get_hidden_attribute", "file"), &FileAccess::get_hidden_attribute);
ClassDB::bind_static_method("FileAccess", D_METHOD("set_hidden_attribute", "file", "hidden"), &FileAccess::set_hidden_attribute);
ClassDB::bind_static_method("FileAccess", D_METHOD("set_read_only_attribute", "file", "ro"), &FileAccess::set_read_only_attribute);
ClassDB::bind_static_method("FileAccess", D_METHOD("get_read_only_attribute", "file"), &FileAccess::get_read_only_attribute);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian");
BIND_ENUM_CONSTANT(READ);
@ -877,4 +930,17 @@ void FileAccess::_bind_methods() {
BIND_ENUM_CONSTANT(COMPRESSION_ZSTD);
BIND_ENUM_CONSTANT(COMPRESSION_GZIP);
BIND_ENUM_CONSTANT(COMPRESSION_BROTLI);
BIND_BITFIELD_FLAG(UNIX_READ_OWNER);
BIND_BITFIELD_FLAG(UNIX_WRITE_OWNER);
BIND_BITFIELD_FLAG(UNIX_EXECUTE_OWNER);
BIND_BITFIELD_FLAG(UNIX_READ_GROUP);
BIND_BITFIELD_FLAG(UNIX_WRITE_GROUP);
BIND_BITFIELD_FLAG(UNIX_EXECUTE_GROUP);
BIND_BITFIELD_FLAG(UNIX_READ_OTHER);
BIND_BITFIELD_FLAG(UNIX_WRITE_OTHER);
BIND_BITFIELD_FLAG(UNIX_EXECUTE_OTHER);
BIND_BITFIELD_FLAG(UNIX_SET_USER_ID);
BIND_BITFIELD_FLAG(UNIX_SET_GROUP_ID);
BIND_BITFIELD_FLAG(UNIX_RESTRICTED_DELETE);
}

View File

@ -60,6 +60,21 @@ public:
WRITE_READ = 7,
};
enum UnixPermissionFlags {
UNIX_EXECUTE_OTHER = 0x001,
UNIX_WRITE_OTHER = 0x002,
UNIX_READ_OTHER = 0x004,
UNIX_EXECUTE_GROUP = 0x008,
UNIX_WRITE_GROUP = 0x010,
UNIX_READ_GROUP = 0x020,
UNIX_EXECUTE_OWNER = 0x040,
UNIX_WRITE_OWNER = 0x080,
UNIX_READ_OWNER = 0x100,
UNIX_RESTRICTED_DELETE = 0x200,
UNIX_SET_GROUP_ID = 0x400,
UNIX_SET_USER_ID = 0x800,
};
enum CompressionMode {
COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
@ -74,8 +89,13 @@ public:
bool big_endian = false;
bool real_is_double = false;
virtual uint32_t _get_unix_permissions(const String &p_file) = 0;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0;
virtual BitField<UnixPermissionFlags> _get_unix_permissions(const String &p_file) = 0;
virtual Error _set_unix_permissions(const String &p_file, BitField<UnixPermissionFlags> p_permissions) = 0;
virtual bool _get_hidden_attribute(const String &p_file) = 0;
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) = 0;
virtual bool _get_read_only_attribute(const String &p_file) = 0;
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) = 0;
protected:
static void _bind_methods();
@ -185,8 +205,13 @@ public:
static CreateFunc get_create_func(AccessType p_access);
static bool exists(const String &p_name); ///< return true if a file exists
static uint64_t get_modified_time(const String &p_file);
static uint32_t get_unix_permissions(const String &p_file);
static Error set_unix_permissions(const String &p_file, uint32_t p_permissions);
static BitField<FileAccess::UnixPermissionFlags> get_unix_permissions(const String &p_file);
static Error set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions);
static bool get_hidden_attribute(const String &p_file);
static Error set_hidden_attribute(const String &p_file, bool p_hidden);
static bool get_read_only_attribute(const String &p_file);
static Error set_read_only_attribute(const String &p_file, bool p_ro);
static void set_backup_save(bool p_enable) { backup_save = p_enable; };
static bool is_backup_save_enabled() { return backup_save; };
@ -212,5 +237,6 @@ public:
VARIANT_ENUM_CAST(FileAccess::CompressionMode);
VARIANT_ENUM_CAST(FileAccess::ModeFlags);
VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags);
#endif // FILE_ACCESS_H

View File

@ -365,20 +365,48 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
}
}
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
BitField<FileAccess::UnixPermissionFlags> FileAccessCompressed::_get_unix_permissions(const String &p_file) {
if (f.is_valid()) {
return f->_get_unix_permissions(p_file);
}
return 0;
}
Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
Error FileAccessCompressed::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
if (f.is_valid()) {
return f->_set_unix_permissions(p_file, p_permissions);
}
return FAILED;
}
bool FileAccessCompressed::_get_hidden_attribute(const String &p_file) {
if (f.is_valid()) {
return f->_get_hidden_attribute(p_file);
}
return false;
}
Error FileAccessCompressed::_set_hidden_attribute(const String &p_file, bool p_hidden) {
if (f.is_valid()) {
return f->_set_hidden_attribute(p_file, p_hidden);
}
return FAILED;
}
bool FileAccessCompressed::_get_read_only_attribute(const String &p_file) {
if (f.is_valid()) {
return f->_get_read_only_attribute(p_file);
}
return false;
}
Error FileAccessCompressed::_set_read_only_attribute(const String &p_file, bool p_ro) {
if (f.is_valid()) {
return f->_set_read_only_attribute(p_file, p_ro);
}
return FAILED;
}
void FileAccessCompressed::close() {
_close();
}

View File

@ -94,8 +94,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override;
virtual uint32_t _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
virtual bool _get_hidden_attribute(const String &p_file) override;
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
virtual bool _get_read_only_attribute(const String &p_file) override;
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;

View File

@ -285,13 +285,46 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
BitField<FileAccess::UnixPermissionFlags> FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
if (file.is_valid()) {
return file->_get_unix_permissions(p_file);
}
return 0;
}
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet.");
return ERR_UNAVAILABLE;
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
if (file.is_valid()) {
return file->_set_unix_permissions(p_file, p_permissions);
}
return FAILED;
}
bool FileAccessEncrypted::_get_hidden_attribute(const String &p_file) {
if (file.is_valid()) {
return file->_get_hidden_attribute(p_file);
}
return false;
}
Error FileAccessEncrypted::_set_hidden_attribute(const String &p_file, bool p_hidden) {
if (file.is_valid()) {
return file->_set_hidden_attribute(p_file, p_hidden);
}
return FAILED;
}
bool FileAccessEncrypted::_get_read_only_attribute(const String &p_file) {
if (file.is_valid()) {
return file->_get_read_only_attribute(p_file);
}
return false;
}
Error FileAccessEncrypted::_set_read_only_attribute(const String &p_file, bool p_ro) {
if (file.is_valid()) {
return file->_set_read_only_attribute(p_file, p_ro);
}
return FAILED;
}
void FileAccessEncrypted::close() {

View File

@ -85,8 +85,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override;
virtual uint32_t _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
virtual bool _get_hidden_attribute(const String &p_file) override;
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
virtual bool _get_read_only_attribute(const String &p_file) override;
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;

View File

@ -68,8 +68,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override {}

View File

@ -150,8 +150,13 @@ class FileAccessPack : public FileAccess {
Ref<FileAccess> f;
virtual Error open_internal(const String &p_path, int p_mode_flags) override;
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
public:
virtual bool is_open() const override;

View File

@ -106,8 +106,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override;

View File

@ -170,6 +170,14 @@
Returns the next 32 bits from the file as a floating-point number.
</description>
</method>
<method name="get_hidden_attribute" qualifiers="static">
<return type="bool" />
<param index="0" name="file" type="String" />
<description>
Returns [code]true[/code], if file [code]hidden[/code] attribute is set.
[b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
</description>
</method>
<method name="get_length" qualifiers="const">
<return type="int" />
<description>
@ -228,6 +236,14 @@
Returns the file cursor's position.
</description>
</method>
<method name="get_read_only_attribute" qualifiers="static">
<return type="bool" />
<param index="0" name="file" type="String" />
<description>
Returns [code]true[/code], if file [code]read only[/code] attribute is set.
[b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
</description>
</method>
<method name="get_real" qualifiers="const">
<return type="float" />
<description>
@ -241,6 +257,14 @@
Returns a SHA-256 [String] representing the file at the given path or an empty [String] on failure.
</description>
</method>
<method name="get_unix_permissions" qualifiers="static">
<return type="int" enum="FileAccess.UnixPermissionFlags" is_bitfield="true" />
<param index="0" name="file" type="String" />
<description>
Returns file UNIX permissions.
[b]Note:[/b] This method is implemented on iOS, Linux/BSD, and macOS.
</description>
</method>
<method name="get_var" qualifiers="const">
<return type="Variant" />
<param index="0" name="allow_objects" type="bool" default="false" />
@ -312,6 +336,33 @@
[b]Note:[/b] This is an offset, so you should use negative numbers or the cursor will be at the end of the file.
</description>
</method>
<method name="set_hidden_attribute" qualifiers="static">
<return type="int" enum="Error" />
<param index="0" name="file" type="String" />
<param index="1" name="hidden" type="bool" />
<description>
Sets file [code]hidden[/code] attribute.
[b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
</description>
</method>
<method name="set_read_only_attribute" qualifiers="static">
<return type="int" enum="Error" />
<param index="0" name="file" type="String" />
<param index="1" name="ro" type="bool" />
<description>
Sets file [code]read only[/code] attribute.
[b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
</description>
</method>
<method name="set_unix_permissions" qualifiers="static">
<return type="int" enum="Error" />
<param index="0" name="file" type="String" />
<param index="1" name="permissions" type="int" enum="FileAccess.UnixPermissionFlags" is_bitfield="true" />
<description>
Sets file UNIX permissions.
[b]Note:[/b] This method is implemented on iOS, Linux/BSD, and macOS.
</description>
</method>
<method name="store_8">
<return type="void" />
<param index="0" name="value" type="int" />
@ -485,5 +536,41 @@
<constant name="COMPRESSION_BROTLI" value="4" enum="CompressionMode">
Uses the [url=https://github.com/google/brotli]brotli[/url] compression method (only decompression is supported).
</constant>
<constant name="UNIX_READ_OWNER" value="256" enum="UnixPermissionFlags" is_bitfield="true">
Read for owner bit.
</constant>
<constant name="UNIX_WRITE_OWNER" value="128" enum="UnixPermissionFlags" is_bitfield="true">
Write for owner bit.
</constant>
<constant name="UNIX_EXECUTE_OWNER" value="64" enum="UnixPermissionFlags" is_bitfield="true">
Execute for owner bit.
</constant>
<constant name="UNIX_READ_GROUP" value="32" enum="UnixPermissionFlags" is_bitfield="true">
Read for group bit.
</constant>
<constant name="UNIX_WRITE_GROUP" value="16" enum="UnixPermissionFlags" is_bitfield="true">
Write for group bit.
</constant>
<constant name="UNIX_EXECUTE_GROUP" value="8" enum="UnixPermissionFlags" is_bitfield="true">
Execute for group bit.
</constant>
<constant name="UNIX_READ_OTHER" value="4" enum="UnixPermissionFlags" is_bitfield="true">
Read for other bit.
</constant>
<constant name="UNIX_WRITE_OTHER" value="2" enum="UnixPermissionFlags" is_bitfield="true">
Write for other bit.
</constant>
<constant name="UNIX_EXECUTE_OTHER" value="1" enum="UnixPermissionFlags" is_bitfield="true">
Execute for other bit.
</constant>
<constant name="UNIX_SET_USER_ID" value="2048" enum="UnixPermissionFlags" is_bitfield="true">
Set user id on execution bit.
</constant>
<constant name="UNIX_SET_GROUP_ID" value="1024" enum="UnixPermissionFlags" is_bitfield="true">
Set group id on execution bit.
</constant>
<constant name="UNIX_RESTRICTED_DELETE" value="512" enum="UnixPermissionFlags" is_bitfield="true">
Restricted deletion (sticky) bit.
</constant>
</constants>
</class>

View File

@ -313,19 +313,19 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
}
}
uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) {
BitField<FileAccess::UnixPermissionFlags> FileAccessUnix::_get_unix_permissions(const String &p_file) {
String file = fix_path(p_file);
struct stat status = {};
int err = stat(file.utf8().get_data(), &status);
if (!err) {
return status.st_mode & 0x7FF; //only permissions
return status.st_mode & 0xFFF; //only permissions
} else {
ERR_FAIL_V_MSG(0, "Failed to get unix permissions for: " + p_file + ".");
}
}
Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
Error FileAccessUnix::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
String file = fix_path(p_file);
int err = chmod(file.utf8().get_data(), p_permissions);
@ -336,6 +336,74 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per
return FAILED;
}
bool FileAccessUnix::_get_hidden_attribute(const String &p_file) {
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
String file = fix_path(p_file);
struct stat st = {};
int err = stat(file.utf8().get_data(), &st);
ERR_FAIL_COND_V_MSG(err, false, "Failed to get attributes for: " + p_file);
return (st.st_flags & UF_HIDDEN);
#else
return false;
#endif
}
Error FileAccessUnix::_set_hidden_attribute(const String &p_file, bool p_hidden) {
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
String file = fix_path(p_file);
struct stat st = {};
int err = stat(file.utf8().get_data(), &st);
ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to get attributes for: " + p_file);
if (p_hidden) {
err = chflags(file.utf8().get_data(), st.st_flags | UF_HIDDEN);
} else {
err = chflags(file.utf8().get_data(), st.st_flags & ~UF_HIDDEN);
}
ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to set attributes for: " + p_file);
return OK;
#else
return ERR_UNAVAILABLE;
#endif
}
bool FileAccessUnix::_get_read_only_attribute(const String &p_file) {
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
String file = fix_path(p_file);
struct stat st = {};
int err = stat(file.utf8().get_data(), &st);
ERR_FAIL_COND_V_MSG(err, false, "Failed to get attributes for: " + p_file);
return st.st_flags & UF_IMMUTABLE;
#else
return false;
#endif
}
Error FileAccessUnix::_set_read_only_attribute(const String &p_file, bool p_ro) {
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
String file = fix_path(p_file);
struct stat st = {};
int err = stat(file.utf8().get_data(), &st);
ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to get attributes for: " + p_file);
if (p_ro) {
err = chflags(file.utf8().get_data(), st.st_flags | UF_IMMUTABLE);
} else {
err = chflags(file.utf8().get_data(), st.st_flags & ~UF_IMMUTABLE);
}
ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to set attributes for: " + p_file);
return OK;
#else
return ERR_UNAVAILABLE;
#endif
}
void FileAccessUnix::close() {
_close();
}

View File

@ -79,8 +79,13 @@ public:
virtual bool file_exists(const String &p_path) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override;
virtual uint32_t _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
virtual bool _get_hidden_attribute(const String &p_file) override;
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
virtual bool _get_read_only_attribute(const String &p_file) override;
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;

View File

@ -381,14 +381,62 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
}
}
uint32_t FileAccessWindows::_get_unix_permissions(const String &p_file) {
BitField<FileAccess::UnixPermissionFlags> FileAccessWindows::_get_unix_permissions(const String &p_file) {
return 0;
}
Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
Error FileAccessWindows::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
return ERR_UNAVAILABLE;
}
bool FileAccessWindows::_get_hidden_attribute(const String &p_file) {
String file = fix_path(p_file);
DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, false, "Failed to get attributes for: " + p_file);
return (attrib & FILE_ATTRIBUTE_HIDDEN);
}
Error FileAccessWindows::_set_hidden_attribute(const String &p_file, bool p_hidden) {
String file = fix_path(p_file);
DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, FAILED, "Failed to get attributes for: " + p_file);
BOOL ok;
if (p_hidden) {
ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib | FILE_ATTRIBUTE_HIDDEN);
} else {
ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib & ~FILE_ATTRIBUTE_HIDDEN);
}
ERR_FAIL_COND_V_MSG(!ok, FAILED, "Failed to set attributes for: " + p_file);
return OK;
}
bool FileAccessWindows::_get_read_only_attribute(const String &p_file) {
String file = fix_path(p_file);
DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, false, "Failed to get attributes for: " + p_file);
return (attrib & FILE_ATTRIBUTE_READONLY);
}
Error FileAccessWindows::_set_read_only_attribute(const String &p_file, bool p_ro) {
String file = fix_path(p_file);
DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, FAILED, "Failed to get attributes for: " + p_file);
BOOL ok;
if (p_ro) {
ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib | FILE_ATTRIBUTE_READONLY);
} else {
ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib & ~FILE_ATTRIBUTE_READONLY);
}
ERR_FAIL_COND_V_MSG(!ok, FAILED, "Failed to set attributes for: " + p_file);
return OK;
}
void FileAccessWindows::close() {
_close();
}

View File

@ -80,8 +80,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
uint64_t _get_modified_time(const String &p_file) override;
virtual uint32_t _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
virtual bool _get_hidden_attribute(const String &p_file) override;
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
virtual bool _get_read_only_attribute(const String &p_file) override;
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;

View File

@ -76,8 +76,13 @@ public:
virtual bool file_exists(const String &p_path) override; // return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override;

View File

@ -91,8 +91,13 @@ public:
static void setup(jobject p_file_access_handler);
virtual uint64_t _get_modified_time(const String &p_file) override;
virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override;