diff --git a/Userland/Libraries/LibDesktop/AppFile.cpp b/Userland/Libraries/LibDesktop/AppFile.cpp index 70daecc5e2..ac42b9e955 100644 --- a/Userland/Libraries/LibDesktop/AppFile.cpp +++ b/Userland/Libraries/LibDesktop/AppFile.cpp @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include namespace Desktop { @@ -179,4 +181,41 @@ bool AppFile::spawn(ReadonlySpan arguments) const return true; } +bool AppFile::spawn_with_escalation(ReadonlySpan user_arguments) const +{ + if (!is_valid()) + return false; + + StringView exe; + Vector args; + // FIXME: These single quotes won't be enough for executables with single quotes in their name. + auto pls_with_executable = ByteString::formatted("/bin/pls '{}'", executable()); + if (run_in_terminal() && !requires_root()) { + exe = "/bin/Terminal"sv; + args = { "-e"sv, executable().view() }; + } else if (!run_in_terminal() && requires_root()) { + exe = "/bin/Escalator"sv; + args = { executable().view() }; + } else if (run_in_terminal() && requires_root()) { + exe = "/bin/Terminal"sv; + args = { "-e"sv, pls_with_executable.view() }; + } else { + exe = executable().view(); + } + args.extend(Vector(user_arguments)); + + auto pid = Core::Process::spawn(exe, args.span(), + working_directory().is_empty() ? Core::StandardPaths::home_directory() : working_directory()); + if (pid.is_error()) + return false; + + return true; +} + +void AppFile::spawn_with_escalation_or_show_error(GUI::Window& window, ReadonlySpan arguments) const +{ + if (!spawn_with_escalation(arguments)) + GUI::MessageBox::show_error(&window, ByteString::formatted("Failed to spawn {} with escalation", executable())); +} + } diff --git a/Userland/Libraries/LibDesktop/AppFile.h b/Userland/Libraries/LibDesktop/AppFile.h index 05299d4c26..c78eaaa6cf 100644 --- a/Userland/Libraries/LibDesktop/AppFile.h +++ b/Userland/Libraries/LibDesktop/AppFile.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace Desktop { @@ -44,6 +45,8 @@ public: Vector launcher_file_types() const; Vector launcher_protocols() const; bool spawn(ReadonlySpan arguments = {}) const; + bool spawn_with_escalation(ReadonlySpan arguments = {}) const; + void spawn_with_escalation_or_show_error(GUI::Window&, ReadonlySpan arguments = {}) const; private: explicit AppFile(StringView path);