From ce385ec27a0e578f1f1741f7b746ca461e38a52d Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Tue, 6 May 2014 19:48:50 +0200 Subject: [PATCH] Switch from vfork/exec to posix_spawn after clang static analyzer run --- src/modules/system/System.cpp | 50 +++++++++++++++-------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index 397cfbb41..dd74c120f 100755 --- a/src/modules/system/System.cpp +++ b/src/modules/system/System.cpp @@ -25,8 +25,9 @@ #if defined(LOVE_MACOSX) #include #elif defined(LOVE_LINUX) -#include -#include +#include +//#include +//#include #include #elif defined(LOVE_WINDOWS) #include "common/utf8.h" @@ -53,12 +54,17 @@ std::string System::getOS() const #endif } +extern "C" +{ + extern char **environ; // The environment, always available +} + bool System::openURL(const std::string &url) const { - bool success = false; #if defined(LOVE_MACOSX) + bool success = false; // We could be lazy and use system("open " + url), but this is safer. CFURLRef cfurl = CFURLCreateWithBytes(nullptr, (const UInt8 *) url.c_str(), @@ -68,34 +74,24 @@ bool System::openURL(const std::string &url) const success = LSOpenCFURLRef(cfurl, nullptr) == noErr; CFRelease(cfurl); + return success; #elif defined(LOVE_LINUX) - // Spawn a child process, which we'll replace with xdg-open. - pid_t pid = vfork(); + pid_t pid; + const char *argv[] = {"xdg-open", url.c_str(), nullptr}; - if (pid == 0) // Child process. - { - // Replace the child process with xdg-open and pass in the URL. - execlp("xdg-open", "xdg-open", url.c_str(), nullptr); + // Note: at the moment this process inherits our file descriptors. + // Note: the below const_cast is really ugly as well. + if (posix_spawnp(&pid, "xdg-open", nullptr, nullptr, const_cast(argv), environ) != 0) + return false; - // exec will only return if it errored, so we should exit with non-zero. - _exit(1); - } - else if (pid > 0) // Parent process. - { - // Wait for xdg-open to complete (or fail.) - int status = 0; - if (waitpid(pid, &status, 0) == pid) - success = (status == 0); - else - success = false; - } + // Wait for xdg-open to complete (or fail.) + int status = 0; + if (waitpid(pid, &status, 0) == pid) + return (status == 0); else - { - // vfork() failed. - success = false; - } + return false; #elif defined(LOVE_WINDOWS) @@ -109,11 +105,9 @@ bool System::openURL(const std::string &url) const nullptr, SW_SHOW); - success = (int) result > 32; + return (int) result > 32; #endif - - return success; } bool System::getConstant(const char *in, System::PowerState &out)