/*************************************************************************** * Copyright (C) 2005 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "process.h" #include #if defined(NO_KDE) # include "common/nokde/nokde_kprocess.h" #else # include #endif #include "purl.h" #include "common/common/synchronous.h" //---------------------------------------------------------------------------- Process::State Process::runSynchronously(Base &process, RunActions actions, uint timeout) { Synchronous sync(timeout); TQObject::connect(&process, TQT_SIGNAL(done(int)), &sync, TQT_SLOT(done())); TQObject::connect(&process, TQT_SIGNAL(requestSynchronousStop()), &sync, TQT_SLOT(done())); if ( (actions & Start) && !process.start(0) ) return process.state(); Q_ASSERT( process.isRunning() ); if ( !sync.enterLoop() ) process.timeoutSlot(); return process.state(); } //---------------------------------------------------------------------------- Process::Base::Base(TQObject *parent, const char *name) : TQObject(parent, name), _state(Stopped) { _process = new KProcess(this); connect(_process, TQT_SIGNAL(processExited(KProcess *)), TQT_SLOT(exited())); connect(_process, TQT_SIGNAL(receivedStdout(KProcess *, char *, int)), TQT_SLOT(receivedStdout(KProcess*, char *, int))); connect(_process, TQT_SIGNAL(receivedStderr(KProcess *, char *, int)), TQT_SLOT(receivedStderr(KProcess*, char *, int))); _timer = new TQTimer(this); connect(_timer, TQT_SIGNAL(timeout()), TQT_SLOT(timeoutSlot())); } Process::Base::~Base() { _process->kill(); } TQStringList Process::Base::arguments() const { if ( _process==0 ) return TQStringList(); #if defined(NO_KDE) return _process->args(); #else TQStringList list; const TQValueList &args = _process->args(); for (uint i=0; istop(); _process->clearArguments(); if (withWine) { _process->setEnvironment("WINEDEBUG", "-all"); *_process << TQString("wine"); } *_process << executable; *_process << options; } bool Process::Base::start(uint timeout) { _state = Stopped; _timer->stop(); _stdout = TQString(); _stderr = TQString(); #if defined(NO_KDE) if ( !_process->start() ) { #else if ( !_process->start(KProcess::NotifyOnExit, KProcess::All) ) { #endif _state = StartFailed; return false; } _state = Running; if (timeout) _timer->start(timeout); return true; } void Process::Base::timeoutSlot() { _state = Timedout; _process->kill(); emit timeout(); } int Process::Base::exitCode() const { return _process->exitStatus(); } void Process::Base::exited() { _state = Exited; _timer->stop(); emit done(exitCode()); } bool Process::Base::isRunning() const { return _process->isRunning(); } void Process::Base::writeToStdin(const TQString &s) { TQCString cs = s.latin1(); _process->writeStdin(cs.data(), cs.length()); } bool Process::Base::signal(int n) { return _process->kill(n); } void Process::Base::setWorkingDirectory(const PURL::Directory &dir) { _process->setWorkingDirectory(dir.path()); } void Process::Base::setUseShell(bool useShell) { _process->setUseShell(useShell); } bool Process::Base::isFilteredLine(const TQString &line) { // "wine" returns all those "libGL warning" that mess up the output... return line.startsWith("libGL warning"); } //---------------------------------------------------------------------------- void Process::StringOutput::receivedStdout(KProcess*, char *data, int len) { _stdout += TQString::tqfromLatin1(data, len); emit stdoutDataReceived(); } void Process::StringOutput::receivedStderr(KProcess*, char *data, int len) { _stderr += TQString::tqfromLatin1(data, len); emit stderrDataReceived(); } //---------------------------------------------------------------------------- void Process::LineBase::receivedStdout(KProcess*, char *data, int len) { for (uint i=0; iisRunning() && !isFilteredLine(_stdout) ) addStdoutLine(_stdout); emit stdoutDataReceived(); } void Process::LineBase::receivedStderr(KProcess*, char *data, int len) { for (uint i=0; iisRunning() && !isFilteredLine(_stderr) ) addStderrLine(_stderr); emit stderrDataReceived(); } //---------------------------------------------------------------------------- bool Process::LineOutput::start(uint timeout) { _stdoutLines.clear(); _stderrLines.clear(); return Process::LineBase::start(timeout); }