1
/* This file is part of the KDE project
2
Copyright (C) 2007 Manolo Valdes <nolis71cu@gmail.com>
4
This library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Library General Public
6
License as published by the Free Software Foundation; either
7
version 2 of the License, or (at your option) any later version.
9
This library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
Library General Public License for more details.
14
You should have received a copy of the GNU Library General Public License
15
along with this library; see the file COPYING.LIB. If not, write to
16
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
Boston, MA 02110-1301, USA.
20
#include "processes_local_p.h"
27
#include <sys/param.h>
28
#include <sys/sysctl.h>
29
#include <sys/types.h>
31
#include <sys/resource.h>
42
class ProcessesLocal::Private
47
inline bool readProc(long pid, struct kinfo_proc *p);
48
inline void readProcStatus(struct kinfo_proc *p, Process *process);
49
inline void readProcStat(struct kinfo_proc *p, Process *process);
50
inline void readProcStatm(struct kinfo_proc *p, Process *process);
51
inline bool readProcCmdline(long pid, Process *process);
54
bool ProcessesLocal::Private::readProc(long pid, struct kinfo_proc *p)
61
mib[2] = KERN_PROC_PID;
64
len = sizeof (struct kinfo_proc);
65
if (sysctl(mib, 4, p, &len, NULL, 0) == -1 || !len)
70
void ProcessesLocal::Private::readProcStatus(struct kinfo_proc *p, Process *process)
74
process->setTracerpid(-1);
76
process->setEuid(p->ki_uid);
77
process->setUid(p->ki_ruid);
78
process->setEgid(p->ki_svgid);
79
process->setGid(p->ki_rgid);
80
process->setName(QString(p->ki_comm ? p->ki_comm : "????"));
83
void ProcessesLocal::Private::readProcStat(struct kinfo_proc *p, Process *ps)
88
ps->setUserTime(p->ki_rusage.ru_utime.tv_sec * 100 + p->ki_rusage.ru_utime.tv_usec / 10000);
89
ps->setSysTime(p->ki_rusage.ru_stime.tv_sec * 100 + p->ki_rusage.ru_stime.tv_usec / 10000);
90
ps->setNiceLevel(p->ki_nice);
91
ps->setVmSize(p->ki_size / 1024);
92
ps->setVmRSS(p->ki_rssize * getpagesize() / 1024);
95
// "idle","run","sleep","stop","zombie"
98
ps->setStatus(Process::Running);
103
ps->setStatus(Process::Sleeping);
106
ps->setStatus(Process::Stopped);
109
ps->setStatus(Process::Zombie);
112
ps->setStatus(Process::OtherStatus);
117
void ProcessesLocal::Private::readProcStatm(struct kinfo_proc *p, Process *process)
119
process->setVmURSS(-1);
122
bool ProcessesLocal::Private::readProcCmdline(long pid, Process *process)
131
mib[2] = KERN_PROC_ARGS;
134
if (sysctl(mib, 4, buf, &buflen, NULL, 0) == -1 || !buflen)
136
QString command = QString(buf);
138
//cmdline seperates parameters with the NULL character
139
command = command.replace('\0', ' ');
140
process->setCommand(command.trimmed());
145
ProcessesLocal::ProcessesLocal() : d(new Private())
150
long ProcessesLocal::getParentPid(long pid) {
153
if(d->readProc(pid, &p))
160
bool ProcessesLocal::updateProcessInfo( long pid, Process *process)
163
if(!d->readProc(pid, &p)) return false;
164
d->readProcStat(&p, process);
165
d->readProcStatus(&p, process);
166
d->readProcStatm(&p, process);
167
if(!d->readProcCmdline(pid, process)) return false;
172
QSet<long> ProcessesLocal::getAllPids( )
178
struct kinfo_proc *p;
182
mib[2] = KERN_PROC_ALL;
183
if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1)
185
if ((p = (kinfo_proc *) malloc(len)) == NULL)
187
if (sysctl(mib, 3, p, &len, NULL, 0) == -1) {
192
for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
194
long pid = p[num].ki_pid;
195
long long ppid = p[num].ki_ppid;
197
//skip all process with parent id = 0 but init
198
if(ppid <= 0 && pid != 1)
206
bool ProcessesLocal::sendSignal(long pid, int sig) {
207
if ( kill( (pid_t)pid, sig ) ) {
214
bool ProcessesLocal::setNiceness(long pid, int priority) {
215
if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
216
//set niceness failed
222
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
224
if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
226
if(pid <= 0) return false; // check the parameters
227
struct sched_param params;
228
params.sched_priority = priority;
229
switch(priorityClass) {
230
case (KSysGuard::Process::Other):
231
return (sched_setscheduler( pid, SCHED_OTHER, ¶ms) == 0);
232
case (KSysGuard::Process::RoundRobin):
233
return (sched_setscheduler( pid, SCHED_RR, ¶ms) == 0);
234
case (KSysGuard::Process::Fifo):
235
return (sched_setscheduler( pid, SCHED_FIFO, ¶ms) == 0);
237
case (KSysGuard::Process::Batch):
238
return (sched_setscheduler( pid, SCHED_BATCH, ¶ms) == 0);
245
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
246
return false; //Not yet supported
249
bool ProcessesLocal::supportsIoNiceness() {
253
long long ProcessesLocal::totalPhysicalMemory() {
258
len = sizeof (Total);
259
if (sysctlbyname("hw.physmem", &Total, &len, NULL, 0) == -1)
262
return Total /= 1024;
265
ProcessesLocal::~ProcessesLocal()