servicemp3.cpp: more simple/flexible streaming detection
[enigma2.git] / lib / base / console.cpp
index 830855fc9433df0f3604becebea4e1a1f5661493..00187683258be0e8348e1d7ad9e07ff074504915 100644 (file)
@@ -55,8 +55,10 @@ int bidirpipe(int pfd[], const char *cmd , const char * const argv[], const char
        return(pid);
 }
 
+DEFINE_REF(eConsoleAppContainer);
+
 eConsoleAppContainer::eConsoleAppContainer()
-:pid(-1), killstate(0), in(0), out(0), err(0)
+:pid(-1), killstate(0)
 {
        for (int i=0; i < 3; ++i)
        {
@@ -107,14 +109,18 @@ int eConsoleAppContainer::execute(const char *cmdline, const char * const argv[]
 
 //     eDebug("pipe in = %d, out = %d, err = %d", fd[0], fd[1], fd[2]);
 
+       ::fcntl(fd[0], F_SETFL, O_NONBLOCK);
        ::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 );
+       in = eSocketNotifier::create(eApp, fd[0], eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Hungup );
+       out = eSocketNotifier::create(eApp, fd[1], eSocketNotifier::Write, false);  
+       err = eSocketNotifier::create(eApp, fd[2], eSocketNotifier::Read|eSocketNotifier::Priority );
        CONNECT(in->activated, eConsoleAppContainer::readyRead);
        CONNECT(out->activated, eConsoleAppContainer::readyWrite);
        CONNECT(err->activated, eConsoleAppContainer::readyErrRead);
+       in->m_clients.push_back(this);
+       out->m_clients.push_back(this);
+       err->m_clients.push_back(this);
 
        return 0;
 }
@@ -143,10 +149,9 @@ void eConsoleAppContainer::kill()
                outbuf.pop();
                delete [] d.data;
        }
-       delete in;
-       delete out;
-       delete err;
-       in=out=err=0;
+       in = 0;
+       out = 0;
+       err = 0;
 
        for (int i=0; i < 3; ++i)
        {
@@ -209,6 +214,7 @@ void eConsoleAppContainer::closePipes()
                outbuf.pop();
                delete [] d.data;
        }
+       in = 0; out = 0; err = 0;
        pid = -1;
 }
 
@@ -390,23 +396,23 @@ static PyGetSetDef eConsolePy_getseters[] = {
 static int
 eConsolePy_traverse(eConsolePy *self, visitproc visit, void *arg)
 {
-       PyObject *obj = self->cont->dataAvail.get(true);
+       PyObject *obj = self->cont->dataAvail.getSteal();
        if (obj) {
                Py_VISIT(obj);
        }
-       obj = self->cont->stdoutAvail.get(true);
+       obj = self->cont->stdoutAvail.getSteal();
        if (obj) {
                Py_VISIT(obj);
        }
-       obj = self->cont->stderrAvail.get(true);
+       obj = self->cont->stderrAvail.getSteal();
        if (obj) {
                Py_VISIT(obj);
        }
-       obj = self->cont->dataSent.get(true);
+       obj = self->cont->dataSent.getSteal();
        if (obj) {
                Py_VISIT(obj);
        }
-       obj = self->cont->appClosed.get(true);
+       obj = self->cont->appClosed.getSteal();
        if (obj) {
                Py_VISIT(obj);
        }
@@ -416,23 +422,23 @@ eConsolePy_traverse(eConsolePy *self, visitproc visit, void *arg)
 static int
 eConsolePy_clear(eConsolePy *self)
 {
-       PyObject *obj = self->cont->dataAvail.get(true);
+       PyObject *obj = self->cont->dataAvail.getSteal(true);
        if (obj) {
                Py_CLEAR(obj);
        }
-       obj = self->cont->stdoutAvail.get(true);
+       obj = self->cont->stdoutAvail.getSteal(true);
        if (obj) {
                Py_CLEAR(obj);
        }
-       obj = self->cont->stderrAvail.get(true);
+       obj = self->cont->stderrAvail.getSteal(true);
        if (obj) {
                Py_CLEAR(obj);
        }
-       obj = self->cont->dataSent.get(true);
+       obj = self->cont->dataSent.getSteal(true);
        if (obj) {
                Py_CLEAR(obj);
        }
-       obj = self->cont->appClosed.get(true);
+       obj = self->cont->appClosed.getSteal(true);
        if (obj) {
                Py_CLEAR(obj);
        }
@@ -445,7 +451,7 @@ eConsolePy_dealloc(eConsolePy* self)
        if (self->in_weakreflist != NULL)
                PyObject_ClearWeakRefs((PyObject *) self);
        eConsolePy_clear(self);
-       delete self->cont;
+       self->cont->Release();
        self->ob_type->tp_free((PyObject*)self);
 }
 
@@ -454,6 +460,7 @@ eConsolePy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
        eConsolePy *self = (eConsolePy *)type->tp_alloc(type, 0);
        self->cont = new eConsoleAppContainer();
+       self->cont->AddRef();
        self->in_weakreflist = NULL;
        return (PyObject *)self;
 }
@@ -470,11 +477,37 @@ eConsolePy_running(eConsolePy* self)
 static PyObject *
 eConsolePy_execute(eConsolePy* self, PyObject *argt)
 {
-       const char *str;
-       if (PyArg_ParseTuple(argt, "s", &str))
-               return PyInt_FromLong(self->cont->execute(str));
-       PyErr_SetString(PyExc_TypeError,
-               "argument is not a string");
+       Py_ssize_t argc = PyTuple_Size(argt);
+       if (argc > 1)
+       {
+               const char *argv[argc + 1];
+               int argpos=0;
+               while(argpos < argc)
+               {
+                       PyObject *arg = PyTuple_GET_ITEM(argt, argpos);
+                       if (!PyString_Check(arg))
+                       {
+                               char err[255];
+                               if (argpos)
+                                       snprintf(err, 255, "arg %d is not a string", argpos);
+                               else
+                                       snprintf(err, 255, "cmd is not a string!");
+                               PyErr_SetString(PyExc_TypeError, err);
+                               return NULL;
+                       }
+                       argv[argpos++] = PyString_AsString(arg);
+               }
+               argv[argpos] = 0;
+               return PyInt_FromLong(self->cont->execute(argv[0], argv+1));
+       }
+       else
+       {
+               const char *str;
+               if (PyArg_ParseTuple(argt, "s", &str))
+                       return PyInt_FromLong(self->cont->execute(str));
+               PyErr_SetString(PyExc_TypeError,
+                       "cmd is not a string!");
+       }
        return NULL;
 }
 
@@ -483,18 +516,15 @@ eConsolePy_write(eConsolePy* self, PyObject *args)
 {
        int len;
        char *data;
-       if (PyArg_ParseTuple(args, "si", &data, &len))
-               ;
-       else
+       int ret = -1;
+       Py_ssize_t argc = PyTuple_Size(args);
+       if (argc > 1)
+               ret = !PyArg_ParseTuple(args, "si", &data, &len);
+       else if (argc == 1)
        {
                PyObject *ob;
-               if (!PyArg_ParseTuple(args, "O", &ob) || !PyString_Check(ob))
-               {
-                       PyErr_SetString(PyExc_TypeError,
-                               "1st arg must be a string, optionaly 2nd arg can be the string length");
-                       return NULL;
-               }
-               else
+               ret = !PyArg_ParseTuple(args, "O", &ob) || !PyString_Check(ob);
+               if (!ret)
                {
                        Py_ssize_t length;
                        if (!PyString_AsStringAndSize(ob, &data, &length))
@@ -503,6 +533,12 @@ eConsolePy_write(eConsolePy* self, PyObject *args)
                                len = 0;
                }
        }
+       if (ret)
+       {
+               PyErr_SetString(PyExc_TypeError,
+                       "1st arg must be a string, optionaly 2nd arg can be the string length");
+               return NULL;
+       }
        self->cont->write(data, len);
        Py_RETURN_NONE;
 }