X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/7ee3f3b8aaf43c8c712ce1c4c1d8b8c52e692e12..f03c85f8c3575d22eb065313857d8d3e57960e95:/lib/base/console.cpp diff --git a/lib/base/console.cpp b/lib/base/console.cpp index 2e00804a..6dc21d2e 100644 --- a/lib/base/console.cpp +++ b/lib/base/console.cpp @@ -7,6 +7,7 @@ #include #include #include +#include int bidirpipe(int pfd[], const char *cmd , const char * const argv[], const char *cwd ) { @@ -58,7 +59,10 @@ eConsoleAppContainer::eConsoleAppContainer() :pid(-1), killstate(0), in(0), out(0), err(0) { for (int i=0; i < 3; ++i) + { fd[i]=-1; + filefd[i]=-1; + } } static char brakets[][2] = { @@ -176,12 +180,13 @@ int eConsoleAppContainer::execute(const char *cmdline, const char * const argv[] // get one read ,one write and the err pipe to the prog.. pid = bidirpipe(fd, cmdline, argv, m_cwd.length() ? m_cwd.c_str() : 0); - if ( pid == -1 ) return -3; // eDebug("pipe in = %d, out = %d, err = %d", fd[0], fd[1], fd[2]); + ::fcntl(fd[1], F_SETFL, O_NONBLOCK); + ::fcntl(fd[2], F_SETFL, O_NONBLOCK); 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 ); @@ -242,6 +247,12 @@ void eConsoleAppContainer::kill() delete out; delete err; in=out=err=0; + + for (int i=0; i < 3; ++i) + { + if ( filefd[i] > 0 ) + close(filefd[i]); + } } void eConsoleAppContainer::sendCtrlC() @@ -296,18 +307,20 @@ void eConsoleAppContainer::readyRead(int what) if (what & (eSocketNotifier::Priority|eSocketNotifier::Read)) { // eDebug("what = %d"); - char buf[2048]; + char buf[2049]; int rd; - while((rd = read(fd[0], buf, 2047)) > 0) + while((rd = read(fd[0], buf, 2048)) > 0) { -/* for ( int i = 0; i < rd; i++ ) - eDebug("%d = %c (%02x)", i, buf[i], buf[i] );*/ buf[rd]=0; /*emit*/ dataAvail(buf); + stdoutAvail(buf); + if ( filefd[1] > 0 ) + ::write(filefd[1], buf, rd); if (!hungup) break; } } + readyErrRead(eSocketNotifier::Priority|eSocketNotifier::Read); /* be sure to flush all data which might be already written */ if (hungup) { eDebug("child has terminated"); @@ -334,18 +347,37 @@ void eConsoleAppContainer::readyErrRead(int what) if (what & (eSocketNotifier::Priority|eSocketNotifier::Read)) { // eDebug("what = %d"); - char buf[2048]; + char buf[2049]; int rd; - while((rd = read(fd[2], buf, 2047)) > 0) + while((rd = read(fd[2], buf, 2048)) > 0) { /* for ( int i = 0; i < rd; i++ ) eDebug("%d = %c (%02x)", i, buf[i], buf[i] );*/ buf[rd]=0; /*emit*/ dataAvail(buf); + stderrAvail(buf); } } } +void eConsoleAppContainer::dumpToFile( PyObject *py_filename ) +{ + char *filename = PyString_AsString(py_filename); + filefd[1] = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644); + eDebug("eConsoleAppContainer::dumpToFile open(%s, O_WRONLY|O_CREAT|O_TRUNC, 0644)=%i", filename, filefd[1]); +} + +void eConsoleAppContainer::readFromFile( PyObject *py_filename ) +{ + char *filename = PyString_AsString(py_filename); + char readbuf[32*1024]; + filefd[0] = open(filename, O_RDONLY); + int rsize = read(filefd[0], readbuf, 32*1024); + eDebug("eConsoleAppContainer::readFromFile open(%s, O_RDONLY)=%i, read: %i", filename, filefd[0], rsize); + if ( filefd[0] > 0 && rsize > 0 ) + write(readbuf, rsize); +} + void eConsoleAppContainer::write( const char *data, int len ) { char *tmp = new char[len]; @@ -369,20 +401,40 @@ void eConsoleAppContainer::readyWrite(int what) { if (what&eSocketNotifier::Write && outbuf.size() ) { - queue_data d = outbuf.front(); - outbuf.pop(); - if ( ::write( fd[1], d.data, d.len ) != d.len ) - { - /* emit */ dataSent(-1); -// eDebug("writeError"); - } + queue_data &d = outbuf.front(); + int wr = ::write( fd[1], d.data+d.dataSent, d.len-d.dataSent ); + if (wr < 0) + eDebug("eConsoleAppContainer write failed (%m)"); else + d.dataSent += wr; + if (d.dataSent == d.len) { + outbuf.pop(); + delete [] d.data; + if ( filefd[0] == -1 ) /* emit */ dataSent(0); -// eDebug("write ok"); } - delete [] d.data; } if ( !outbuf.size() ) - out->stop(); + { + if ( filefd[0] > 0 ) + { + char readbuf[32*1024]; + int rsize = read(filefd[0], readbuf, 32*1024); + if ( rsize > 0 ) + write(readbuf, rsize); + else + { + close(filefd[0]); + filefd[0] = -1; + ::close(fd[1]); + eDebug("readFromFile done - closing eConsoleAppContainer stdin pipe"); + fd[1]=-1; + dataSent(0); + out->stop(); + } + } + else + out->stop(); + } }