File indexing completed on 2024-04-28 16:49:55
0001 /* 0002 SPDX-FileCopyrightText: 2007 John Tapsell <tapsell@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef PROCESSES_H_ 0008 #define PROCESSES_H_ 0009 0010 #include "process.h" 0011 #include <QHash> 0012 #include <QObject> 0013 #include <QVariant> 0014 0015 namespace KSysGuard 0016 { 0017 /** 0018 * This class retrieves the processes currently running in an OS independent way. 0019 * 0020 * To use, do something like: 0021 * 0022 * \code 0023 * #include "processes.h> 0024 * #include "process.h> 0025 * 0026 * KSysGuard::Processes *processes = new KSysGuard::Processes() 0027 * QHash<long, Process *> processlist = processes->getProcesses(); 0028 * foreach( Process * process, processlist) { 0029 * kDebug() << "Process with pid " << process->pid() << " is called " << process->name; 0030 * } 0031 * delete processes; 0032 * processes = NULL; 0033 * \endcode 0034 * 0035 * @author John Tapsell <tapsell@kde.org> 0036 */ 0037 #ifdef Q_WS_WIN 0038 class Processes : public QObject 0039 #else 0040 class Q_DECL_EXPORT Processes : public QObject 0041 #endif 0042 { 0043 Q_OBJECT 0044 0045 public: 0046 Processes(const QString &hostname = QString(), QObject *parent = nullptr); 0047 ~Processes() override; 0048 enum UpdateFlag { 0049 StandardInformation = 1, 0050 IOStatistics = 2, 0051 XMemory = 4, 0052 Smaps = 8, 0053 }; 0054 Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag) 0055 0056 enum Error { Unknown = 0, InvalidPid, InvalidParameter, InsufficientPermissions, ProcessDoesNotExistOrZombie, NotSupported, NoError }; 0057 0058 /** 0059 * Update all the process information. After calling this, /proc or equivalent is scanned and 0060 * the signals processChanged, etc are emitted. 0061 * 0062 * Set updateDuration to whatever time period that you update, in milliseconds. 0063 * For example, if you update every 2000ms, set this to 2000. That way it won't update 0064 * more often than needed. 0065 */ 0066 void updateAllProcesses(long updateDurationMS = 0, Processes::UpdateFlags updateFlags = {}); 0067 0068 /** 0069 * Return information for one specific process. Call getProcess(0) to get the 0070 * fake process used as the top most parent for all processes. 0071 * This doesn't fetch any new information and so returns almost instantly. 0072 * Call updateAllProcesses() to actually fetch the process information. 0073 */ 0074 Process *getProcess(long pid) const; 0075 0076 /** 0077 * Get the error code for the last command that failed. 0078 */ 0079 Error lastError() const; 0080 0081 /** 0082 * Kill the specified process. You may not have the privilege to kill the process. 0083 * The process may also chose to ignore the command. Send the SIGKILL signal to kill 0084 * the process immediately. You may lose any unsaved data. 0085 * 0086 * @returns Successful or not in killing the process 0087 */ 0088 bool killProcess(long pid); 0089 0090 /** 0091 * Send the specified named POSIX signal to the process given. 0092 * 0093 * For example, to indicate for process 324 to STOP do: 0094 * \code 0095 * #include <signals.h> 0096 * ... 0097 * 0098 * KSysGuard::Processes::sendSignal(23, SIGSTOP); 0099 * \endcode 0100 * 0101 */ 0102 bool sendSignal(long pid, int sig); 0103 0104 /** 0105 * Set the priority for a process. This is from 19 (very nice, lowest priority) to 0106 * -20 (highest priority). The default value for a process is 0. 0107 * 0108 * @return false if you do not have permission to set the priority 0109 */ 0110 bool setNiceness(long pid, int priority); 0111 0112 /** 0113 * Set the scheduler for a process. This is defined according to POSIX.1-2001 0114 * See "man sched_setscheduler" for more information. 0115 * 0116 * @p priorityClass One of SCHED_FIFO, SCHED_RR, SCHED_OTHER, and SCHED_BATCH 0117 * @p priority Set to 0 for SCHED_OTHER and SCHED_BATCH. Between 1 and 99 for SCHED_FIFO and SCHED_RR 0118 * @return false if you do not have permission to set the priority 0119 */ 0120 bool setScheduler(long pid, KSysGuard::Process::Scheduler priorityClass, int priority); 0121 0122 /** 0123 * Set the io priority for a process. This is from 7 (very nice, lowest io priority) to 0124 * 0 (highest priority). The default value is determined as: io_nice = (cpu_nice + 20) / 5. 0125 * 0126 * @return false if you do not have permission to set the priority 0127 */ 0128 bool setIoNiceness(long pid, KSysGuard::Process::IoPriorityClass priorityClass, int priority); 0129 0130 /** 0131 * Returns true if ionice is supported on this system 0132 */ 0133 bool supportsIoNiceness(); 0134 0135 /** 0136 * Return the internal pointer of all the processes. The order of the processes 0137 * is guaranteed to never change. Call updateAllProcesses() first to actually 0138 * update the information. 0139 */ 0140 const QList<Process *> &getAllProcesses() const; 0141 0142 /** 0143 * Return the number of processes. Call updateAllProcesses() to actually 0144 * update the information. 0145 * 0146 * This is equivalent to getAllProcesses().count() 0147 */ 0148 int processCount() const; 0149 0150 /** 0151 * Return the total amount of physical memory in KB. This is fast (just a system call) 0152 * Returns 0 on error 0153 */ 0154 long long totalPhysicalMemory(); 0155 0156 /** 0157 * Return the number of processor cores enabled. 0158 * (A system can disable processors. Disabled processors are not counted here). 0159 * This is fast (just a system call) */ 0160 long numberProcessorCores(); 0161 0162 /** Update/add process for given pid immediately */ 0163 bool updateOrAddProcess(long pid); 0164 0165 /** Whether we can get historic process and system data */ 0166 bool isHistoryAvailable() const; 0167 0168 /** Stop using historical data and use the most recent up-to-date data */ 0169 void useCurrentData(); 0170 0171 /** Return a list of end times and intervals for all the available history */ 0172 QList<QPair<QDateTime, uint>> historiesAvailable() const; 0173 0174 /** Use historical process data closest to the given date-time. 0175 * Returns false if it is outside the range available or there is a problem 0176 * getting the data. */ 0177 bool setViewingTime(const QDateTime &when); 0178 QDateTime viewingTime() const; 0179 bool loadHistoryFile(const QString &filename); 0180 QString historyFileName() const; 0181 0182 public Q_SLOTS: 0183 /** The abstract processes has updated its list of processes */ 0184 void processesUpdated(); 0185 void processUpdated(long pid, const Process::Updates &changes); 0186 0187 Q_SIGNALS: 0188 /** The data for a process has changed. 0189 * if @p onlyTotalCpu is set, only the total cpu usage has been updated. 0190 * process->changes contains a bit field indicating what has changed since the last time this was emitted 0191 * for this process 0192 */ 0193 void processChanged(KSysGuard::Process *process, bool onlyTotalCpu); 0194 0195 /** 0196 * This indicates we are about to add a process in the model. 0197 * The process already has the pid, ppid and tree_parent set up. 0198 */ 0199 void beginAddProcess(KSysGuard::Process *process); 0200 0201 /** 0202 * We have finished inserting a process 0203 */ 0204 void endAddProcess(); 0205 /** 0206 * This indicates we are about to remove a process in the model. Emit the appropriate signals 0207 */ 0208 0209 void beginRemoveProcess(KSysGuard::Process *process); 0210 0211 /** 0212 * We have finished removing a process 0213 */ 0214 void endRemoveProcess(); 0215 0216 /** 0217 * This indicates we are about move a process from one parent to another. 0218 */ 0219 void beginMoveProcess(KSysGuard::Process *process, KSysGuard::Process *new_parent); 0220 0221 /** 0222 * We have finished moving the process 0223 */ 0224 void endMoveProcess(); 0225 0226 void updated(); 0227 0228 protected: 0229 class Private; 0230 Private *d; 0231 0232 private: 0233 inline void deleteProcess(long pid); 0234 bool updateProcess(Process *process, long ppid); 0235 bool updateProcessInfo(Process *ps); 0236 bool addProcess(long pid, long ppid); 0237 0238 Q_SIGNALS: 0239 /** For a remote machine, we rely on being able to communicate with ksysguardd. 0240 * This must be dealt with by the program including this widget. It must listen to our 0241 * 'runCommand' signal, and run the given command, with the given id. */ 0242 void runCommand(const QString &command, int id); 0243 0244 public: 0245 /** For a remote machine, we rely on being able to communicate with ksysguardd. 0246 * The programming using this must call this slot when an answer is received from ksysguardd, 0247 * in response to a runCommand request. The id identifies the answer */ 0248 void answerReceived(int id, const QList<QByteArray> &answer); 0249 }; 0250 Q_DECLARE_OPERATORS_FOR_FLAGS(Processes::UpdateFlags) 0251 } 0252 0253 #endif