You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
piklab/src/common/global/process.cpp

194 lines
5.5 KiB

/***************************************************************************
* Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
* *
* 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 <tqdatetime.h>
#if defined(NO_KDE)
# include "common/nokde/nokde_kprocess.h"
#else
# include <kprocess.h>
#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<TQCString> &args = _process->args();
for (uint i=0; i<args.count(); i++) list.append(args[i]);
return list;
#endif
}
void Process::Base::setup(const TQString &executable, const TQStringList &options, bool withWine)
{
_state = Stopped;
_timer->stop();
_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; i<uint(len); i++) {
if ( data[i]=='\r' ) continue;
if ( data[i]=='\n' ) {
if ( !isFilteredLine(_stdout) ) addStdoutLine(_stdout);
_stdout = TQString();
} else _stdout += TQString::tqfromLatin1(data + i, 1);
}
if ( !_process->isRunning() && !isFilteredLine(_stdout) ) addStdoutLine(_stdout);
emit stdoutDataReceived();
}
void Process::LineBase::receivedStderr(KProcess*, char *data, int len)
{
for (uint i=0; i<uint(len); i++) {
if ( data[i]=='\r' ) continue;
if ( data[i]=='\n' ) {
if ( !isFilteredLine(_stderr) ) addStderrLine(_stderr);
_stderr = TQString();
} else _stderr += TQString::tqfromLatin1(data + i, 1);
}
if ( !_process->isRunning() && !isFilteredLine(_stderr) ) addStderrLine(_stderr);
emit stderrDataReceived();
}
//----------------------------------------------------------------------------
bool Process::LineOutput::start(uint timeout)
{
_stdoutLines.clear();
_stderrLines.clear();
return Process::LineBase::start(timeout);
}