Commit 0ed84fe6 authored by David Redondo's avatar David Redondo 🏎
Browse files

Refactor so that the methods of AbstractProcesses return the actual error

Checking if the return value is false and then acessing the last error is
not very elegant. Instead we can directly return the actual error. This does
not yet extend to public API in Processes but the same can be easily done there
in the future.
parent 18937f39
......@@ -52,10 +52,11 @@ ActionReply KSysGuardProcessListHelper::sendsignal(const QVariantMap &parameters
QStringList errorList;
for (int i = 0; i < numProcesses; ++i) {
qlonglong pid = GET_PID(i);
bool successForThisPid = processes.sendSignal(pid, signal);
if (!successForThisPid)
KSysGuard::Processes::Error error = processes.sendSignal(pid, signal);
if (error != KSysGuard::Processes::NoError) {
errorList << QString::number(pid);
success = successForThisPid && success;
success = false;
}
}
if(success) {
return ActionReply::SuccessReply();
......@@ -76,7 +77,7 @@ ActionReply KSysGuardProcessListHelper::renice(const QVariantMap &parameters) {
int numProcesses = parameters.value(QStringLiteral("pidcount")).toInt();
for (int i = 0; i < numProcesses; ++i) {
qlonglong pid = GET_PID(i);
success = processes.setNiceness(pid, niceValue) && success;
success &= (processes.setNiceness(pid, niceValue) != KSysGuard::Processes::NoError);
}
if(success)
return ActionReply::SuccessReply();
......@@ -95,7 +96,7 @@ ActionReply KSysGuardProcessListHelper::changeioscheduler(const QVariantMap &par
const int numProcesses = parameters.value(QStringLiteral("pidcount")).toInt();
for (int i = 0; i < numProcesses; ++i) {
qlonglong pid = GET_PID(i);
success = processes.setIoNiceness(pid, ioScheduler, ioSchedulerPriority) && success;
success &= (processes.setIoNiceness(pid, ioScheduler, ioSchedulerPriority) != KSysGuard::Processes::NoError);
}
if(success)
return ActionReply::SuccessReply();
......@@ -115,7 +116,7 @@ ActionReply KSysGuardProcessListHelper::changecpuscheduler(const QVariantMap &pa
const int numProcesses = parameters.value(QStringLiteral("pidcount")).toInt();
for (int i = 0; i < numProcesses; ++i) {
qlonglong pid = GET_PID(i);
success = processes.setScheduler(pid, cpuScheduler, cpuSchedulerPriority) && success;
success &= (processes.setScheduler(pid, cpuScheduler, cpuSchedulerPriority) != KSysGuard::Processes::NoError);
}
if(success)
return ActionReply::SuccessReply();
......
......@@ -41,7 +41,7 @@ struct ApplyResult
class ProcessController::Private
{
public:
ApplyResult applyToPids(const QVector<int> &pids, const std::function<bool(int)> &function);
ApplyResult applyToPids(const QVector<int> &pids, const std::function<Processes::Error(int)> &function);
ProcessController::Result runKAuthAction(const QString &actionId, const QVector<int> &pids, const QVariantMap &options);
QVector<int> listToVector(const QList<long long> &list);
QVector<int> listToVector(const QVariantList &list);
......@@ -212,33 +212,29 @@ QString ProcessController::resultToString(Result result)
}
}
ApplyResult KSysGuard::ProcessController::Private::applyToPids(const QVector<int>& pids, const std::function<bool(int)>& function)
ApplyResult KSysGuard::ProcessController::Private::applyToPids(const QVector<int>& pids, const std::function<Processes::Error(int)>& function)
{
ApplyResult result;
s_localProcesses->errorCode = KSysGuard::Processes::Unknown;
for (auto pid : pids) {
auto success = function(pid);
if (!success) {
switch (s_localProcesses->errorCode) {
case KSysGuard::Processes::InsufficientPermissions:
case KSysGuard::Processes::Unknown:
result.unchanged << pid;
result.resultCode = Result::InsufficientPermissions;
break;
case Processes::InvalidPid:
case Processes::ProcessDoesNotExistOrZombie:
case Processes::InvalidParameter:
result.resultCode = Result::NoSuchProcess;
break;
case Processes::NotSupported:
result.resultCode = Result::Unsupported;
break;
default:
result.resultCode = Result::Unknown;
break;
}
auto error = function(pid);
switch (error) {
case KSysGuard::Processes::InsufficientPermissions:
case KSysGuard::Processes::Unknown:
result.unchanged << pid;
result.resultCode = Result::InsufficientPermissions;
break;
case Processes::InvalidPid:
case Processes::ProcessDoesNotExistOrZombie:
case Processes::InvalidParameter:
result.resultCode = Result::NoSuchProcess;
break;
case Processes::NotSupported:
result.resultCode = Result::Unsupported;
break;
case Processes::NoError:
break;
}
}
return result;
......
......@@ -53,6 +53,7 @@ namespace KSysGuard
mHavePreviousIoValues = false;
mUpdateFlags = {};
mUsingHistoricalData = false;
mLastError = Error::NoError;
q = q_ptr;
}
~Private();
......@@ -77,6 +78,8 @@ namespace KSysGuard
bool mHavePreviousIoValues; ///< This is whether we updated the IO value on the last update
bool mUsingHistoricalData; ///< Whether to return historical data for updateProcess() etc
Processes *q;
Error mLastError;
};
Processes::Private::~Private() {
......@@ -112,7 +115,7 @@ Processes::~Processes()
Processes::Error Processes::lastError() const
{
return d->mAbstractProcesses->errorCode;
return d->mLastError;
}
Process *Processes::getProcess(long pid) const
{
......@@ -434,44 +437,48 @@ bool Processes::killProcess(long pid) {
}
bool Processes::sendSignal(long pid, int sig) {
d->mAbstractProcesses->errorCode = Unknown;
if(d->mUsingHistoricalData) {
d->mAbstractProcesses->errorCode = NotSupported;
auto processes = d->mUsingHistoricalData ? d->mHistoricProcesses : d->mAbstractProcesses;
auto error = processes->sendSignal(pid, sig);
if (error != NoError) {
d->mLastError = error;
return false;
}
return d->mAbstractProcesses->sendSignal(pid, sig);
return true;
}
bool Processes::setNiceness(long pid, int priority) {
d->mAbstractProcesses->errorCode = Unknown;
if(d->mUsingHistoricalData) {
d->mAbstractProcesses->errorCode = NotSupported;
auto processes = d->mUsingHistoricalData ? d->mHistoricProcesses : d->mAbstractProcesses;
auto error = processes->setNiceness(pid, priority);
if (error != NoError) {
d->mLastError = error;
return false;
}
return d->mAbstractProcesses->setNiceness(pid, priority);
return true;
}
bool Processes::setScheduler(long pid, KSysGuard::Process::Scheduler priorityClass, int priority) {
d->mAbstractProcesses->errorCode = Unknown;
if(d->mUsingHistoricalData) {
d->mAbstractProcesses->errorCode = NotSupported;
auto processes = d->mUsingHistoricalData ? d->mHistoricProcesses : d->mAbstractProcesses;
auto error = processes->setScheduler(pid, priorityClass, priority);
if (error != NoError) {
d->mLastError = error;
return false;
}
return d->mAbstractProcesses->setScheduler(pid, priorityClass, priority);
return true;
}
bool Processes::setIoNiceness(long pid, KSysGuard::Process::IoPriorityClass priorityClass, int priority) {
d->mAbstractProcesses->errorCode = Unknown;
if(d->mUsingHistoricalData) {
d->mAbstractProcesses->errorCode = NotSupported;
auto processes = d->mUsingHistoricalData ? d->mHistoricProcesses : d->mAbstractProcesses;
auto error = processes->setIoNiceness(pid, priorityClass, priority);
if (error != NoError) {
d->mLastError = error;
return false;
}
return d->mAbstractProcesses->setIoNiceness(pid, priorityClass, priority);
return true;
}
bool Processes::supportsIoNiceness() {
if(d->mUsingHistoricalData)
return false;
return d->mHistoricProcesses->supportsIoNiceness();
return d->mAbstractProcesses->supportsIoNiceness();
}
......@@ -511,9 +518,8 @@ void Processes::useCurrentData()
bool Processes::setViewingTime(const QDateTime &when)
{
d->mAbstractProcesses->errorCode = Unknown;
if(!d->mIsLocalHost) {
d->mAbstractProcesses->errorCode = NotSupported;
d->mLastError = NotSupported;
return false;
}
if(!d->mUsingHistoricalData) {
......@@ -528,9 +534,8 @@ bool Processes::setViewingTime(const QDateTime &when)
bool Processes::loadHistoryFile(const QString &filename)
{
d->mAbstractProcesses->errorCode = Unknown;
if(!d->mIsLocalHost) {
d->mAbstractProcesses->errorCode = NotSupported;
d->mLastError = NotSupported;
return false;
}
if(!d->mHistoricProcesses)
......
......@@ -74,7 +74,8 @@ namespace KSysGuard
InvalidParameter,
InsufficientPermissions,
ProcessDoesNotExistOrZombie,
NotSupported
NotSupported,
NoError
};
/**
......
......@@ -324,40 +324,36 @@ QSet<long> ProcessesATop::getAllPids( )
return d->pids.toSet();
}
bool ProcessesATop::sendSignal(long pid, int sig) {
Processes::Error ProcessesATop::sendSignal(long pid, int sig) {
Q_UNUSED(pid);
Q_UNUSED(sig);
errorCode = Processes::NotSupported;
return false;
return Processes::NotSupported;
}
bool ProcessesATop::setNiceness(long pid, int priority) {
Processes::Error ProcessesATop::setNiceness(long pid, int priority) {
Q_UNUSED(pid);
Q_UNUSED(priority);
errorCode = Processes::NotSupported;
return false;
return Processes::NotSupported;
}
bool ProcessesATop::setScheduler(long pid, int priorityClass, int priority) {
Processes::Error ProcessesATop::setScheduler(long pid, int priorityClass, int priority) {
Q_UNUSED(pid);
Q_UNUSED(priorityClass);
Q_UNUSED(priority);
errorCode = Processes::NotSupported;
return false;
return Processes::NotSupported;
}
bool ProcessesATop::setIoNiceness(long pid, int priorityClass, int priority)
Processes::Error ProcessesATop::setIoNiceness(long pid, int priorityClass, int priority)
{
Q_UNUSED(pid);
Q_UNUSED(priorityClass);
Q_UNUSED(priority);
errorCode = Processes::NotSupported;
return false;
return Processes::NotSupported;
}
bool ProcessesATop::supportsIoNiceness()
......
......@@ -43,11 +43,11 @@ namespace KSysGuard
QSet<long> getAllPids() override;
long getParentPid(long pid) override;
bool updateProcessInfo(long pid, Process *process) override;
bool sendSignal(long pid, int sig) override;
bool setNiceness(long pid, int priority) override;
bool setScheduler(long pid, int priorityClass, int priority) override;
Processes::Error sendSignal(long pid, int sig) override;
Processes::Error setNiceness(long pid, int priority) override;
Processes::Error setScheduler(long pid, int priorityClass, int priority) override;
long long totalPhysicalMemory() override;
bool setIoNiceness(long pid, int priorityClass, int priority) override;
Processes::Error setIoNiceness(long pid, int priorityClass, int priority) override;
bool supportsIoNiceness() override;
long numberProcessorCores() override
#ifdef _SC_NPROCESSORS_ONLN
......
......@@ -44,7 +44,7 @@ namespace KSysGuard
public:
AbstractProcesses() { errorCode = Processes::Unknown; }
AbstractProcesses() {}
~AbstractProcesses() override {}
/** \brief Get a set of the currently running process PIDs.
......@@ -81,9 +81,10 @@ namespace KSysGuard
*
* KSysGuard::Processes::sendSignal(324, SIGSTOP);
* \endcode
* @return Error::NoError if successful
*
*/
virtual bool sendSignal(long pid, int sig) = 0;
virtual Processes::Error sendSignal(long pid, int sig) = 0;
/** \brief Set the priority for a process.
*
......@@ -92,9 +93,9 @@ namespace KSysGuard
*
* This has no effect if the scheduler is not the normal one (SCHED_OTHER in Linux).
*
* @return false if you do not have permission to set the priority.
* @return Error::NoError if successful
*/
virtual bool setNiceness(long pid, int priority) = 0;
virtual Processes::Error setNiceness(long pid, int priority) = 0;
/** \brief Set the scheduler for a process.
*
......@@ -103,9 +104,9 @@ namespace KSysGuard
*
* @p priorityClass One of SCHED_FIFO, SCHED_RR, SCHED_OTHER, and SCHED_BATCH
* @p priority Set to 0 for SCHED_OTHER and SCHED_BATCH. Between 1 and 99 for SCHED_FIFO and SCHED_RR
* @return false if you do not have permission to set the priority
* @return Error::NoError if successful
*/
virtual bool setScheduler(long pid, int priorityClass, int priority) = 0;
virtual Processes::Error setScheduler(long pid, int priorityClass, int priority) = 0;
/** \brief Return the total amount of physical memory in KiB.
*
......@@ -119,9 +120,9 @@ namespace KSysGuard
* This is from 7 (very nice, lowest i/o priority) to
* 0 (highest priority). The default value is determined as: io_nice = (cpu_nice + 20) / 5.
*
* @return false if you do not have permission to set the priority
* @return Error::NoError if successful
*/
virtual bool setIoNiceness(long pid, int priorityClass, int priority) = 0;
virtual Processes::Error setIoNiceness(long pid, int priorityClass, int priority) = 0;
/** \brief Returns true if ionice is supported on this system
*/
......@@ -138,8 +139,6 @@ namespace KSysGuard
* Get all the current process information from the machine. When done, emit updateAllProcesses().
*/
virtual void updateAllProcesses( Processes::UpdateFlags updateFlags ) = 0;
Processes::Error errorCode;
Q_SIGNALS:
/** \brief This is emitted when the processes have been updated, and the view should be refreshed.
*/
......
......@@ -206,47 +206,54 @@ QSet<long> ProcessesLocal::getAllPids( )
return pids;
}
bool ProcessesLocal::sendSignal(long pid, int sig) {
Processes::Error ProcessesLocal::sendSignal(long pid, int sig) {
if ( kill( (pid_t)pid, sig ) ) {
//Kill failed
return false;
return Processes::Unknown;
}
return true;
return Processes::NoError;
}
bool ProcessesLocal::setNiceness(long pid, int priority) {
Processes::Error ProcessesLocal::setNiceness(long pid, int priority) {
if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
//set niceness failed
return false;
return Processes::Unknown;
}
return true;
return Processes::NoError;
}
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
Processes::Error ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
{
if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
priority = 0;
if(pid <= 0) return false; // check the parameters
if(pid <= 0) return Processes::InvalidPid; // check the parameters
struct sched_param params;
params.sched_priority = priority;
bool success;
switch(priorityClass) {
case (KSysGuard::Process::Other):
return (sched_setscheduler( pid, SCHED_OTHER, &params) == 0);
success = (sched_setscheduler( pid, SCHED_OTHER, &params) == 0);
break;
case (KSysGuard::Process::RoundRobin):
return (sched_setscheduler( pid, SCHED_RR, &params) == 0);
success = (sched_setscheduler( pid, SCHED_RR, &params) == 0);
break;
case (KSysGuard::Process::Fifo):
return (sched_setscheduler( pid, SCHED_FIFO, &params) == 0);
success = (sched_setscheduler( pid, SCHED_FIFO, &params) == 0);
break;
#ifdef SCHED_BATCH
case (KSysGuard::Process::Batch):
return (sched_setscheduler( pid, SCHED_BATCH, &params) == 0);
success = (sched_setscheduler( pid, SCHED_BATCH, &params) == 0);
break;
#endif
default:
return false;
}
if (success) {
return Processes::NoError;
}
return Processes::Unknown;
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return false; //Not yet supported
Processes::Error ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return Processes::NotSupported; //Not yet supported
}
bool ProcessesLocal::supportsIoNiceness() {
......
......@@ -203,47 +203,54 @@ QSet<long> ProcessesLocal::getAllPids( )
return pids;
}
bool ProcessesLocal::sendSignal(long pid, int sig) {
Processes::Error ProcessesLocal::sendSignal(long pid, int sig) {
if ( kill( (pid_t)pid, sig ) ) {
//Kill failed
return false;
return Processes::Unknown;
}
return true;
return Processes::NoError;
}
bool ProcessesLocal::setNiceness(long pid, int priority) {
Processes::Error ProcessesLocal::setNiceness(long pid, int priority) {
if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
//set niceness failed
return false;
return Processes::Unknown;
}
return true;
return Processes::NoError;
}
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
Processes::Error ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
{
if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
priority = 0;
if(pid <= 0) return false; // check the parameters
struct sched_param params;
params.sched_priority = priority;
bool success = false;
switch(priorityClass) {
case (KSysGuard::Process::Other):
return (sched_setscheduler( pid, SCHED_OTHER, &params) == 0);
success = (sched_setscheduler( pid, SCHED_OTHER, &params) == 0);
break;
case (KSysGuard::Process::RoundRobin):
return (sched_setscheduler( pid, SCHED_RR, &params) == 0);
success = (sched_setscheduler( pid, SCHED_RR, &params) == 0);
break;
case (KSysGuard::Process::Fifo):
return (sched_setscheduler( pid, SCHED_FIFO, &params) == 0);
success = (sched_setscheduler( pid, SCHED_FIFO, &params) == 0);
break;
#ifdef SCHED_BATCH
case (KSysGuard::Process::Batch):
return (sched_setscheduler( pid, SCHED_BATCH, &params) == 0);
success = (sched_setscheduler( pid, SCHED_BATCH, &params) == 0);
break;
#endif
default:
return false;
}
if (success) {
return Processes::NoError;
}
return Processes::Unknown;
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return false; //Not yet supported
Processes::Error ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return Processes::NotSupported; //Not yet supported
}
bool ProcessesLocal::supportsIoNiceness() {
......
......@@ -64,24 +64,25 @@ QSet<long> ProcessesLocal::getAllPids()
return pids;
}
bool ProcessesLocal::sendSignal(long pid, int sig)
Processes::Error ProcessesLocal::sendSignal(long pid, int sig)
{
return false;
return Processes::NotSupported;
}
bool ProcessesLocal::setNiceness(long pid, int priority)
Processes::Error ProcessesLocal::setNiceness(long pid, int priority)
{
return false;
return Processes::NotSupported;
}
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
Processes::Error ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
{
return false;
return Processes::NotSupported;
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority)
Processes::Error ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority)
{
return false;
return Processes::NotSupported;
}
bool ProcessesLocal::supportsIoNiceness()
......
......@@ -584,66 +584,53 @@ QSet<long> ProcessesLocal::getAllPids( )
return pids;
}
bool ProcessesLocal::sendSignal(long pid, int sig) {
Processes::Error ProcessesLocal::sendSignal(long pid, int sig) {
errno = 0;
if (pid <= 0) {
errorCode = Processes::InvalidPid;
return false;
return Processes::InvalidPid;
}
if (kill( (pid_t)pid, sig )) {
switch (errno) {
case ESRCH:
errorCode = Processes::ProcessDoesNotExistOrZombie;
break;
return Processes::ProcessDoesNotExistOrZombie;
case EINVAL:
errorCode = Processes::InvalidParameter;
break;
return Processes::InvalidParameter;
case EPERM:
errorCode = Processes::InsufficientPermissions;
break;
default:
break;
return Processes::InsufficientPermissions;
}
//Kill failed
return false;
return Processes::Unknown;
}
return true;
return Processes::NoError;
}
bool ProcessesLocal::setNiceness(long pid, int priority) {
Processes::Error ProcessesLocal::setNiceness(long pid, int priority) {
errno = 0;
if (pid <= 0) {
errorCode = Processes::InvalidPid;
return false;
return Processes::InvalidPid;
}
if (setpriority( PRIO_PROCESS, pid, priority )) {
switch (errno) {
case ESRCH:
errorCode = Processes::ProcessDoesNotExistOrZombie;
break;
return Processes::ProcessDoesNotExistOrZombie;
case EINVAL:
errorCode = Processes::InvalidParameter;
break;
return Processes::InvalidParameter;
case EACCES:
case EPERM:
errorCode = Processes::InsufficientPermissions;