Commit 757101c6 authored by Robert Knight's avatar Robert Knight

If reading the current working directory of a process fails (eg. when running...

If reading the current working directory of a process fails (eg. when running a 'sudo' command) when preparing a tab title then fall back to the parent process's current working directory.  Add basic error reporting to ProcessInfo.

svn path=/trunk/KDE/kdebase/apps/konsole/; revision=699000
parent c5a24369
......@@ -28,7 +28,6 @@
// Qt
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QRegExp>
#include <QtCore/QTextStream>
......@@ -53,9 +52,13 @@ ProcessInfo::ProcessInfo(int pid , bool enableEnvironmentRead)
, _pid(pid)
, _parentPid(0)
, _foregroundPid(0)
, _lastError(NoError)
{
}
ProcessInfo::Error ProcessInfo::error() const { return _lastError; }
void ProcessInfo::setError(Error error) { _lastError = error; }
void ProcessInfo::update()
{
readProcessInfo(_pid,_enableEnvironmentRead);
......@@ -67,13 +70,27 @@ QString ProcessInfo::format(const QString& input) const
QString output(input);
// search for and replace known markers
// search for and replace known marker
output.replace("%u","NOT IMPLEMENTED YET");
output.replace("%n",name(&ok));
output.replace("%c",formatCommand(name(&ok),arguments(&ok),ShortCommandFormat));
output.replace("%C",formatCommand(name(&ok),arguments(&ok),LongCommandFormat));
output.replace("%D",currentDir(&ok));
output.replace("%d",formatShortDir(currentDir(&ok)));
// read current dir, if an error occurs try the parent as the next
// best option
int currentPid = parentPid(&ok);
QString dir = currentDir(&ok);
while ( !ok && currentPid != 0 )
{
ProcessInfo* current = ProcessInfo::newInstance(currentPid);
current->update();
currentPid = current->parentPid(&ok);
dir = current->currentDir(&ok);
delete current;
}
output.replace("%D",dir);
output.replace("%d",formatShortDir(dir));
// remove any remaining %[LETTER] sequences
// output.replace(QRegExp("%\\w"),QString::null);
......@@ -303,38 +320,52 @@ bool UnixProcessInfo::readProcessInfo(int pid , bool enableEnvironmentRead)
}
else
{
qDebug() << __FUNCTION__ << "failed to open stat file";
setFileError( processInfo.error() );
return false;
}
// check that data was read successfully
bool ok = false;
int foregroundPid = foregroundPidString.toInt(&ok);
if (!ok) return false;
if (ok)
setForegroundPid(foregroundPid);
int parentPid = parentPidString.toInt(&ok);
if (!ok) return false;
if (ok)
setParentPid(parentPid);
if (processNameString.isEmpty()) return false;
if (!processNameString.isEmpty())
setName(processNameString);
if (!readArguments(pid)) return false;
if (!readCurrentDir(pid)) return false;
readArguments(pid);
readCurrentDir(pid);
if ( enableEnvironmentRead )
{
if (!readEnvironment(pid)) return false;
readEnvironment(pid);
}
// update object state
setPid(pid);
setName(processNameString);
setForegroundPid(foregroundPid);
setParentPid(parentPid);
return true;
}
void ProcessInfo::setFileError( QFile::FileError error )
{
switch ( error )
{
case PermissionsError:
setError( PermissionsError );
break;
case NoError:
setError( NoError );
break;
default:
setError( UnknownError );
}
}
ProcessInfo* ProcessInfo::newInstance(int pid,bool enableEnvironmentRead)
{
#ifdef Q_OS_UNIX
......@@ -374,6 +405,10 @@ bool UnixProcessInfo::readArguments(int pid)
addArgument(entry);
}
}
else
{
setFileError( argumentsFile.error() );
}
return true;
}
......@@ -381,13 +416,21 @@ bool UnixProcessInfo::readArguments(int pid)
bool UnixProcessInfo::readCurrentDir(int pid)
{
QFileInfo info( QString("/proc/%1/cwd").arg(pid) );
if ( info.isSymLink() )
const bool readable = info.isReadable();
if ( readable && info.isSymLink() )
{
setCurrentDir( info.symLinkTarget() );
return true;
}
else
{
if ( !readable )
setError( PermissionsError );
else
setError( UnknownError );
return false;
}
}
......@@ -422,6 +465,10 @@ bool UnixProcessInfo::readEnvironment(int pid)
}
}
}
else
{
setFileError( environmentFile.error() );
}
return true;
}
......
......@@ -21,6 +21,7 @@
#define PROCESSINFO_H
// Qt
#include <QtCore/QFile>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QVector>
......@@ -174,6 +175,25 @@ public:
*/
QString format(const QString& text) const;
/**
* This enum describes the errors which can occur when trying to read
* a process's information.
*/
enum Error
{
/** No error occurred. */
NoError,
/** The nature of the error is unknown. */
UnknownError,
/** Konsole does not have permission to obtain the process information. */
PermissionsError
};
/**
* Returns the last error which occurred.
*/
Error error() const;
protected:
/**
* Constructs a new process instance. You should not call the constructor
......@@ -215,6 +235,12 @@ protected:
/** Sets the current working directory for the process */
void setCurrentDir(const QString& dir);
/** Sets the error */
void setError( Error error );
/** Convenience method. Sets the error based on a QFile error code. */
void setFileError( QFile::FileError error );
/**
* Adds a commandline argument for the process, as returned
* by arguments()
......@@ -269,6 +295,9 @@ private:
int _pid;
int _parentPid;
int _foregroundPid;
Error _lastError;
QString _name;
QString _currentDir;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment