patch by Pieter Grimmerink: -call waitpid on the child, after it completes. This...
authorFelix Domke <tmbinc@elitedvb.net>
Sun, 16 Dec 2007 20:34:49 +0000 (20:34 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Sun, 16 Dec 2007 20:34:49 +0000 (20:34 +0000)
lib/base/console.cpp

index 3f73fba..1e391e1 100644 (file)
@@ -5,6 +5,8 @@
 #include <signal.h>
 #include <errno.h>
 #include <poll.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 int bidirpipe(int pfd[], char *cmd , char *argv[])
 {
@@ -222,7 +224,11 @@ void eConsoleAppContainer::kill()
        {
                eDebug("user kill(SIGKILL) console App");
                killstate=-1;
-               ::kill(pid, SIGKILL);
+               /*
+                * Use a negative pid value, to signal the whole process group
+                * ('pid' might not even be running anymore at this point)
+                */
+               ::kill(-pid, SIGKILL);
                closePipes();
        }
        while( outbuf.size() ) // cleanup out buffer
@@ -242,7 +248,11 @@ void eConsoleAppContainer::sendCtrlC()
        if ( killstate != -1 && pid != -1 )
        {
                eDebug("user send SIGINT(Ctrl-C) to console App");
-               ::kill(pid, SIGINT);
+               /*
+                * Use a negative pid value, to signal the whole process group
+                * ('pid' might not even be running anymore at this point)
+                */
+               ::kill(-pid, SIGINT);
        }
 }
 
@@ -301,7 +311,20 @@ void eConsoleAppContainer::readyRead(int what)
        {
                eDebug("child has terminated");
                closePipes();
-               /*emit*/ appClosed(killstate);
+               int childstatus;
+               int retval = killstate;
+               /*
+                * We have to call 'wait' on the child process, in order to avoid zombies.
+                * Also, this gives us the chance to provide better exit status info to appClosed.
+                */
+               if (::waitpid(pid, &childstatus, 0) > 0)
+               {
+                       if (WIFEXITED(childstatus))
+                       {
+                               retval = WEXITSTATUS(childstatus);
+                       }
+               }
+               /*emit*/ appClosed(retval);
        }
 }