1
/* This file is part of the KDE project
2
Copyright (C) 2007 Manolo Valdes <nolis71cu@gmail.com>
3
Copyright (C) 2010 Alex Hornung <ahornung@gmail.com>
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public License
16
along with this library; see the file COPYING.LIB. If not, write to
17
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
Boston, MA 02110-1301, USA.
21
#include "processes_local_p.h"
28
#include <sys/param.h>
29
#include <sys/sysctl.h>
30
#include <sys/types.h>
32
#include <sys/resource.h>
33
#include <sys/resourcevar.h>
40
#define PP(pp, field) ((pp)->kp_ ## field)
41
#define LP(pp, field) ((pp)->kp_lwp.kl_ ## field)
42
#define VP(pp, field) ((pp)->kp_vm_ ## field)
47
class ProcessesLocal::Private
52
inline bool readProc(long pid, struct kinfo_proc *p);
53
inline void readProcStatus(struct kinfo_proc *p, Process *process);
54
inline void readProcStat(struct kinfo_proc *p, Process *process);
55
inline void readProcStatm(struct kinfo_proc *p, Process *process);
56
inline bool readProcCmdline(long pid, Process *process);
59
bool ProcessesLocal::Private::readProc(long pid, struct kinfo_proc *p)
66
mib[2] = KERN_PROC_PID;
69
len = sizeof (struct kinfo_proc);
70
if (sysctl(mib, 4, p, &len, NULL, 0) == -1 || !len)
75
void ProcessesLocal::Private::readProcStatus(struct kinfo_proc *p, Process *process)
79
process->setTracerpid(-1);
81
process->setEuid(PP(p, uid));
82
process->setUid(PP(p, ruid));
83
process->setEgid(PP(p, svgid));
84
process->setGid(PP(p, rgid));
85
process->setName(QString(PP(p, comm)));
88
void ProcessesLocal::Private::readProcStat(struct kinfo_proc *p, Process *ps)
90
ps->setUserTime(LP(p, uticks) / 10000);
91
ps->setSysTime((LP(p, sticks) + LP(p, iticks)) / 10000);
92
ps->setNiceLevel(PP(p, nice));
93
ps->setVmSize(VP(p, map_size) / 1024); /* convert to KiB */
94
ps->setVmRSS(VP(p, prssize) * getpagesize() / 1024); /* convert to KiB */
96
// "idle","run","sleep","stop","zombie"
97
switch( LP(p, stat) ) {
99
ps->setStatus(Process::Running);
102
ps->setStatus(Process::Sleeping);
105
ps->setStatus(Process::Stopped);
108
ps->setStatus(Process::OtherStatus);
111
if (PP(p, stat) == SZOMB)
112
ps->setStatus(Process::Zombie);
115
void ProcessesLocal::Private::readProcStatm(struct kinfo_proc *p, Process *process)
117
process->setVmURSS(-1);
120
bool ProcessesLocal::Private::readProcCmdline(long pid, Process *process)
128
mib[2] = KERN_PROC_ARGS;
131
if (sysctl(mib, 4, buf, &buflen, NULL, 0) == -1 || (buflen == 0))
133
QString command = QString(buf);
135
//cmdline seperates parameters with the NULL character
136
command = command.replace('\0', ' ');
137
process->setCommand(command.trimmed());
142
ProcessesLocal::ProcessesLocal() : d(new Private())
146
long ProcessesLocal::getParentPid(long pid)
151
if(d->readProc(pid, &p))
157
bool ProcessesLocal::updateProcessInfo( long pid, Process *process)
161
if(!d->readProc(pid, &p)) {
165
d->readProcStat(&p, process);
166
d->readProcStatus(&p, process);
167
d->readProcStatm(&p, process);
168
if(!d->readProcCmdline(pid, process)) {
175
QSet<long> ProcessesLocal::getAllPids( )
181
struct kinfo_proc *p;
185
mib[2] = KERN_PROC_ALL;
186
if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1)
188
if ((p = (kinfo_proc *) malloc(len)) == NULL)
190
if (sysctl(mib, 3, p, &len, NULL, 0) == -1) {
195
for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
197
long pid = PP((&p[num]), pid);
198
long long ppid = PP((&p[num]), ppid);
200
//skip all process with parent id = 0 but init
201
if(ppid <= 0 && pid != 1)
209
bool ProcessesLocal::sendSignal(long pid, int sig) {
210
if ( kill( (pid_t)pid, sig ) ) {
217
bool ProcessesLocal::setNiceness(long pid, int priority) {
218
if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
219
//set niceness failed
225
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
227
if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
229
if(pid <= 0) return false; // check the parameters
230
struct sched_param params;
231
params.sched_priority = priority;
232
switch(priorityClass) {
233
case (KSysGuard::Process::Other):
234
return (sched_setscheduler( pid, SCHED_OTHER, ¶ms) == 0);
235
case (KSysGuard::Process::RoundRobin):
236
return (sched_setscheduler( pid, SCHED_RR, ¶ms) == 0);
237
case (KSysGuard::Process::Fifo):
238
return (sched_setscheduler( pid, SCHED_FIFO, ¶ms) == 0);
240
case (KSysGuard::Process::Batch):
241
return (sched_setscheduler( pid, SCHED_BATCH, ¶ms) == 0);
248
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
249
return false; //Not yet supported
252
bool ProcessesLocal::supportsIoNiceness() {
256
long long ProcessesLocal::totalPhysicalMemory() {
261
len = sizeof (Total);
262
if (sysctlbyname("hw.physmem", &Total, &len, NULL, 0) == -1)
265
Total *= getpagesize() / 1024;
269
ProcessesLocal::~ProcessesLocal()