summaryrefslogtreecommitdiffstats
path: root/drivers/unix/file_access_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/unix/file_access_unix.cpp')
-rw-r--r--drivers/unix/file_access_unix.cpp81
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 = {};