not block so long
[enigma2.git] / lib / base / console.cpp
index b3fbbf7..3f73fba 100644 (file)
@@ -49,7 +49,7 @@ int bidirpipe(int pfd[], char *cmd , char *argv[])
 }
 
 eConsoleAppContainer::eConsoleAppContainer()
-:pid(-1), killstate(0)
+:pid(-1), killstate(0), in(0), out(0), err(0)
 {
        for (int i=0; i < 3; ++i)
                fd[i]=-1;
@@ -124,7 +124,9 @@ int eConsoleAppContainer::execute( const std::string &cmd )
 
 //     eDebug("%d args", cnt-2);
        char **argv = new char*[cnt];  // min two args... path and terminating 0
-       argv[0] = new char[ plen ];
+//     eDebug("%d args", cnt);
+       argv[0] = new char[ plen+1 ];
+//     eDebug("new argv[0] %d bytes (%s)", plen+1, path.c_str());
        strcpy( argv[0], path.c_str() );
        argv[cnt-1] = 0;               // set terminating null
 
@@ -154,6 +156,7 @@ int eConsoleAppContainer::execute( const std::string &cmd )
                                        tmp.erase(tmp.length()-1, 1);
                                        bracketClosed=false;
                                }
+//                             eDebug("new argv[%d] %d bytes (%s)", cnt, tmp.length()+1, tmp.c_str());
                                argv[cnt] = new char[ tmp.length()+1 ];
 //                             eDebug("idx=%d, arg = %s", idx, tmp.c_str() );
                                strcpy( argv[cnt++], tmp.c_str() );
@@ -171,7 +174,8 @@ int eConsoleAppContainer::execute( const std::string &cmd )
                        cmds.erase(cmds.length()-1, 1);
                }
                // store the last arg
-               argv[cnt] = new char[ cmds.length() ];
+//             eDebug("new argv[%d] %d bytes (%s)", cnt, cmds.length()+1, cmds.c_str());
+               argv[cnt] = new char[ cmds.length()+1 ];
                strcpy( argv[cnt], cmds.c_str() );
        }
        else
@@ -196,11 +200,11 @@ int eConsoleAppContainer::execute( const std::string &cmd )
        if ( pid == -1 )
                return -3;
 
-       eDebug("pipe in = %d, out = %d, err = %d", fd[0], fd[1], fd[2]);
+//     eDebug("pipe in = %d, out = %d, err = %d", fd[0], fd[1], fd[2]);
 
-       in = new eSocketNotifier(eApp, fd[0], POLLIN|POLLPRI|POLLHUP );
-       out = new eSocketNotifier(eApp, fd[1], POLLOUT, false);  
-       err = new eSocketNotifier(eApp, fd[2], POLLIN|POLLPRI );
+       in = new eSocketNotifier(eApp, fd[0], eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Hungup );
+       out = new eSocketNotifier(eApp, fd[1], eSocketNotifier::Write, false);  
+       err = new eSocketNotifier(eApp, fd[2], eSocketNotifier::Read|eSocketNotifier::Priority );
        CONNECT(in->activated, eConsoleAppContainer::readyRead);
        CONNECT(out->activated, eConsoleAppContainer::readyWrite);
        CONNECT(err->activated, eConsoleAppContainer::readyErrRead);
@@ -214,7 +218,7 @@ eConsoleAppContainer::~eConsoleAppContainer()
 
 void eConsoleAppContainer::kill()
 {
-       if ( killstate != -1 )
+       if ( killstate != -1 && pid != -1 )
        {
                eDebug("user kill(SIGKILL) console App");
                killstate=-1;
@@ -235,7 +239,7 @@ void eConsoleAppContainer::kill()
 
 void eConsoleAppContainer::sendCtrlC()
 {
-       if ( killstate != -1 )
+       if ( killstate != -1 && pid != -1 )
        {
                eDebug("user send SIGINT(Ctrl-C) to console App");
                ::kill(pid, SIGINT);
@@ -244,15 +248,27 @@ void eConsoleAppContainer::sendCtrlC()
 
 void eConsoleAppContainer::closePipes()
 {
-       in->stop();
-       out->stop();
-       err->stop();
-       ::close(fd[0]);
-       fd[0]=-1;
-       ::close(fd[1]);
-       fd[1]=-1;
-       ::close(fd[2]);
-       fd[2]=-1;
+       if (in)
+               in->stop();
+       if (out)
+               out->stop();
+       if (err)
+               err->stop();
+       if (fd[0] != -1)
+       {
+               ::close(fd[0]);
+               fd[0]=-1;
+       }
+       if (fd[1] != -1)
+       {
+               ::close(fd[1]);
+               fd[1]=-1;
+       }
+       if (fd[2] != -1)
+       {
+               ::close(fd[2]);
+               fd[2]=-1;
+       }
        eDebug("pipes closed");
        while( outbuf.size() ) // cleanup out buffer
        {
@@ -260,27 +276,28 @@ void eConsoleAppContainer::closePipes()
                outbuf.pop();
                delete [] d.data;
        }
+       pid = -1;
 }
 
 void eConsoleAppContainer::readyRead(int what)
 {
-       if (what & POLLPRI|POLLIN)
+       bool hungup = what & eSocketNotifier::Hungup;
+       if (what & (eSocketNotifier::Priority|eSocketNotifier::Read))
        {
 //             eDebug("what = %d");
                char buf[2048];
-               int readed = read(fd[0], buf, 2047);
-//             eDebug("%d bytes read", readed);
-               if ( readed != -1 && readed )
+               int rd;
+               while((rd = read(fd[0], buf, 2047)) > 0)
                {
-/*                     for ( int i = 0; i < readed; i++ )
+/*                     for ( int i = 0; i < rd; i++ )
                                eDebug("%d = %c (%02x)", i, buf[i], buf[i] );*/
-                       buf[readed]=0;
+                       buf[rd]=0;
                        /*emit*/ dataAvail(buf);
+                       if (!hungup)
+                               break;
                }
-               else if (readed == -1)
-                       eDebug("readerror %d", errno);
        }
-       if (what & eSocketNotifier::Hungup)
+       if (hungup)
        {
                eDebug("child has terminated");
                closePipes();
@@ -290,21 +307,18 @@ void eConsoleAppContainer::readyRead(int what)
 
 void eConsoleAppContainer::readyErrRead(int what)
 {
-       if (what & POLLPRI|POLLIN)
+       if (what & (eSocketNotifier::Priority|eSocketNotifier::Read))
        {
 //             eDebug("what = %d");
                char buf[2048];
-               int readed = read(fd[2], buf, 2047);
-//             eDebug("%d bytes read", readed);
-               if ( readed != -1 && readed )
+               int rd;
+               while((rd = read(fd[2], buf, 2047)) > 0)
                {
-/*                     for ( int i = 0; i < readed; i++ )
+/*                     for ( int i = 0; i < rd; i++ )
                                eDebug("%d = %c (%02x)", i, buf[i], buf[i] );*/
-                       buf[readed]=0;
+                       buf[rd]=0;
                        /*emit*/ dataAvail(buf);
                }
-               else if (readed == -1)
-                       eDebug("readerror %d", errno);
        }
 }
 
@@ -318,7 +332,7 @@ void eConsoleAppContainer::write( const char *data, int len )
 
 void eConsoleAppContainer::readyWrite(int what)
 {
-       if (what&POLLOUT && outbuf.size() )
+       if (what&eSocketNotifier::Write && outbuf.size() )
        {
                queue_data d = outbuf.front();
                outbuf.pop();