From: Andreas Frisch Date: Tue, 2 Sep 2008 16:57:09 +0000 (+0000) Subject: emit seperate signals for stdout and stderr pipes, allow cat'ing file content into... X-Git-Tag: 2.6.0~912 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/654bb0a0f8583b7cbc47b32f7e9b6921dffc4e03 emit seperate signals for stdout and stderr pipes, allow cat'ing file content into container apps and dumping their output to a file --- diff --git a/lib/base/console.cpp b/lib/base/console.cpp index 4c3be72c..6dc21d2e 100644 --- a/lib/base/console.cpp +++ b/lib/base/console.cpp @@ -59,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] = { @@ -244,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() @@ -304,6 +313,9 @@ void eConsoleAppContainer::readyRead(int what) { buf[rd]=0; /*emit*/ dataAvail(buf); + stdoutAvail(buf); + if ( filefd[1] > 0 ) + ::write(filefd[1], buf, rd); if (!hungup) break; } @@ -343,10 +355,29 @@ void eConsoleAppContainer::readyErrRead(int what) 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]; @@ -380,9 +411,30 @@ void eConsoleAppContainer::readyWrite(int what) { outbuf.pop(); delete [] d.data; + if ( filefd[0] == -1 ) /* emit */ dataSent(0); } } 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(); + } } diff --git a/lib/base/console.h b/lib/base/console.h index 3aa180e4..f7cd469c 100644 --- a/lib/base/console.h +++ b/lib/base/console.h @@ -24,6 +24,7 @@ class eConsoleAppContainer: public Object { #ifndef SWIG int fd[3]; + int filefd[3]; int pid; int killstate; std::string m_cwd; @@ -46,8 +47,12 @@ public: void sendCtrlC(); void write( const char *data, int len ); void write( PyObject *data ); + void readFromFile( PyObject *py_filename ); + void dumpToFile( PyObject *py_filename ); bool running() { return (fd[0]!=-1) && (fd[1]!=-1) && (fd[2]!=-1); } PSignal1 dataAvail; + PSignal1 stdoutAvail; + PSignal1 stderrAvail; PSignal1 dataSent; PSignal1 appClosed; }; diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index e7fdd8f7..d5fffbc6 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -160,7 +160,8 @@ class Task(object): from enigma import eConsoleAppContainer self.container = eConsoleAppContainer() self.container.appClosed.get().append(self.processFinished) - self.container.dataAvail.get().append(self.processOutput) + self.container.stdoutAvail.get().append(self.processStdout) + self.container.stderrAvail.get().append(self.processStderr) assert self.cmd is not None assert len(self.args) >= 1 @@ -177,6 +178,12 @@ class Task(object): def cleanup(self, failed): pass + + def processStdout(self, data): + self.processOutput(data) + + def processStderr(self, data): + self.processOutput(data) def processOutput(self, data): self.output_line += data diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 7f141a94..e934885e 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -144,6 +144,8 @@ typedef long time_t; // TODO: embed these... %immutable eConsoleAppContainer::appClosed; %immutable eConsoleAppContainer::dataAvail; +%immutable eConsoleAppContainer::stdoutAvail; +%immutable eConsoleAppContainer::stderrAvail; %immutable eConsoleAppContainer::dataSent; %immutable eButton::selected; %immutable eInput::changed;