ChildProcess exitCode


#1

Hello!

Any chance of adding a function to get the exit code from a ChildProcess?

[I spent a chunk of yesterday reworking my old code for managing child processes, and it wasn't until I'd got it all working nicely that I discovered you'd already added a class with the same name and damn-near the same interface! :D the only thing it's missing is the exit code].

 


#2

...the fact that stdErr and stdOut are combined into one stream is a bit of a problem, especially without access to an exit code. 

Currently the only way to separate error output from normal output is to run a process twice :s

 


#3

Bit busy, but if you could give me a quick diff for getting the return code, would be happy to add it ;)

FYI, I'm working on some new classes that'll combine the ChildProcess and InterprocessConnection into some higher-level objects so that it'll be really easy to create and spin-off a slave process and talk to it with two-way message passing. My initial use-case for this is to improve plugin scanning, but it'll be a really handy class for lots of other stuff too.


#4

I've been working on windows at the moment, so alas that's all I have any implementation for right now.

Here's a diff all the same! As bare-bones and carefree as it gets :)


diff --git a/modules/juce_core/native/juce_win32_Threads.cpp b/modules/juce_core/native/juce_win32_Threads.cpp
index d6de0f8..4868ce0 100644
--- a/modules/juce_core/native/juce_win32_Threads.cpp
+++ b/modules/juce_core/native/juce_win32_Threads.cpp
@@ -487,6 +487,13 @@ public:
         return WaitForSingleObject (processInfo.hProcess, 0) != WAIT_OBJECT_0;
     }
 
+    uint32 getExitCode () const
+    {
+        DWORD exitCode = 0;
+        GetExitCodeProcess(processInfo.hProcess, &exitCode); // todo: check return value!
+        return exitCode;
+    }
+
     int read (void* dest, int numNeeded) const
     {
         int total = 0;
@@ -556,6 +563,11 @@ bool ChildProcess::isRunning() const
     return activeProcess != nullptr && activeProcess->isRunning();
 }
 
+uint32 ChildProcess::getExitCode () const
+{
+    return activeProcess != nullptr ? activeProcess->getExitCode() : 0;
+}
+
 int ChildProcess::readProcessOutput (void* dest, int numBytes)
 {
     return activeProcess != nullptr ? activeProcess->read (dest, numBytes) : 0;
diff --git a/modules/juce_core/threads/juce_ChildProcess.h b/modules/juce_core/threads/juce_ChildProcess.h
index c5a245f..bd669b8 100644
--- a/modules/juce_core/threads/juce_ChildProcess.h
+++ b/modules/juce_core/threads/juce_ChildProcess.h
@@ -83,6 +83,8 @@ public:
     /** Returns true if the child process is alive. */
     bool isRunning() const;
 
+    uint32 getExitCode () const;
+
     /** Attempts to read some output from the child process.
         This will attempt to read up to the given number of bytes of data from the
         process. It returns the number of bytes that were actually read.

#5

Ok, have added that now.. Haven't tested windows so let me know if it doesn't work.


#6

cool :) I have to carry on with my version for now, since I need to be able to read stdout and stderr independently - its not really all that different - the only problem it creates is breaking the 'readAllProcessOutput' function, since that only returns a single String. For now, my version has an OutputLog class which my equivalent function returns instead (which just holds two strings and the exit code), but i'm not entirely convinced it's the best approach to use. Other than that, its the same.