summaryrefslogtreecommitdiffstats
path: root/drivers/unix
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/unix')
-rw-r--r--drivers/unix/dir_access_unix.cpp23
-rw-r--r--drivers/unix/dir_access_unix.h2
-rw-r--r--drivers/unix/os_unix.cpp27
3 files changed, 50 insertions, 2 deletions
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 095991e27b..46efb45934 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -38,9 +38,11 @@
#include "core/templates/list.h"
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/ioctl.h>
#include <sys/statvfs.h>
#ifdef HAVE_MNTENT
@@ -488,6 +490,27 @@ bool DirAccessUnix::is_hidden(const String &p_name) {
return p_name != "." && p_name != ".." && p_name.begins_with(".");
}
+bool DirAccessUnix::is_case_sensitive(const String &p_path) const {
+#if defined(LINUXBSD_ENABLED)
+ String f = p_path;
+ if (!f.is_absolute_path()) {
+ f = get_current_dir().path_join(f);
+ }
+ f = fix_path(f);
+
+ int fd = ::open(f.utf8().get_data(), O_RDONLY | O_NONBLOCK);
+ if (fd) {
+ long flags = 0;
+ if (ioctl(fd, _IOR('f', 1, long), &flags) >= 0) {
+ ::close(fd);
+ return !(flags & 0x40000000 /* FS_CASEFOLD_FL */);
+ }
+ ::close(fd);
+ }
+#endif
+ return true;
+}
+
DirAccessUnix::DirAccessUnix() {
dir_stream = nullptr;
_cisdir = false;
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 68ad869003..8d13ff1fa8 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -82,6 +82,8 @@ public:
virtual String read_link(String p_file) override;
virtual Error create_link(String p_source, String p_target) override;
+ virtual bool is_case_sensitive(const String &p_path) const override;
+
virtual uint64_t get_space_left() override;
virtual String get_filesystem_type() const override;
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 581daaca05..51ea9234d4 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -85,6 +85,12 @@
#define RTLD_DEEPBIND 0
#endif
+#ifndef SANITIZERS_ENABLED
+#define GODOT_DLOPEN_MODE RTLD_NOW | RTLD_DEEPBIND
+#else
+#define GODOT_DLOPEN_MODE RTLD_NOW
+#endif
+
#if defined(MACOS_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
// Random location for getentropy. Fitting.
#include <sys/random.h>
@@ -650,7 +656,9 @@ Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle
path = get_executable_path().get_base_dir().path_join("../lib").path_join(p_path.get_file());
}
- p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW | RTLD_DEEPBIND);
+ ERR_FAIL_COND_V(!FileAccess::exists(path), ERR_FILE_NOT_FOUND);
+
+ p_library_handle = dlopen(path.utf8().get_data(), GODOT_DLOPEN_MODE);
ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", p_path, dlerror()));
if (r_resolved_path != nullptr) {
@@ -745,12 +753,27 @@ String OS_Unix::get_executable_path() const {
return OS::get_executable_path();
}
return b;
-#elif defined(__OpenBSD__) || defined(__NetBSD__)
+#elif defined(__OpenBSD__)
char resolved_path[MAXPATHLEN];
realpath(OS::get_executable_path().utf8().get_data(), resolved_path);
return String(resolved_path);
+#elif defined(__NetBSD__)
+ int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
+ char buf[MAXPATHLEN];
+ size_t len = sizeof(buf);
+ if (sysctl(mib, 4, buf, &len, nullptr, 0) != 0) {
+ WARN_PRINT("Couldn't get executable path from sysctl");
+ return OS::get_executable_path();
+ }
+
+ // NetBSD does not always return a normalized path. For example if argv[0] is "./a.out" then executable path is "/home/netbsd/./a.out". Normalize with realpath:
+ char resolved_path[MAXPATHLEN];
+
+ realpath(buf, resolved_path);
+
+ return String(resolved_path);
#elif defined(__FreeBSD__)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
char buf[MAXPATHLEN];