|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
#include "kshellcmdexecutor.h"
|
|
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <tqsocketnotifier.h>
|
|
|
|
|
|
|
|
#include <kinputdialog.h>
|
|
|
|
#include <kglobalsettings.h>
|
|
|
|
#include <tdesu/process.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
KShellCommandExecutor::KShellCommandExecutor(const TQString& command, TQWidget* parent)
|
|
|
|
:TQTextView(parent)
|
|
|
|
,m_shellProcess(0)
|
|
|
|
,m_command(command)
|
|
|
|
,m_readNotifier(0)
|
|
|
|
,m_writeNotifier(0)
|
|
|
|
{
|
|
|
|
setTextFormat(PlainText);
|
|
|
|
setFont( KGlobalSettings::fixedFont() );
|
|
|
|
}
|
|
|
|
|
|
|
|
KShellCommandExecutor::~KShellCommandExecutor()
|
|
|
|
{
|
|
|
|
if (m_shellProcess!=0)
|
|
|
|
{
|
|
|
|
::kill(m_shellProcess->pid()+1, SIGTERM);
|
|
|
|
delete m_shellProcess;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
int KShellCommandExecutor::exec()
|
|
|
|
{
|
|
|
|
//kdDebug()<<"---------- KShellCommandExecutor::exec()"<<endl;
|
|
|
|
setText("");
|
|
|
|
if (m_shellProcess!=0)
|
|
|
|
{
|
|
|
|
::kill(m_shellProcess->pid(),SIGTERM);
|
|
|
|
delete m_shellProcess;
|
|
|
|
};
|
|
|
|
if (m_readNotifier!=0)
|
|
|
|
delete m_readNotifier;
|
|
|
|
if (m_writeNotifier!=0)
|
|
|
|
delete m_writeNotifier;
|
|
|
|
|
|
|
|
m_shellProcess=new PtyProcess();
|
|
|
|
m_shellProcess->setTerminal(true);
|
|
|
|
|
|
|
|
QCStringList args;
|
|
|
|
args+="-c";
|
|
|
|
args+=m_command.local8Bit();
|
|
|
|
//kdDebug()<<"------- executing: "<<m_command.local8Bit()<<endl;
|
|
|
|
|
|
|
|
TQCString shell( getenv("SHELL") );
|
|
|
|
if (shell.isEmpty())
|
|
|
|
shell = "sh";
|
|
|
|
|
|
|
|
int ret = m_shellProcess->exec(shell, args);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
//kdDebug()<<"could not execute"<<endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_readNotifier=new TQSocketNotifier(m_shellProcess->fd(),TQSocketNotifier::Read, TQT_TQOBJECT(this));
|
|
|
|
m_writeNotifier=new TQSocketNotifier(m_shellProcess->fd(),TQSocketNotifier::Write, TQT_TQOBJECT(this));
|
|
|
|
m_writeNotifier->setEnabled(false);
|
|
|
|
connect (m_readNotifier, TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this),TQT_SLOT(readDataFromShell()));
|
|
|
|
connect (m_writeNotifier, TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this),TQT_SLOT(writeDataToShell()));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KShellCommandExecutor::readDataFromShell()
|
|
|
|
{
|
|
|
|
//kdDebug()<<"--------- reading ------------"<<endl;
|
|
|
|
char buffer[16*1024];
|
|
|
|
int bytesRead=::read(m_shellProcess->fd(), buffer, 16*1024-1);
|
|
|
|
//0-terminate the buffer
|
|
|
|
//process exited
|
|
|
|
if (bytesRead<=0)
|
|
|
|
{
|
|
|
|
slotFinished();
|
|
|
|
}
|
|
|
|
else if (bytesRead>0)
|
|
|
|
{
|
|
|
|
//kdDebug()<<"***********************\n"<<buffer<<"###################\n"<<endl;
|
|
|
|
buffer[bytesRead]='\0';
|
|
|
|
this->append(TQString::fromLocal8Bit(buffer));
|
|
|
|
setTextFormat(PlainText);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void KShellCommandExecutor::writeDataToShell()
|
|
|
|
{
|
|
|
|
//kdDebug()<<"--------- writing ------------"<<endl;
|
|
|
|
bool ok;
|
|
|
|
TQString str = KInputDialog::getText( TQString::null,
|
|
|
|
i18n( "Input Required:" ), TQString::null, &ok, this );
|
|
|
|
if ( ok )
|
|
|
|
{
|
|
|
|
TQCString input=str.local8Bit();
|
|
|
|
::write(m_shellProcess->fd(),input,input.length());
|
|
|
|
::write(m_shellProcess->fd(),"\n",1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
slotFinished();
|
|
|
|
|
|
|
|
if (m_writeNotifier)
|
|
|
|
{
|
|
|
|
m_writeNotifier->setEnabled(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KShellCommandExecutor::slotFinished()
|
|
|
|
{
|
|
|
|
setTextFormat(PlainText);
|
|
|
|
if (m_shellProcess!=0)
|
|
|
|
{
|
|
|
|
delete m_readNotifier;
|
|
|
|
m_readNotifier = 0;
|
|
|
|
delete m_writeNotifier;
|
|
|
|
m_writeNotifier = 0;
|
|
|
|
|
|
|
|
//kdDebug()<<"slotFinished: pid: "<<m_shellProcess->pid()<<endl;
|
|
|
|
::kill(m_shellProcess->pid()+1, SIGTERM);
|
|
|
|
::kill(m_shellProcess->pid(), SIGTERM);
|
|
|
|
};
|
|
|
|
delete m_shellProcess;
|
|
|
|
m_shellProcess=0;
|
|
|
|
emit finished();
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kshellcmdexecutor.moc"
|