create global (real) config entries, update setup on hotplug (untested), fix apply...
[enigma2.git] / lib / base / console.cpp
index 75c6162f2b86c52b82e5d1f9c70baf59fc1c2bf6..1e391e170f416287a74d7f40639a4bc7f14cbdfe 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);
        }
 }
 
@@ -281,6 +291,7 @@ void eConsoleAppContainer::closePipes()
 
 void eConsoleAppContainer::readyRead(int what)
 {
+       bool hungup = what & eSocketNotifier::Hungup;
        if (what & (eSocketNotifier::Priority|eSocketNotifier::Read))
        {
 //             eDebug("what = %d");
@@ -292,13 +303,28 @@ void eConsoleAppContainer::readyRead(int what)
                                eDebug("%d = %c (%02x)", i, buf[i], buf[i] );*/
                        buf[rd]=0;
                        /*emit*/ dataAvail(buf);
+                       if (!hungup)
+                               break;
                }
        }
-       if (what & eSocketNotifier::Hungup)
+       if (hungup)
        {
                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);
        }
 }