diff --git a/util/commandexecutor.cpp b/util/commandexecutor.cpp index 0737d2ca57..2c433fa2ee 100644 --- a/util/commandexecutor.cpp +++ b/util/commandexecutor.cpp @@ -1,123 +1,142 @@ /* This file is part of KDevelop Copyright 2009 Andreas Pakulat 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 "commandexecutor.h" #include "processlinemaker.h" #include #include #include #include +#include namespace KDevelop { class CommandExecutorPrivate { public: CommandExecutorPrivate( CommandExecutor* cmd ) - : m_exec(cmd) + : m_exec(cmd), m_useShell(false) { } CommandExecutor* m_exec; KProcess* m_process; ProcessLineMaker* m_lineMaker; QString m_command; QStringList m_args; QString m_workDir; QMap m_env; + bool m_useShell; void procError( QProcess::ProcessError error ) { Q_UNUSED(error) m_lineMaker->flushBuffers(); emit m_exec->failed(); } void procFinished( int code, QProcess::ExitStatus status ) { Q_UNUSED(code) m_lineMaker->flushBuffers(); if( status == QProcess::NormalExit ) emit m_exec->completed(); } }; CommandExecutor::CommandExecutor( const QString& command, QObject* parent ) : QObject(parent), d(new CommandExecutorPrivate(this)) { d->m_process = new KProcess(this); d->m_process->setOutputChannelMode( KProcess::SeparateChannels ); d->m_lineMaker = new ProcessLineMaker( d->m_process ); d->m_command = command; connect( d->m_lineMaker, SIGNAL(receivedStdoutLines( const QStringList& ) ), this, SIGNAL( receivedStandardOutput( const QStringList& ) ) ); connect( d->m_lineMaker, SIGNAL(receivedStderrLines( const QStringList& ) ), this, SIGNAL( receivedStandardError( const QStringList& ) ) ); connect( d->m_process, SIGNAL( error( QProcess::ProcessError ) ), this, SLOT( procError( QProcess::ProcessError ) ) ); connect( d->m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), this, SLOT( procFinished( int, QProcess::ExitStatus ) ) ); } CommandExecutor::~CommandExecutor() { delete d->m_process; delete d->m_lineMaker; delete d; } void CommandExecutor::setEnvironment( const QMap& env ) { d->m_env = env; } void CommandExecutor::setArguments( const QStringList& args ) { d->m_args = args; } void CommandExecutor::setWorkingDirectory( const QString& dir ) { d->m_workDir = dir; } +bool CommandExecutor::useShell() const +{ + return d->m_useShell; +} + +void CommandExecutor::setUseShell( bool shell ) +{ + d->m_useShell = shell; +} + void CommandExecutor::start() { Q_FOREACH( const QString &s, d->m_env.keys() ) { d->m_process->setEnv( s, d->m_env[s] ); } d->m_process->setWorkingDirectory( d->m_workDir ); - d->m_process->setProgram( d->m_command, d->m_args ); + if( !d->m_useShell ) { + d->m_process->setProgram( d->m_command, d->m_args ); + } else { + QStringList arguments; + Q_FOREACH( const QString &a, d->m_args ) arguments << KShell::quoteArg( a ); + d->m_process->setShellCommand( d->m_command + " " + arguments.join( " " ) ); + } + d->m_process->start(); } void CommandExecutor::setCommand( const QString& command ) { d->m_command = command; } void CommandExecutor::kill() { d->m_process->close(); } } #include "commandexecutor.moc" diff --git a/util/commandexecutor.h b/util/commandexecutor.h index 11a53913ec..0da7336c01 100644 --- a/util/commandexecutor.h +++ b/util/commandexecutor.h @@ -1,101 +1,111 @@ /* This file is part of KDevelop Copyright 2007 Andreas Pakulat 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. */ #ifndef COMMANDEXECUTOR_H #define COMMANDEXECUTOR_H #include #include #include "utilexport.h" namespace KDevelop { /** * Simplifying the exeuction of a Command through (QK)Process. * * This class emits only very basic signals when the process writes something * to stdout or stderr and for signaling completed and failed status. * * If you need more fine-grained control use (QK)Process directly and also * check whether you can use \ref KDevelop::ProcessLineMaker to use properly * terminated lines of output. * * Also this class provides only asynchronous operation, it doesn't allow to * wait for the program to finish. * * @author Andreas Pakulat * TODO: Should this be a KJob?? */ class KDEVPLATFORMUTIL_EXPORT CommandExecutor : public QObject { Q_OBJECT public: /** * Create a command using the given executable, arguments and environment * * The process is not started immediately, instead start() has to be called. */ explicit CommandExecutor( const QString& command, QObject* parent = 0 ); ~CommandExecutor(); /** * set additional arguments to be used when executing the command */ void setArguments( const QStringList& args ); /** * set additional environment variables to be used when executing the command */ void setEnvironment( const QMap& env ); /** * Sets the working directory of the command */ void setWorkingDirectory( const QString& dir ); /** * start the command, after this has been called signals may be emitted */ void start(); /** * kill the process, failed() will likely be emitted */ void kill(); /** * set the Command that should be started, now a commandexecutor can be reused */ void setCommand( const QString& command ); + + /** + * whether the commands are executed from a shell + */ + bool useShell() const; + /** + * if @p shell is true, the command is executed from a shell + */ + void setUseShell( bool shell ); + Q_SIGNALS: void receivedStandardError( const QStringList& ); void receivedStandardOutput( const QStringList& ); void failed(); void completed(); private: Q_PRIVATE_SLOT( d, void procError( QProcess::ProcessError ) ) Q_PRIVATE_SLOT( d, void procFinished( int, QProcess::ExitStatus ) ) class CommandExecutorPrivate* const d; friend class CommandExecutorPrivate; }; } #endif