diff --git a/src/Session.cpp b/src/Session.cpp index 2111c1ec..e02d020b 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -263,17 +263,14 @@ void Session::removeView(TerminalDisplay* widget) } } -void Session::run() +QString Session::checkProgram(const QString& program) const { - //check that everything is in place to run the session - if (_program.isEmpty()) - kDebug() << "Session::run() - program to run not set."; - if (_arguments.isEmpty()) - kDebug() << "Session::run() - no command line arguments specified."; - // Upon a KPty error, there is no description on what that error was... // Check to see if the given program is executable. - QString exec = QFile::encodeName(_program); + QString exec = QFile::encodeName(program); + + if (exec.isEmpty()) + return QString(); // if 'exec' is not specified, fall back to default shell. if that // is not set then fall back to /bin/sh @@ -282,20 +279,68 @@ void Session::run() if ( exec.isEmpty() ) exec = "/bin/sh"; - // if no arguments are specified, fall back to shell - QStringList arguments = _arguments.join(QChar(' ')).isEmpty() ? - QStringList() << exec : _arguments; - - exec = KRun::binaryName(exec, false); exec = KShell::tildeExpand(exec); QString pexec = KGlobal::dirs()->findExe(exec); - if ( pexec.isEmpty() ) { - kError()<<"can not execute "<receiveData(redPenOn,strlen(redPenOn)); + _emulation->receiveData("\n\r\n\r",4); + _emulation->receiveData(warningText.constData(),strlen(warningText.constData())); + _emulation->receiveData(messageText.constData(),strlen(messageText.constData())); + _emulation->receiveData("\n\r\n\r",4); + _emulation->receiveData(redPenOff,strlen(redPenOff)); +} +void Session::run() +{ + //check that everything is in place to run the session + if (_program.isEmpty()) + kDebug() << "Session::run() - program to run not set."; + if (_arguments.isEmpty()) + kDebug() << "Session::run() - no command line arguments specified."; + + const int CHOICE_COUNT = 3; + QString programs[CHOICE_COUNT] = {_program,getenv("SHELL"),"/bin/sh"}; + QString exec; + int choice = 0; + while (choice < CHOICE_COUNT) + { + exec = checkProgram(programs[choice]); + if (exec.isEmpty()) + choice++; + else + break; } + if (choice != 0 && choice < CHOICE_COUNT && !_program.isEmpty()) + { + terminalWarning(i18n("Could not find '%1', starting '%2' instead. Please check your profile settings.",_program,exec)); + } + else if (choice == CHOICE_COUNT) + { + terminalWarning(i18n("Could not find an interactive shell to start.")); + return; + } + + // if no arguments are specified, fall back to program name + QStringList arguments = _arguments.join(QChar(' ')).isEmpty() ? + QStringList() << exec : _arguments; + QString dbusService = QDBusConnection::sessionBus().baseService(); QString cwd_save = QDir::currentPath(); if (!_initialWorkingDir.isEmpty()) @@ -323,6 +368,7 @@ void Session::run() if (result < 0) { + terminalWarning(i18n("Could not start program '%1' with arguments '%2'.")); return; } @@ -592,22 +638,24 @@ void Session::done(int exitStatus) return; } + QString message; if (!_wantedClose || exitStatus != 0) { - QString message; - if (_shellProcess->exitStatus() == QProcess::NormalExit) message = i18n("Program '%1' exited with status %2.", _shellProcess->program().first(), exitStatus); else - message = i18n("Program '%1' exited unexpectedly.", _shellProcess->program().first()); + message = i18n("Program '%1' crashed.", _shellProcess->program().first()); //FIXME: See comments in Session::monitorTimerDone() KNotification::event("Finished", message , QPixmap(), QApplication::activeWindow(), KNotification::CloseWhenWidgetActivated); } - - emit finished(); + + if ( exitStatus != 0 || _shellProcess->exitStatus() != QProcess::NormalExit ) + terminalWarning(message); + else + emit finished(); } Emulation* Session::emulation() const diff --git a/src/Session.h b/src/Session.h index e17483ff..d512c76d 100644 --- a/src/Session.h +++ b/src/Session.h @@ -509,6 +509,13 @@ private: void updateTerminalSize(); WId windowId() const; bool kill(int signal); + // print a warning message in the terminal. This is used + // if the program fails to start, or if the shell exits in + // an unsuccessful manner + void terminalWarning(const QString& message); + // checks that the binary 'program' is available and can be executed + // returns the binary name if available or an empty string otherwise + QString checkProgram(const QString& program) const; int _uniqueIdentifier;