Utilities.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
  3. * Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "Utilities.h"
  8. #include <AK/LexicalPath.h>
  9. #include <AK/Platform.h>
  10. #include <LibCore/Directory.h>
  11. #include <LibCore/Environment.h>
  12. #include <LibCore/Resource.h>
  13. #include <LibCore/ResourceImplementationFile.h>
  14. #include <LibCore/System.h>
  15. #include <LibFileSystem/FileSystem.h>
  16. #define TOKENCAT(x, y) x##y
  17. #define STRINGIFY(x) TOKENCAT(x, sv)
  18. // This is expected to be set from the build scripts, if a packager desires
  19. #if defined(LADYBIRD_LIBEXECDIR)
  20. constexpr auto libexec_path = STRINGIFY(LADYBIRD_LIBEXECDIR);
  21. #else
  22. constexpr auto libexec_path = "libexec"sv;
  23. #endif
  24. ByteString s_ladybird_resource_root;
  25. Optional<ByteString> s_mach_server_name;
  26. Optional<ByteString const&> mach_server_name()
  27. {
  28. if (s_mach_server_name.has_value())
  29. return *s_mach_server_name;
  30. return {};
  31. }
  32. void set_mach_server_name(ByteString name)
  33. {
  34. s_mach_server_name = move(name);
  35. }
  36. ErrorOr<ByteString> application_directory()
  37. {
  38. auto current_executable_path = TRY(Core::System::current_executable_path());
  39. return LexicalPath::dirname(current_executable_path);
  40. }
  41. [[gnu::used]] static LexicalPath find_prefix(LexicalPath const& application_directory);
  42. static LexicalPath find_prefix(LexicalPath const& application_directory)
  43. {
  44. if (application_directory.string().ends_with(libexec_path)) {
  45. // Strip libexec_path if it's there
  46. return LexicalPath(application_directory.string().substring_view(0, application_directory.string().length() - libexec_path.length()));
  47. }
  48. // Otherwise, we are in $prefix/bin
  49. return application_directory.parent();
  50. }
  51. void platform_init()
  52. {
  53. s_ladybird_resource_root = [] {
  54. auto home = Core::Environment::get("XDG_CONFIG_HOME"sv)
  55. .value_or_lazy_evaluated_optional([]() { return Core::Environment::get("HOME"sv); });
  56. if (home.has_value()) {
  57. auto home_lagom = ByteString::formatted("{}/.lagom", home);
  58. if (FileSystem::is_directory(home_lagom))
  59. return home_lagom;
  60. }
  61. auto app_dir = MUST(application_directory());
  62. #ifdef AK_OS_MACOS
  63. return LexicalPath(app_dir).parent().append("Resources"sv).string();
  64. #else
  65. return find_prefix(LexicalPath(app_dir)).append("share/Lagom"sv).string();
  66. #endif
  67. }();
  68. Core::ResourceImplementation::install(make<Core::ResourceImplementationFile>(MUST(String::from_byte_string(s_ladybird_resource_root))));
  69. }
  70. void copy_default_config_files(StringView config_path)
  71. {
  72. MUST(Core::Directory::create(config_path, Core::Directory::CreateDirectories::Yes));
  73. auto config_resources = MUST(Core::Resource::load_from_uri("resource://ladybird/default-config"sv));
  74. config_resources->for_each_descendant_file([config_path](Core::Resource const& resource) -> IterationDecision {
  75. auto file_path = ByteString::formatted("{}/{}", config_path, resource.filename());
  76. if (Core::System::stat(file_path).is_error()) {
  77. auto file = MUST(Core::File::open(file_path, Core::File::OpenMode::Write));
  78. MUST(file->write_until_depleted(resource.data()));
  79. }
  80. return IterationDecision::Continue;
  81. });
  82. }
  83. ErrorOr<Vector<ByteString>> get_paths_for_helper_process(StringView process_name)
  84. {
  85. auto application_path = TRY(application_directory());
  86. Vector<ByteString> paths;
  87. #if !defined(AK_OS_MACOS)
  88. auto prefix = find_prefix(LexicalPath(application_path));
  89. TRY(paths.try_append(LexicalPath::join(prefix.string(), libexec_path, process_name).string()));
  90. TRY(paths.try_append(LexicalPath::join(prefix.string(), "bin"sv, process_name).string()));
  91. #endif
  92. TRY(paths.try_append(ByteString::formatted("{}/{}", application_path, process_name)));
  93. TRY(paths.try_append(ByteString::formatted("./{}", process_name)));
  94. // NOTE: Add platform-specific paths here
  95. return paths;
  96. }