diff options
Diffstat (limited to 'drivers/unix/file_access_unix.cpp')
-rw-r--r-- | drivers/unix/file_access_unix.cpp | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index ca5a13799e..43ad0799ba 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -41,6 +41,11 @@ #include <sys/types.h> #include <unistd.h> +#if defined(TOOLS_ENABLED) +#include <limits.h> +#include <stdlib.h> +#endif + void FileAccessUnix::check_errors() const { ERR_FAIL_NULL_MSG(f, "File must be opened before use."); @@ -87,6 +92,22 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) { } } +#if defined(TOOLS_ENABLED) + if (p_mode_flags & READ) { + String real_path = get_real_path(); + if (real_path != path) { + // Don't warn on symlinks, since they can be used to simply share addons on multiple projects. + if (real_path.to_lower() == path.to_lower()) { + // The File system is case insensitive, but other platforms can be sensitive to it + // To ease cross-platform development, we issue a warning if users try to access + // a file using the wrong case (which *works* on Windows and macOS, but won't on other + // platforms). + WARN_PRINT(vformat("Case mismatch opening requested file '%s', stored as '%s' in the filesystem. This file will not open when exported to other case-sensitive platforms.", path, real_path)); + } + } + } +#endif + if (is_backup_save_enabled() && (p_mode_flags == WRITE)) { save_path = path; // Create a temporary file in the same directory as the target file. @@ -173,6 +194,26 @@ String FileAccessUnix::get_path_absolute() const { return path; } +#if defined(TOOLS_ENABLED) +String FileAccessUnix::get_real_path() const { + char *resolved_path = ::realpath(path.utf8().get_data(), nullptr); + + if (!resolved_path) { + return path; + } + + String result; + Error parse_ok = result.parse_utf8(resolved_path); + ::free(resolved_path); + + if (parse_ok != OK) { + return path; + } + + return result.simplify_path(); +} +#endif + void FileAccessUnix::seek(uint64_t p_position) { ERR_FAIL_NULL_MSG(f, "File must be opened before use."); @@ -218,22 +259,13 @@ bool FileAccessUnix::eof_reached() const { return last_error == ERR_FILE_EOF; } -uint8_t FileAccessUnix::get_8() const { - ERR_FAIL_NULL_V_MSG(f, 0, "File must be opened before use."); - uint8_t b; - if (fread(&b, 1, 1, f) == 0) { - check_errors(); - b = '\0'; - } - return b; -} - uint64_t FileAccessUnix::get_buffer(uint8_t *p_dst, uint64_t p_length) const { - ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_NULL_V_MSG(f, -1, "File must be opened before use."); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); uint64_t read = fread(p_dst, 1, p_length, f); check_errors(); + return read; } @@ -241,14 +273,26 @@ Error FileAccessUnix::get_error() const { return last_error; } -void FileAccessUnix::flush() { - ERR_FAIL_NULL_MSG(f, "File must be opened before use."); - fflush(f); +Error FileAccessUnix::resize(int64_t p_length) { + ERR_FAIL_NULL_V_MSG(f, FAILED, "File must be opened before use."); + int res = ::ftruncate(fileno(f), p_length); + switch (res) { + case 0: + return OK; + case EBADF: + return ERR_FILE_CANT_OPEN; + case EFBIG: + return ERR_OUT_OF_MEMORY; + case EINVAL: + return ERR_INVALID_PARAMETER; + default: + return FAILED; + } } -void FileAccessUnix::store_8(uint8_t p_dest) { +void FileAccessUnix::flush() { ERR_FAIL_NULL_MSG(f, "File must be opened before use."); - ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1); + fflush(f); } void FileAccessUnix::store_buffer(const uint8_t *p_src, uint64_t p_length) { @@ -291,7 +335,6 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) { if (!err) { return status.st_mtime; } else { - print_verbose("Failed to get modified time for: " + p_file + ""); return 0; } } @@ -320,7 +363,7 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, BitField<FileA } bool FileAccessUnix::_get_hidden_attribute(const String &p_file) { -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) String file = fix_path(p_file); struct stat st = {}; @@ -334,7 +377,7 @@ bool FileAccessUnix::_get_hidden_attribute(const String &p_file) { } Error FileAccessUnix::_set_hidden_attribute(const String &p_file, bool p_hidden) { -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) String file = fix_path(p_file); struct stat st = {}; |