Changeset View
Changeset View
Standalone View
Standalone View
outputview/outputexecutejob.cpp
Show All 15 Lines | |||||
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | Boston, MA 02110-1301, USA. | 17 | Boston, MA 02110-1301, USA. | ||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include "outputexecutejob.h" | 20 | #include "outputexecutejob.h" | ||
21 | #include "outputmodel.h" | 21 | #include "outputmodel.h" | ||
22 | #include "outputdelegate.h" | 22 | #include "outputdelegate.h" | ||
23 | #include "debug.h" | 23 | #include "debug.h" | ||
24 | #include <interfaces/icore.h> | ||||
25 | #include <interfaces/iruntime.h> | ||||
26 | #include <interfaces/iruntimecontroller.h> | ||||
24 | #include <util/environmentprofilelist.h> | 27 | #include <util/environmentprofilelist.h> | ||
25 | #include <util/processlinemaker.h> | 28 | #include <util/processlinemaker.h> | ||
26 | #include <KProcess> | 29 | #include <KProcess> | ||
27 | #include <KLocalizedString> | 30 | #include <KLocalizedString> | ||
28 | #include <KShell> | 31 | #include <KShell> | ||
29 | #include <QFileInfo> | 32 | #include <QFileInfo> | ||
30 | #include <QDir> | 33 | #include <QDir> | ||
31 | 34 | | |||
Show All 28 Lines | 40 | public: | |||
60 | QScopedPointer<IFilterStrategy> m_filteringStrategyPtr; | 63 | QScopedPointer<IFilterStrategy> m_filteringStrategyPtr; | ||
61 | QStringList m_arguments; | 64 | QStringList m_arguments; | ||
62 | QStringList m_privilegedExecutionCommand; | 65 | QStringList m_privilegedExecutionCommand; | ||
63 | QUrl m_workingDirectory; | 66 | QUrl m_workingDirectory; | ||
64 | QString m_environmentProfile; | 67 | QString m_environmentProfile; | ||
65 | QHash<QString, QString> m_environmentOverrides; | 68 | QHash<QString, QString> m_environmentOverrides; | ||
66 | QString m_jobName; | 69 | QString m_jobName; | ||
67 | bool m_outputStarted; | 70 | bool m_outputStarted; | ||
71 | bool m_executeOnHost = false; | ||||
68 | }; | 72 | }; | ||
69 | 73 | | |||
70 | OutputExecuteJobPrivate::OutputExecuteJobPrivate( OutputExecuteJob* owner ) : | 74 | OutputExecuteJobPrivate::OutputExecuteJobPrivate( OutputExecuteJob* owner ) : | ||
71 | m_owner( owner ), | 75 | m_owner( owner ), | ||
72 | m_process( new KProcess( m_owner ) ), | 76 | m_process( new KProcess( m_owner ) ), | ||
73 | m_lineMaker( new ProcessLineMaker( m_owner ) ), // do not assign process to the line maker as we'll feed it data ourselves | 77 | m_lineMaker( new ProcessLineMaker( m_owner ) ), // do not assign process to the line maker as we'll feed it data ourselves | ||
74 | m_status( OutputExecuteJob::JobNotStarted ), | 78 | m_status( OutputExecuteJob::JobNotStarted ), | ||
75 | m_properties( OutputExecuteJob::DisplayStdout ), | 79 | m_properties( OutputExecuteJob::DisplayStdout ), | ||
Show All 21 Lines | |||||
97 | OutputExecuteJob::~OutputExecuteJob() | 101 | OutputExecuteJob::~OutputExecuteJob() | ||
98 | { | 102 | { | ||
99 | // indicates if process is running and survives kill, then we cannot do anything | 103 | // indicates if process is running and survives kill, then we cannot do anything | ||
100 | bool killSuccessful = d->m_process->state() == QProcess::NotRunning; | 104 | bool killSuccessful = d->m_process->state() == QProcess::NotRunning; | ||
101 | if( !killSuccessful ) { | 105 | if( !killSuccessful ) { | ||
102 | killSuccessful = doKill(); | 106 | killSuccessful = doKill(); | ||
103 | } | 107 | } | ||
104 | 108 | | |||
105 | Q_ASSERT( d->m_process->state() == QProcess::NotRunning || !killSuccessful ); | 109 | Q_ASSERT( d->m_process->state() != QProcess::Running || !killSuccessful ); | ||
mwolff: out of interest: why is this required? what state is the process in? | |||||
I'll revert it and debug again, I don't remember why I added it anymore. apol: I'll revert it and debug again, I don't remember why I added it anymore. | |||||
106 | delete d; | 110 | delete d; | ||
107 | } | 111 | } | ||
108 | 112 | | |||
109 | OutputExecuteJob::JobStatus OutputExecuteJob::status() const | 113 | OutputExecuteJob::JobStatus OutputExecuteJob::status() const | ||
110 | { | 114 | { | ||
111 | return d->m_status; | 115 | return d->m_status; | ||
112 | } | 116 | } | ||
113 | 117 | | |||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Line(s) | 169 | { | |||
272 | } | 276 | } | ||
273 | 277 | | |||
274 | d->m_process->setProcessEnvironment( d->effectiveEnvironment(effectiveWorkingDirectory) ); | 278 | d->m_process->setProcessEnvironment( d->effectiveEnvironment(effectiveWorkingDirectory) ); | ||
275 | 279 | | |||
276 | if (!d->effectiveCommandLine().isEmpty()) { | 280 | if (!d->effectiveCommandLine().isEmpty()) { | ||
277 | d->m_process->setProgram( d->effectiveCommandLine() ); | 281 | d->m_process->setProgram( d->effectiveCommandLine() ); | ||
278 | // there is no way to input data in the output view so redirect stdin to the null device | 282 | // there is no way to input data in the output view so redirect stdin to the null device | ||
279 | d->m_process->setStandardInputFile(QProcess::nullDevice()); | 283 | d->m_process->setStandardInputFile(QProcess::nullDevice()); | ||
280 | qCDebug(OUTPUTVIEW) << "Starting:" << d->m_process->program().join(QStringLiteral(" ")) << "in" << d->m_process->workingDirectory(); | 284 | qCDebug(OUTPUTVIEW) << "Starting:" << d->effectiveCommandLine() << d->m_process->QProcess::program() << "in" << d->m_process->workingDirectory(); | ||
285 | if (d->m_executeOnHost) { | ||||
281 | d->m_process->start(); | 286 | d->m_process->start(); | ||
282 | } else { | 287 | } else { | ||
288 | KDevelop::ICore::self()->runtimeController()->currentRuntime()->startProcess(d->m_process); | ||||
289 | } | ||||
290 | } else { | ||||
283 | QString errorMessage = i18n("Failed to specify program to start"); | 291 | QString errorMessage = i18n("Failed to specify program to start"); | ||
284 | model()->appendLine( i18n( "*** %1 ***", errorMessage) ); | 292 | model()->appendLine( i18n( "*** %1 ***", errorMessage) ); | ||
285 | setErrorText(errorMessage); | 293 | setErrorText(errorMessage); | ||
286 | setError( FailedShownError ); | 294 | setError( FailedShownError ); | ||
287 | emitResult(); | 295 | emitResult(); | ||
288 | return; | 296 | return; | ||
289 | } | 297 | } | ||
290 | } | 298 | } | ||
291 | 299 | | |||
292 | bool OutputExecuteJob::doKill() | 300 | bool OutputExecuteJob::doKill() | ||
293 | { | 301 | { | ||
294 | const int terminateKillTimeout = 1000; // msecs | 302 | const int terminateKillTimeout = 1000; // msecs | ||
295 | 303 | | |||
296 | if( d->m_status != JobRunning ) { | 304 | if( d->m_status != JobRunning ) { | ||
297 | return true; | 305 | return true; | ||
298 | } | 306 | } | ||
307 | | ||||
mwolff: unrelated | |||||
299 | d->m_status = JobCanceled; | 308 | d->m_status = JobCanceled; | ||
300 | 309 | | |||
301 | d->m_process->terminate(); | 310 | d->m_process->terminate(); | ||
302 | bool terminated = d->m_process->waitForFinished( terminateKillTimeout ); | 311 | bool terminated = d->m_process->waitForFinished( terminateKillTimeout ); | ||
303 | if( !terminated ) { | 312 | if( !terminated ) { | ||
304 | d->m_process->kill(); | 313 | d->m_process->kill(); | ||
305 | terminated = d->m_process->waitForFinished( terminateKillTimeout ); | 314 | terminated = d->m_process->waitForFinished( terminateKillTimeout ); | ||
306 | } | 315 | } | ||
▲ Show 20 Lines • Show All 161 Lines • ▼ Show 20 Line(s) | 476 | { | |||
468 | d->m_environmentOverrides[name] = value; | 477 | d->m_environmentOverrides[name] = value; | ||
469 | } | 478 | } | ||
470 | 479 | | |||
471 | void OutputExecuteJob::removeEnvironmentOverride( const QString& name ) | 480 | void OutputExecuteJob::removeEnvironmentOverride( const QString& name ) | ||
472 | { | 481 | { | ||
473 | d->m_environmentOverrides.remove( name ); | 482 | d->m_environmentOverrides.remove( name ); | ||
474 | } | 483 | } | ||
475 | 484 | | |||
485 | | ||||
486 | void OutputExecuteJob::setExecuteOnHost(bool executeHost) | ||||
487 | { | ||||
488 | d->m_executeOnHost = executeHost; | ||||
489 | } | ||||
490 | | ||||
491 | bool OutputExecuteJob::executeOnHost() const | ||||
492 | { | ||||
493 | return d->m_executeOnHost; | ||||
494 | } | ||||
495 | | ||||
476 | template< typename T > | 496 | template< typename T > | ||
477 | void OutputExecuteJobPrivate::mergeEnvironment( QProcessEnvironment& dest, const T& src ) | 497 | void OutputExecuteJobPrivate::mergeEnvironment( QProcessEnvironment& dest, const T& src ) | ||
478 | { | 498 | { | ||
479 | for( typename T::const_iterator it = src.begin(); it != src.end(); ++it ) { | 499 | for( typename T::const_iterator it = src.begin(); it != src.end(); ++it ) { | ||
480 | dest.insert( it.key(), it.value() ); | 500 | dest.insert( it.key(), it.value() ); | ||
481 | } | 501 | } | ||
482 | } | 502 | } | ||
483 | 503 | | |||
▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines |
out of interest: why is this required? what state is the process in?