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>
32
#if defined(__DragonFly__)
33
#include <sys/resourcevar.h>
46
class ProcessesLocal::Private
51
inline bool readProc(long pid, struct kinfo_proc *p);
52
inline void readProcStatus(struct kinfo_proc *p, Process *process);
53
inline void readProcStat(struct kinfo_proc *p, Process *process);
54
inline void readProcStatm(struct kinfo_proc *p, Process *process);
55
inline bool readProcCmdline(long pid, Process *process);
58
bool ProcessesLocal::Private::readProc(long pid, struct kinfo_proc *p)
65
mib[2] = KERN_PROC_PID;
68
len = sizeof (struct kinfo_proc);
69
if (sysctl(mib, 4, p, &len, NULL, 0) == -1 || !len)
74
void ProcessesLocal::Private::readProcStatus(struct kinfo_proc *p, Process *process)
78
process->setTracerpid(-1);
81
#if defined(__FreeBSD__) && __FreeBSD_version >= 500015
82
process->setUid(p->ki_uid);
83
process->setGid(p->ki_pgid);
84
process->setName(QString(p->ki_comm ? p->ki_comm : "????"));
85
#elif defined(__DragonFly__) && __DragonFly_version >= 190000
86
process->setUid(p->kp_uid);
87
process->setGid(p->kp_pgid);
88
process->setName(QString(p->kp_comm ? p->kp_comm : "????"));
90
process->setUid(p->kp_eproc.e_ucred.cr_uid);
91
process->setGid(p->kp_eproc.e_pgid);
95
void ProcessesLocal::Private::readProcStat(struct kinfo_proc *p, Process *ps)
99
#if defined(__FreeBSD__) && __FreeBSD_version >= 500015
100
ps->setUserTime(p->ki_runtime / 10000);
101
ps->setNiceLevel(p->ki_nice);
102
ps->setVmSize(p->ki_size);
103
ps->setVmRSS(p->ki_rssize * getpagesize());
105
#elif defined(__DragonFly__) && __DragonFly_version >= 190000
106
if (!getrusage(p->kp_pid, &pru)) {
107
errx(1, "failed to get rusage info");
109
ps->setUserTime(pru.ru_utime.tv_usec / 1000); /*p_runtime / 1000*/
110
ps->setNiceLevel(p->kp_nice);
111
ps->setVmSize(p->kp_vm_map_size);
112
ps->setVmRSS(p->kp_vm_rssize * getpagesize());
115
ps->setUserTime(p->kp_proc.p_rtime.tv_sec*100+p->kp_proc.p_rtime.tv_usec/100);
116
ps->setNiceLevel(p->kp_proc.p_nice);
117
ps->setVmSize(p->kp_eproc.e_vm.vm_map.size);
118
ps->setVmRSS(p->kp_eproc.e_vm.vm_rssize * getpagesize());
119
status = p->kp_proc.p_stat;
123
// "idle","run","sleep","stop","zombie"
126
ps->setStatus(Process::DiskSleep);
129
ps->setStatus(Process::Running);
132
ps->setStatus(Process::Sleeping);
135
ps->setStatus(Process::Stopped);
138
ps->setStatus(Process::Zombie);
141
ps->setStatus(Process::OtherStatus);
146
void ProcessesLocal::Private::readProcStatm(struct kinfo_proc *p, Process *process)
150
// unsigned long shared;
151
// process->setVmURSS(process->vmRSS - (shared * sysconf(_SC_PAGESIZE) / 1024));
154
bool ProcessesLocal::Private::readProcCmdline(long pid, Process *process)
163
mib[2] = KERN_PROC_ARGS;
166
if (sysctl(mib, 4, buf, &buflen, NULL, 0) == -1 || !buflen)
168
QString command = QString(buf);
170
//cmdline seperates parameters with the NULL character
171
command.replace('\0', ' ');
172
process->setCommand(command.trimmed());
177
ProcessesLocal::ProcessesLocal() : d(new Private())
182
long ProcessesLocal::getParentPid(long pid) {
186
if(d->readProc(pid, &p))
188
#if defined(__FreeBSD__) && __FreeBSD_version >= 500015
190
#elif defined(__DragonFly__) && __DragonFly_version >= 190000
193
ppid = p.kp_eproc.e_ppid;
199
bool ProcessesLocal::updateProcessInfo( long pid, Process *process)
202
if(!d->readProc(pid, &p)) return false;
203
d->readProcStat(&p, process);
204
d->readProcStatus(&p, process);
205
d->readProcStatm(&p, process);
206
if(!d->readProcCmdline(pid, process)) return false;
211
QSet<long> ProcessesLocal::getAllPids( )
217
struct kinfo_proc *p;
221
mib[2] = KERN_PROC_ALL;
222
sysctl(mib, 3, NULL, &len, NULL, 0);
223
p = (kinfo_proc *) malloc(len);
224
sysctl(mib, 3, p, &len, NULL, 0);
226
for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
227
#if defined(__FreeBSD__) && __FreeBSD_version >= 500015
228
pids.insert(p[num].ki_pid);
229
#elif defined(__DragonFly__) && __DragonFly_version >= 190000
230
pids.insert(p[num].kp_pid);
232
pids.insert(p[num].kp_proc.p_pid);
238
bool ProcessesLocal::sendSignal(long pid, int sig) {
239
if ( kill( (pid_t)pid, sig ) ) {
246
bool ProcessesLocal::setNiceness(long pid, int priority) {
247
if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
248
//set niceness failed
254
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
256
if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
258
if(pid <= 0) return false; // check the parameters
262
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
263
return false; //Not yet supported
266
bool ProcessesLocal::supportsIoNiceness() {
270
long long ProcessesLocal::totalPhysicalMemory() {
272
static int physmem_mib[] = { CTL_HW, HW_PHYSMEM };
273
/* get the page size with "getpagesize" and calculate pageshift from
275
int pagesize = ::getpagesize();
277
while (pagesize > 1) {
282
size_t size = sizeof(Total);
283
sysctl(physmem_mib, 2, &Total, &size, NULL, 0);
284
return Total /= 1024;
287
long int KSysGuard::ProcessesLocal::numberProcessorCores()
297
if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1 || !len)
301
ProcessesLocal::~ProcessesLocal()