diff options
Diffstat (limited to 'Source/CPack/OSXScriptLauncher.cxx')
-rw-r--r-- | Source/CPack/OSXScriptLauncher.cxx | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx new file mode 100644 index 0000000..00d272c --- /dev/null +++ b/Source/CPack/OSXScriptLauncher.cxx @@ -0,0 +1,119 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmsys/FStream.hxx" +#include "cmsys/Process.h" +#include "cmsys/SystemTools.hxx" +#include <iostream> +#include <stddef.h> +#include <string> +#include <vector> + +#include <CoreFoundation/CoreFoundation.h> + +// For the PATH_MAX constant +#include <sys/syslimits.h> + +#define DebugError(x) \ + ofs << x << std::endl; \ + std::cout << x << std::endl + +int main(int argc, char* argv[]) +{ + // if ( cmsys::SystemTools::FileExists( + cmsys::ofstream ofs("/tmp/output.txt"); + + CFStringRef fileName; + CFBundleRef appBundle; + CFURLRef scriptFileURL; + UInt8* path; + + // get CF URL for script + if (!(appBundle = CFBundleGetMainBundle())) { + DebugError("Cannot get main bundle"); + return 1; + } + fileName = CFSTR("RuntimeScript"); + if (!(scriptFileURL = + CFBundleCopyResourceURL(appBundle, fileName, nullptr, nullptr))) { + DebugError("CFBundleCopyResourceURL failed"); + return 1; + } + + // create path string + if (!(path = new UInt8[PATH_MAX])) { + return 1; + } + + // get the file system path of the url as a cstring + // in an encoding suitable for posix apis + if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path, PATH_MAX)) { + DebugError("CFURLGetFileSystemRepresentation failed"); + return 1; + } + + // dispose of the CF variable + CFRelease(scriptFileURL); + + std::string fullScriptPath = reinterpret_cast<char*>(path); + delete[] path; + + if (!cmsys::SystemTools::FileExists(fullScriptPath.c_str())) { + return 1; + } + + std::string scriptDirectory = + cmsys::SystemTools::GetFilenamePath(fullScriptPath); + ofs << fullScriptPath << std::endl; + std::vector<const char*> args; + args.push_back(fullScriptPath.c_str()); + int cc; + for (cc = 1; cc < argc; ++cc) { + args.push_back(argv[cc]); + } + args.push_back(nullptr); + + cmsysProcess* cp = cmsysProcess_New(); + cmsysProcess_SetCommand(cp, args.data()); + cmsysProcess_SetWorkingDirectory(cp, scriptDirectory.c_str()); + cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); + cmsysProcess_SetTimeout(cp, 0); + cmsysProcess_Execute(cp); + + std::vector<char> tempOutput; + char* data; + int length; + while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) { + // Translate NULL characters in the output into valid text. + for (int i = 0; i < length; ++i) { + if (data[i] == '\0') { + data[i] = ' '; + } + } + std::cout.write(data, length); + } + + cmsysProcess_WaitForExit(cp, nullptr); + + bool result = true; + if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { + if (cmsysProcess_GetExitValue(cp) != 0) { + result = false; + } + } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exception) { + const char* exception_str = cmsysProcess_GetExceptionString(cp); + std::cerr << exception_str << std::endl; + result = false; + } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Error) { + const char* error_str = cmsysProcess_GetErrorString(cp); + std::cerr << error_str << std::endl; + result = false; + } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Expired) { + const char* error_str = "Process terminated due to timeout\n"; + std::cerr << error_str << std::endl; + result = false; + } + + cmsysProcess_Delete(cp); + + return 0; +} |