diff options
Diffstat (limited to 'platform/linuxbsd/os_linuxbsd.cpp')
-rw-r--r-- | platform/linuxbsd/os_linuxbsd.cpp | 171 |
1 files changed, 128 insertions, 43 deletions
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 88c3d2cc14..d22d398a67 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -30,21 +30,18 @@ #include "os_linuxbsd.h" +#include "core/io/certs_compressed.gen.h" #include "core/io/dir_access.h" #include "main/main.h" #include "servers/display_server.h" -#include "modules/modules_enabled.gen.h" // For regex. -#ifdef MODULE_REGEX_ENABLED -#include "modules/regex/regex.h" -#endif - #ifdef X11_ENABLED #include "x11/display_server_x11.h" #endif -#ifdef HAVE_MNTENT -#include <mntent.h> +#include "modules/modules_enabled.gen.h" // For regex. +#ifdef MODULE_REGEX_ENABLED +#include "modules/regex/regex.h" #endif #include <dlfcn.h> @@ -56,6 +53,10 @@ #include <sys/utsname.h> #include <unistd.h> +#ifdef HAVE_MNTENT +#include <mntent.h> +#endif + void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" }; @@ -163,6 +164,27 @@ String OS_LinuxBSD::get_processor_name() const { ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name from `/proc/cpuinfo`. Returning an empty string.")); } +bool OS_LinuxBSD::is_sandboxed() const { + // This function is derived from SDL: + // https://github.com/libsdl-org/SDL/blob/main/src/core/linux/SDL_sandbox.c#L28-L45 + + if (access("/.flatpak-info", F_OK) == 0) { + return true; + } + + // For Snap, we check multiple variables because they might be set for + // unrelated reasons. This is the same thing WebKitGTK does. + if (has_environment("SNAP") && has_environment("SNAP_NAME") && has_environment("SNAP_REVISION")) { + return true; + } + + if (access("/run/host/container-manager", F_OK) == 0) { + return true; + } + + return false; +} + void OS_LinuxBSD::finalize() { if (main_loop) { memdelete(main_loop); @@ -195,6 +217,10 @@ void OS_LinuxBSD::set_main_loop(MainLoop *p_main_loop) { main_loop = p_main_loop; } +String OS_LinuxBSD::get_identifier() const { + return "linuxbsd"; +} + String OS_LinuxBSD::get_name() const { #ifdef __linux__ return "Linux"; @@ -210,48 +236,54 @@ String OS_LinuxBSD::get_name() const { } String OS_LinuxBSD::get_systemd_os_release_info_value(const String &key) const { - static String info; - if (info.is_empty()) { - Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ); - if (f.is_valid()) { - while (!f->eof_reached()) { - const String line = f->get_line(); - if (line.find(key) != -1) { - return line.split("=")[1].strip_edges(); - } + Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ); + if (f.is_valid()) { + while (!f->eof_reached()) { + const String line = f->get_line(); + if (line.find(key) != -1) { + String value = line.split("=")[1].strip_edges(); + value = value.trim_prefix("\""); + return value.trim_suffix("\""); } } } - return info; + return ""; } String OS_LinuxBSD::get_distribution_name() const { - static String systemd_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string. - if (!systemd_name.is_empty()) { - return systemd_name; + static String distribution_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string. + if (!distribution_name.is_empty()) { + return distribution_name; } struct utsname uts; // returns a decent value for BSD family. uname(&uts); - return uts.sysname; + distribution_name = uts.sysname; + return distribution_name; } String OS_LinuxBSD::get_version() const { - static String systemd_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string. - if (!systemd_version.is_empty()) { - return systemd_version; + static String release_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string. + if (!release_version.is_empty()) { + return release_version; } struct utsname uts; // returns a decent value for BSD family. uname(&uts); - return uts.version; + release_version = uts.version; + return release_version; } Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { - if (RenderingServer::get_singleton()->get_rendering_device() == nullptr) { + if (RenderingServer::get_singleton() == nullptr) { return Vector<String>(); } - const String rendering_device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name(); // e.g. `NVIDIA GeForce GTX 970` - const String rendering_device_vendor = RenderingServer::get_singleton()->get_rendering_device()->get_device_vendor_name(); // e.g. `NVIDIA` + static Vector<String> info; + if (!info.is_empty()) { + return info; + } + + const String rendering_device_name = RenderingServer::get_singleton()->get_video_adapter_name(); // e.g. `NVIDIA GeForce GTX 970` + const String rendering_device_vendor = RenderingServer::get_singleton()->get_video_adapter_vendor(); // e.g. `NVIDIA` const String card_name = rendering_device_name.trim_prefix(rendering_device_vendor).strip_edges(); // -> `GeForce GTX 970` String vendor_device_id_mappings; @@ -315,8 +347,8 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { Vector<String> class_display_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_display_device_candidates, kernel_lit, dummys); Vector<String> class_3d_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_3d_device_candidates, kernel_lit, dummys); - static String driver_name; - static String driver_version; + String driver_name; + String driver_version; // Use first valid value: for (const String &driver : class_3d_device_drivers) { @@ -336,7 +368,6 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { } } - Vector<String> info; info.push_back(driver_name); String modinfo; @@ -486,10 +517,23 @@ bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) { return font_config_initialized; } #endif + +#ifndef __linux__ + // `bsd` includes **all** BSD, not only "other BSD" (see `get_name()`). + if (p_feature == "bsd") { + return true; + } +#endif + if (p_feature == "pc") { return true; } + // Match against the specific OS (`linux`, `freebsd`, `netbsd`, `openbsd`). + if (p_feature == get_name().to_lower()) { + return true; + } + return false; } @@ -931,39 +975,36 @@ static String get_mountpoint(const String &p_path) { } Error OS_LinuxBSD::move_to_trash(const String &p_path) { - String path = p_path.rstrip("/"); // Strip trailing slash when path points to a directory + // We try multiple methods, until we find one that works. + // So we only return on success until we exhausted possibilities. + String path = p_path.rstrip("/"); // Strip trailing slash when path points to a directory. int err_code; List<String> args; args.push_back(path); - args.push_front("trash"); // The command is `gio trash <file_name>` so we need to add it to args. + + args.push_front("trash"); // The command is `gio trash <file_name>` so we add it before the path. Error result = execute("gio", args, nullptr, &err_code); // For GNOME based machines. - if (result == OK && !err_code) { + if (result == OK && err_code == 0) { // Success. return OK; - } else if (err_code == 2) { - return ERR_FILE_NOT_FOUND; } args.pop_front(); args.push_front("move"); args.push_back("trash:/"); // The command is `kioclient5 move <file_name> trash:/`. result = execute("kioclient5", args, nullptr, &err_code); // For KDE based machines. - if (result == OK && !err_code) { + if (result == OK && err_code == 0) { return OK; - } else if (err_code == 2) { - return ERR_FILE_NOT_FOUND; } args.pop_front(); args.pop_back(); result = execute("gvfs-trash", args, nullptr, &err_code); // For older Linux machines. - if (result == OK && !err_code) { + if (result == OK && err_code == 0) { return OK; - } else if (err_code == 2) { - return ERR_FILE_NOT_FOUND; } - // If the commands `kioclient5`, `gio` or `gvfs-trash` don't exist on the system we do it manually. + // If the commands `kioclient5`, `gio` or `gvfs-trash` don't work on the system we do it manually. String trash_path = ""; String mnt = get_mountpoint(path); @@ -1076,6 +1117,40 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { return OK; } +String OS_LinuxBSD::get_system_ca_certificates() { + String certfile; + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + // Compile time preferred certificates path. + if (!String(_SYSTEM_CERTS_PATH).is_empty() && da->file_exists(_SYSTEM_CERTS_PATH)) { + certfile = _SYSTEM_CERTS_PATH; + } else if (da->file_exists("/etc/ssl/certs/ca-certificates.crt")) { + // Debian/Ubuntu + certfile = "/etc/ssl/certs/ca-certificates.crt"; + } else if (da->file_exists("/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem")) { + // Fedora + certfile = "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"; + } else if (da->file_exists("/etc/ca-certificates/extracted/tls-ca-bundle.pem")) { + // Arch Linux + certfile = "/etc/ca-certificates/extracted/tls-ca-bundle.pem"; + } else if (da->file_exists("/var/lib/ca-certificates/ca-bundle.pem")) { + // openSUSE + certfile = "/var/lib/ca-certificates/ca-bundle.pem"; + } else if (da->file_exists("/etc/ssl/cert.pem")) { + // FreeBSD/OpenBSD + certfile = "/etc/ssl/cert.pem"; + } + + if (certfile.is_empty()) { + return ""; + } + + Ref<FileAccess> f = FileAccess::open(certfile, FileAccess::READ); + ERR_FAIL_COND_V_MSG(f.is_null(), "", vformat("Failed to open system CA certificates file: '%s'", certfile)); + + return f->get_as_text(); +} + OS_LinuxBSD::OS_LinuxBSD() { main_loop = nullptr; @@ -1103,6 +1178,16 @@ OS_LinuxBSD::OS_LinuxBSD() { font_config_initialized = true; #endif if (font_config_initialized) { + bool ver_ok = false; + int version = FcGetVersion(); + ver_ok = ((version / 100 / 100) == 2 && (version / 100 % 100) >= 11) || ((version / 100 / 100) > 2); // 2.11.0 + print_verbose(vformat("FontConfig %d.%d.%d detected.", version / 100 / 100, version / 100 % 100, version % 100)); + if (!ver_ok) { + font_config_initialized = false; + } + } + + if (font_config_initialized) { config = FcInitLoadConfigAndFonts(); if (!config) { font_config_initialized = false; |