aboutsummaryrefslogtreecommitdiff
path: root/src/zen/browser_launcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zen/browser_launcher.cpp')
-rw-r--r--src/zen/browser_launcher.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/zen/browser_launcher.cpp b/src/zen/browser_launcher.cpp
new file mode 100644
index 000000000..a115bf46a
--- /dev/null
+++ b/src/zen/browser_launcher.cpp
@@ -0,0 +1,71 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "browser_launcher.h"
+
+#include <zenbase/zenbase.h>
+#include <zencore/except_fmt.h>
+#include <zencore/logging.h>
+
+#include <stdexcept>
+#include <string>
+
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+# include <shellapi.h>
+#else
+# include <spawn.h>
+# include <sys/wait.h>
+extern char** environ;
+#endif
+
+namespace zen {
+
+void
+LaunchBrowser(std::string_view Url)
+{
+ if (Url.empty())
+ {
+ throw zen::runtime_error("Cannot launch browser with empty URL");
+ }
+
+ bool Success = false;
+
+#if ZEN_PLATFORM_WINDOWS
+ std::string UrlZ(Url);
+ HINSTANCE Result = ShellExecuteA(nullptr, "open", UrlZ.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ Success = reinterpret_cast<intptr_t>(Result) > 32;
+#else
+# if ZEN_PLATFORM_MAC
+ const char* Program = "open";
+# elif ZEN_PLATFORM_LINUX
+ const char* Program = "xdg-open";
+# else
+ ZEN_NOT_IMPLEMENTED("Browser launching not implemented on this platform");
+ const char* Program = nullptr;
+# endif
+
+ // Spawn directly via posix_spawnp to avoid the shell entirely, so URL contents
+ // cannot be interpreted as shell syntax regardless of what characters they contain.
+ std::string Url_c(Url);
+ char* const Argv[] = {const_cast<char*>(Program), Url_c.data(), nullptr};
+ pid_t Pid = 0;
+ const int SpawnRc = posix_spawnp(&Pid, Program, nullptr, nullptr, Argv, environ);
+ if (SpawnRc == 0)
+ {
+ int Status = 0;
+ if (waitpid(Pid, &Status, 0) == Pid)
+ {
+ Success = WIFEXITED(Status) && WEXITSTATUS(Status) == 0;
+ }
+ }
+#endif
+
+ if (!Success)
+ {
+ throw zen::runtime_error("Failed to launch browser for '{}'", Url);
+ }
+
+ ZEN_CONSOLE("Web browser launched for '{}' successfully", Url);
+}
+
+} // namespace zen