From cd3bb9933361ebea980be1cae79152d99d3dd067 Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
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(-)

(limited to 'raul')

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<size_t> _front; ///< Index to front of queue (circular)
-	std::atomic<size_t> _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<size_t> _front;    ///< Index to front of queue
+	std::atomic<size_t> _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<typename T>
-- 
cgit v1.2.1