Fix opening URIs hanging the game on freedesktop systems

Apparently xdg-open was meant to hang all this time and we're supposed to not wait for it, ok then: 5f7169ec0f/scripts/desc/xdg-open.xml (L148)

Also stop using system(3).
This commit is contained in:
Tamás Bálint Misius
2025-08-16 14:33:24 +02:00
parent 8cbb17471f
commit 21b533ae47

View File

@@ -6,18 +6,59 @@
#include "Config.h"
#include <cstring>
#include <ctime>
#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
#ifdef __FreeBSD__
# include <sys/sysctl.h>
#endif
static bool Run(const char *what, std::vector<ByteString> cmd, bool check)
{
auto pid = fork();
if (pid == -1)
{
std::cerr << what << ": fork failed: errno " << errno << ": " << strerror(errno) << std::endl;
return false;
}
if (pid == 0)
{
std::vector<char *> argv;
for (auto &p : cmd)
{
argv.push_back(const_cast<char *>(p.c_str())); // not really a problem hopefully
}
argv.push_back(nullptr);
execvp(argv[0], argv.data());
exit(1); // exec failed >_>
}
if (check)
{
int status;
if (waitpid(pid, &status, 0) != pid)
{
std::cerr << what << ": child possibly failed: errno " << errno << ": " << strerror(errno) << std::endl;
return false;
}
if (!WIFEXITED(status))
{
std::cerr << what << ": child possibly failed: waitpid status " << status << std::endl;
return false;
}
if (WEXITSTATUS(status))
{
std::cerr << what << ": child failed: exit status " << WEXITSTATUS(status) << std::endl;
return false;
}
}
return true;
}
namespace Platform
{
void OpenURI(ByteString uri)
{
if (system(("xdg-open \"" + uri + "\"").c_str()))
{
fprintf(stderr, "cannot open URI: system(...) failed\n");
}
Run("opening URI", { "xdg-open", uri }, false);
}
long unsigned int GetTime()
@@ -100,35 +141,36 @@ bool Install()
desktopData += ByteString::Build("Path=", desktopEscapeString(path), "\n");
ByteString file = ByteString::Build(APPVENDOR, "-", APPID, ".desktop");
ok = ok && Platform::WriteFile(desktopData, file);
ok = ok && !system(ByteString::Build("xdg-desktop-menu install ", file).c_str());
ok = ok && !system(ByteString::Build("xdg-mime default ", file, " application/vnd.powdertoy.save").c_str());
ok = ok && !system(ByteString::Build("xdg-mime default ", file, " x-scheme-handler/ptsave").c_str());
ok = ok && Run("installing desktop file", { "xdg-desktop-menu", "install", file }, true);
ok = ok && Run("associating save MIME type with desktop file", { "xdg-mime", "default", file, "application/vnd.powdertoy.save" }, true);
ok = ok && Run("associating ptsave URL scheme with desktop file", { "xdg-mime", "default", file, "x-scheme-handler/ptsave" }, true);
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = ByteString(APPVENDOR) + "-save.xml";
ok = ok && Platform::WriteFile(save_xml.AsCharSpan(), file);
ok = ok && !system(ByteString::Build("xdg-mime install ", file).c_str());
ok = ok && Run("associating saves and stamps with save MIME type with desktop file", { "xdg-mime", "install", file }, true);
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = ByteString(APPVENDOR) + "-cps.png";
ok = ok && Platform::WriteFile(icon_cps_png.AsCharSpan(), file);
ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 64 ", file, " application-vnd.powdertoy.save").c_str());
ok = ok && Run("providing file icons for saves and stamps", { "xdg-icon-resource", "install", "--noupdate", "--context", "mimetypes", "--size", "64", file, "application-vnd.powdertoy.save" }, true);
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = ByteString(APPVENDOR) + "-exe.png";
auto vendoredName = ByteString::Build(APPVENDOR, "-", APPEXE);
ok = ok && Platform::WriteFile(icon_exe_png.AsCharSpan(), file);
ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --size 64 ", file, " ", APPVENDOR, "-", APPEXE).c_str());
ok = ok && Run("providing desktop file icon", { "xdg-icon-resource", "install", "--noupdate", "--size", "64", file, vendoredName }, true);
Platform::RemoveFile(file);
}
if (ok)
{
ok = ok && !system("xdg-icon-resource forceupdate");
ok = ok && Run("updating desktop icons", { "xdg-icon-resource", "forceupdate" }, true);
}
return ok;
}