|
|
|
//mdm:
|
|
|
|
// File : class_process.h
|
|
|
|
// Creation date : Thu Feb 1 14:39:48 CEST 2005
|
|
|
|
// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
|
|
|
|
//
|
|
|
|
// This file is part of the KVirc irc client distribution
|
|
|
|
// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
|
|
|
|
//
|
|
|
|
// 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 opinion) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the HOPE that it will be USEFUL,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, write to the Free Software Foundation,
|
|
|
|
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
#include "class_process.h"
|
|
|
|
#include "kvi_error.h"
|
|
|
|
#include "kvi_debug.h"
|
|
|
|
#include "kvi_settings.h"
|
|
|
|
#include "kvi_locale.h"
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#ifdef COMPILE_USE_QT4
|
|
|
|
#include <tq3process.h>
|
|
|
|
#else
|
|
|
|
#include <tqprocess.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
@doc: process
|
|
|
|
@keyterms:
|
|
|
|
process object class, process
|
|
|
|
@title:
|
|
|
|
process class
|
|
|
|
@type:
|
|
|
|
class
|
|
|
|
@short:
|
|
|
|
A class to manage process.
|
|
|
|
@inherits:
|
|
|
|
[class]object[/class]
|
|
|
|
@description:
|
|
|
|
The Process class is used to start external programs and to communicate with them.[br]
|
|
|
|
!WARNING AT LAST YOU HAVE TO CLOSE THE PROCESS!
|
|
|
|
@functions:
|
|
|
|
!fn: $addArg(<process-name:string>)
|
|
|
|
With this command you give the process name (or more arguments) for comunication.
|
|
|
|
Es: see the next example.
|
|
|
|
!fn: $start()
|
|
|
|
Tries to run the process.[br]
|
|
|
|
Es: [br]
|
|
|
|
%process=$new(process);[br]
|
|
|
|
%process->$addArg("cmd.exe");[br]
|
|
|
|
%process->$start();[br]
|
|
|
|
!fn: <string> $readStdout()
|
|
|
|
Reads the data that the process has written to standard output.
|
|
|
|
!fn: <string> $readStderr()
|
|
|
|
Reads the data that the process has written to standard error.
|
|
|
|
Es:[br]
|
|
|
|
-------------------Start:[br]
|
|
|
|
class (test,object)[br]
|
|
|
|
{[br]
|
|
|
|
slotReadStdout()[br]
|
|
|
|
{[br]
|
|
|
|
%stdo = %Process->$readStdout()[br]
|
|
|
|
#%Aoutput->$append(%stdo);// coming soon in the new texteditor class[br]
|
|
|
|
%Aoutput->$settext(%stdo);[br]
|
|
|
|
}[br]
|
|
|
|
slotReadStderr()[br]
|
|
|
|
{[br]
|
|
|
|
%stderr= %Process->$readStderr()[br]
|
|
|
|
#%Aoutput->$append(%stderr);// coming soon in the new texteditor class[br]
|
|
|
|
%Aoutput->$settext(%stderr);[br]
|
|
|
|
}[br]
|
|
|
|
}[br]
|
|
|
|
|
|
|
|
%tt=$new(test)[br]
|
|
|
|
%A=$new(widget)[br]
|
|
|
|
%A->$setGeometry(100,100,400,300)[br]
|
|
|
|
%tqlayoutA=$new(tqlayout,%A)[br]
|
|
|
|
%Ainput=$new(lineedit,%A)[br]
|
|
|
|
#%Aoutput=$new(textedit,%A)// coming soon in the new texteditor class[br]
|
|
|
|
%Aoutput=$new(label,%A)[br]
|
|
|
|
%bclosekill=$new(button,%A)[br]
|
|
|
|
%bclosekill->$settext("&CloseKill ")[br]
|
|
|
|
%bkill=$new(button,%A)[br]
|
|
|
|
%bkill->$settext("&Kill ")[br]
|
|
|
|
%bterminate=$new(button,%A)[br]
|
|
|
|
%bterminate->$settext("&Ask to Terminate ")[br]
|
|
|
|
%tqlayoutA->$addwidget(%Ainput,0,0)[br]
|
|
|
|
%tqlayoutA->$addwidget(%Aoutput,1,0)[br]
|
|
|
|
%tqlayoutA->$addwidget(%bclosekill,3,0)[br]
|
|
|
|
%tqlayoutA->$addwidget(%bkill,4,0,)[br]
|
|
|
|
%tqlayoutA->$addwidget(%bterminate,5,0)[br]
|
|
|
|
|
|
|
|
%Process=$new(process)[br]
|
|
|
|
%Process->$addArg("cmd.exe")[br]
|
|
|
|
%Process->$start();[br]
|
|
|
|
|
|
|
|
connect %Process readyReadStdout %tt slotReadStdout[br]
|
|
|
|
connect %Process readyReadStderr %tt slotReadStderr[br]
|
|
|
|
privateimpl(%Ainput,returnPressedEvent)[br]
|
|
|
|
{
|
|
|
|
%command=%Ainput->$text() "\r\n"[br]
|
|
|
|
%Process->$writeToStdin(%command);[br]
|
|
|
|
%Ainput->$setText("");[br]
|
|
|
|
}[br]
|
|
|
|
|
|
|
|
privateimpl(%bclosekill,mousepressevent)[br]
|
|
|
|
{[br]
|
|
|
|
%Process->$closekill();[br]
|
|
|
|
delete %A;[br]
|
|
|
|
}[br]
|
|
|
|
privateimpl(%bkill,mousepressevent)[br]
|
|
|
|
{[br]
|
|
|
|
%Process->$kill();[br]
|
|
|
|
delete %A;[br]
|
|
|
|
}[br]
|
|
|
|
privateimpl(%bterminate,mousepressevent)[br]
|
|
|
|
{[br]
|
|
|
|
%Process->$tryTerminate();[br]
|
|
|
|
delete %A;[br]
|
|
|
|
}[br]
|
|
|
|
%A->$show();[br]
|
|
|
|
--------------------End.[br]
|
|
|
|
!fn: $writeToStdin(<command:string>)
|
|
|
|
Whit this command you send a command to the process:
|
|
|
|
!fn: $closekill()
|
|
|
|
This tries to terminate the process the nice way.[br]
|
|
|
|
If the process is still running after 5 seconds, it terminates the process the hard way.[br]
|
|
|
|
(I think that this is the better way.)[br]
|
|
|
|
Es:
|
|
|
|
%Process->close_kill();
|
|
|
|
!fn: $kill()
|
|
|
|
Kill the process in hard way.(Bad Idea)
|
|
|
|
!fn: $tryTerminate()
|
|
|
|
Tries to terminate the process.(It could be well but...)
|
|
|
|
!fn: $closeStdin()
|
|
|
|
Close the standard Input.
|
|
|
|
!fn: <boolean> $isRunning()
|
|
|
|
Return 1 if the process is running, else return 0.
|
|
|
|
!fn: <boolean> $normalExit()
|
|
|
|
Returns TRUE if the process has exited normally; otherwise returns FALSE.
|
|
|
|
!fn: $readyReadStdoutEvent()
|
|
|
|
This function is invoched by the process when there are new datas.[br]
|
|
|
|
The default implementation emits the [classfnc]$readyReadStdout[/classfnc]() signal.
|
|
|
|
!fn: $readyReadStderrEvent()
|
|
|
|
This function is invoched by the process when there are new error messages.[br]
|
|
|
|
The default implementation emits the [classfnc]$readyReadStderr[/classfnc]() signal.
|
|
|
|
|
|
|
|
@signals:
|
|
|
|
!sg: $readyReadStdout()
|
|
|
|
This signal is emitted by the default implementation of [classfnc]$readyReadStdoutEvent[/classfnc]().[br]
|
|
|
|
If you reimplement that function you will have to emit the signal manually (if you still need it).
|
|
|
|
!sg: $readyReadStderr()
|
|
|
|
This signal is emitted by the default implementation of [classfnc]$readyReadStderrEvent[/classfnc]().
|
|
|
|
*/
|
|
|
|
|
|
|
|
KVSO_BEGIN_REGISTERCLASS(KviKvsObject_process,"process","object")
|
|
|
|
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"addArg", functionaddArgument);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"start", functionstartProcess);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"readStdout", functionreadStdout);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"readStderr", functionreadStderr);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"writeToStdin", functionwriteToStdin);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"closekill", functionclosekill);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"kill", functionkill);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"tryTerminate", functiontryTerminate);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"closeStdin", functioncloseStdin);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"isRunning",functionisRunning);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"normalExit",functionnormalExit);
|
|
|
|
|
|
|
|
// Events
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"readyReadStdoutEvent",functionreadyReadStdoutEvent);
|
|
|
|
KVSO_REGISTER_HANDLER(KviKvsObject_process,"readyReadStderrEvent",functionreadyReadStderrEvent);
|
|
|
|
|
|
|
|
KVSO_END_REGISTERCLASS(KviKvsObject_process)
|
|
|
|
|
|
|
|
|
|
|
|
KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_process,KviKvsObject)
|
|
|
|
|
|
|
|
#ifdef COMPILE_USE_QT4
|
|
|
|
m_pProcess = new Q3Process();
|
|
|
|
#else
|
|
|
|
m_pProcess = new TQProcess();
|
|
|
|
#endif
|
|
|
|
connect(m_pProcess,TQT_SIGNAL(readyReadStdout()),this,TQT_SLOT(slotReadStdout()));
|
|
|
|
connect(m_pProcess,TQT_SIGNAL(readyReadStderr()),this,TQT_SLOT(slotReadStderr()));
|
|
|
|
|
|
|
|
KVSO_END_CONSTRUCTOR(KviKvsObject_process)
|
|
|
|
|
|
|
|
KVSO_BEGIN_DESTRUCTOR(KviKvsObject_process)
|
|
|
|
|
|
|
|
delete m_pProcess;
|
|
|
|
|
|
|
|
KVSO_END_CONSTRUCTOR(KviKvsObject_process)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool KviKvsObject_process::functionaddArgument(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString szArgument;
|
|
|
|
KVSO_PARAMETERS_BEGIN(c)
|
|
|
|
KVSO_PARAMETER("argument",KVS_PT_NONEMPTYSTRING,0,szArgument)
|
|
|
|
KVSO_PARAMETERS_END(c)
|
|
|
|
if (m_pProcess) m_pProcess->addArgument(szArgument);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//->Start the process.
|
|
|
|
bool KviKvsObject_process::functionstartProcess(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
|
|
|
|
if(!(m_pProcess->start()))
|
|
|
|
c->warning( __tr2qs("Process could not be starded."));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//-->Read the standard output.
|
|
|
|
bool KviKvsObject_process::functionreadStderr(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
TQString ng_Process =m_pProcess->readStderr();
|
|
|
|
c->returnValue()->setString(ng_Process);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-->Read the standard error.
|
|
|
|
bool KviKvsObject_process::functionreadStdout(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
TQString ng_Process =m_pProcess->readStdout();
|
|
|
|
c->returnValue()->setString(ng_Process);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//-->Signals and slot to manage reading output and error from the process.
|
|
|
|
bool KviKvsObject_process::functionreadyReadStdoutEvent(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
|
|
|
|
emitSignal("readyReadStdout",c);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviKvsObject_process::functionreadyReadStderrEvent(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
|
|
|
|
emitSignal("readyReadStderr",c);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
bool KviKvsObject_process::functionwriteToStdin(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString szCommand;
|
|
|
|
KVSO_PARAMETERS_BEGIN(c)
|
|
|
|
KVSO_PARAMETER("command",KVS_PT_STRING,0,szCommand)
|
|
|
|
KVSO_PARAMETERS_END(c)
|
|
|
|
if (m_pProcess) m_pProcess->writeToStdin(szCommand);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//-->The 3 Closing process functions
|
|
|
|
bool KviKvsObject_process::functionclosekill(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
//I try to to terminate the process the nice way....
|
|
|
|
m_pProcess->tryTerminate();
|
|
|
|
//If the process is still running after 5 seconds, I'll terminate the process in the hard way.
|
|
|
|
TQTimer::singleShot( 5000, m_pProcess, TQT_SLOT( kill() ) );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool KviKvsObject_process::functionkill(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
m_pProcess->kill();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool KviKvsObject_process::functiontryTerminate(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
m_pProcess->tryTerminate();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//-->Close the standard input.
|
|
|
|
bool KviKvsObject_process::functioncloseStdin(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pProcess->closeStdin();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//->Returns if the process still runnig
|
|
|
|
bool KviKvsObject_process::functionisRunning(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
c->returnValue()->setBoolean(m_pProcess->isRunning());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//->Returns if the process exited.
|
|
|
|
bool KviKvsObject_process::functionnormalExit(KviKvsObjectFunctionCall *c)
|
|
|
|
{
|
|
|
|
c->returnValue()->setBoolean(m_pProcess->normalExit());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviKvsObject_process::slotReadStdout()
|
|
|
|
{
|
|
|
|
KviKvsVariantList *params=0;
|
|
|
|
callFunction(this,"readyReadStdoutEvent",params);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviKvsObject_process::slotReadStderr()
|
|
|
|
{
|
|
|
|
KviKvsVariantList *params=0;
|
|
|
|
callFunction(this,"readyReadStderrEvent",params);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "m_class_process.moc"
|