From cd3bb9933361ebea980be1cae79152d99d3dd067 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 16 Mar 2015 22:50:11 +0000 Subject: Fix launching GUI with no engine. git-svn-id: http://svn.drobilla.net/lad/trunk/raul@5640 a436a847-0d15-0410-975c-d299462d15a1 --- raul/Process.hpp | 71 +++++++++++++++++++++++++++--------------------------- raul/SRSWQueue.hpp | 8 +++--- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/raul/Process.hpp b/raul/Process.hpp index 4226a46..1ddb41f 100644 --- a/raul/Process.hpp +++ b/raul/Process.hpp @@ -34,49 +34,48 @@ namespace Raul { class Process : Noncopyable { public: - /** Launch a sub process. * - * @param command can be a typical shell command with parameters, the PATH is searched etc. + * @param argv List of arguments, where argv[0] is the command name. + * @return True on success. */ - static bool launch(const std::string& command) { - const std::string executable = (command.find(" ") != std::string::npos) - ? command.substr(0, command.find(" ")) - : command; - - const std::string arguments = command.substr((command.find(" ") + 1)); - - // Use the same double fork() trick as JACK to prevent zombie children - const int err = fork(); - - if (err == 0) { - // (child) - - // close all nonstandard file descriptors - struct rlimit max_fds; - getrlimit(RLIMIT_NOFILE, &max_fds); - - for (rlim_t fd = 3; fd < max_fds.rlim_cur; ++fd) - close(fd); - - switch (fork()) { - case 0: - // (grandchild) - setsid(); - execlp(executable.c_str(), arguments.c_str(), NULL); - _exit(-1); - - case -1: - // (second) fork failed, there is no grandchild - _exit(-1); + static bool launch(const char* const argv[]) { + // Use the same double fork() trick as JACK to prevent zombie children + const int child = fork(); + + if (child == 0) { + // (in child) + + // Close all nonstandard file descriptors + struct rlimit max_fds; + getrlimit(RLIMIT_NOFILE, &max_fds); + for (rlim_t fd = 3; fd < max_fds.rlim_cur; ++fd) { + close(fd); + } - /* exit the child process here */ - default: - _exit(0); + // Fork child + const int grandchild = fork(); + switch (grandchild) { + case 0: + // (in grandchild) + setsid(); + execvp(argv[0], (char*const*)argv); + _exit(-1); + + case -1: + // Fork failed, there is no grandchild + _exit(-1); + + default: + // Fork succeeded, return grandchild PID + _exit(grandchild); } + } else if (child < 0) { + // Fork failed, there is no child + return false; } - return (err > 0); + return true; } private: diff --git a/raul/SRSWQueue.hpp b/raul/SRSWQueue.hpp index 36c0f5d..754cccd 100644 --- a/raul/SRSWQueue.hpp +++ b/raul/SRSWQueue.hpp @@ -60,10 +60,10 @@ public: inline void pop(); private: - std::atomic _front; ///< Index to front of queue (circular) - std::atomic _back; ///< Index to back of queue (one past last element) (circular) - const size_t _size; ///< Size of `_objects` (you can store _size-1 objects) - T* const _objects; ///< Fixed array containing queued elements + std::atomic _front; ///< Index to front of queue + std::atomic _back; ///< Index to back of queue (one past end) + const size_t _size; ///< Size of `_objects` (at most _size-1) + T* const _objects; ///< Fixed array containing queued elements }; template -- cgit v1.2.1