1 /* This file is part of the KDE project
2 Copyright (C) 2007 Manolo Valdes <nolis71cu@gmail.com>
3 Copyright (C) 2007 Mark Davies <mark@mcs.vuw.ac.nz>
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"
29 #include <sys/param.h>
30 #include <sys/sysctl.h>
31 #include <sys/types.h>
44 class ProcessesLocal::Private
47 Private() { kd
= kvm_open(NULL
, NULL
, NULL
, KVM_NO_FILES
, "kvm_open");}
48 ~Private() { kvm_close(kd
);}
49 inline bool readProc(long pid
, struct kinfo_proc2
**p
, int *num
);
50 inline void readProcStatus(struct kinfo_proc2
*p
, Process
*process
);
51 inline void readProcStat(struct kinfo_proc2
*p
, Process
*process
);
52 inline void readProcStatm(struct kinfo_proc2
*p
, Process
*process
);
53 inline bool readProcCmdline(struct kinfo_proc2
*p
, Process
*process
);
58 #ifndef _SC_NPROCESSORS_ONLN
59 long int KSysGuard::ProcessesLocal::numberProcessorCores()
69 if (sysctl(mib
, 2, &ncpu
, &len
, NULL
, 0) == -1 || !len
)
75 bool ProcessesLocal::Private::readProc(long pid
, struct kinfo_proc2
**p
, int *num
)
87 *p
= kvm_getproc2(kd
, op
, arg
, sizeof(struct kinfo_proc2
), &len
);
97 void ProcessesLocal::Private::readProcStatus(struct kinfo_proc2
*p
, Process
*process
)
99 process
->setUid(p
->p_ruid
);
100 process
->setEuid(p
->p_uid
);
101 process
->setGid(p
->p_rgid
);
102 process
->setEgid(p
->p_gid
);
103 process
->setTracerpid(0);
105 process
->setName(QString(p
->p_comm
? p
->p_comm
: "????"));
108 void ProcessesLocal::Private::readProcStat(struct kinfo_proc2
*p
, Process
*ps
)
113 ps
->setUserTime(p
->p_uutime_sec
*100+p
->p_uutime_usec
/10000);
114 ps
->setSysTime(p
->p_ustime_sec
*100+p
->p_ustime_usec
/10000);
116 ps
->setUserUsage(100.0 * ((double)(p
->p_pctcpu
) / FSCALE
));
119 ps
->setNiceLevel(p
->p_nice
- NZERO
);
120 ps
->setVmSize((p
->p_vm_tsize
+ p
->p_vm_dsize
+ p
->p_vm_ssize
)
122 ps
->setVmRSS(p
->p_vm_rssize
* getpagesize());
124 // "idle","run","sleep","stop","zombie"
125 switch( p
->p_stat
) {
127 ps
->setStatus(Process::Running
);
130 ps
->setStatus(Process::Sleeping
);
133 ps
->setStatus(Process::Stopped
);
136 ps
->setStatus(Process::Zombie
);
139 ps
->setStatus(Process::Running
);
142 ps
->setStatus(Process::OtherStatus
);
147 if (dev
== NODEV
|| (ttname
= devname(dev
, S_IFCHR
)) == NULL
) {
148 ps
->setTty(QByteArray());
150 ps
->setTty(QByteArray(ttname
));
154 void ProcessesLocal::Private::readProcStatm(struct kinfo_proc2
*p
, Process
*process
)
158 // unsigned long shared;
159 // process->vmURSS = process->vmRSS - (shared * sysconf(_SC_PAGESIZE) / 1024);
160 process
->setVmURSS(-1);
163 bool ProcessesLocal::Private::readProcCmdline(struct kinfo_proc2
*p
, Process
*process
)
167 if ((argv
= kvm_getargv2(kd
, p
, 256)) == NULL
)
170 QString command
= QString("");
177 process
->setCommand(command
.trimmed());
182 ProcessesLocal::ProcessesLocal() : d(new Private())
187 long ProcessesLocal::getParentPid(long pid
) {
189 struct kinfo_proc2
*p
;
190 if(d
->readProc(pid
, &p
, 0))
197 bool ProcessesLocal::updateProcessInfo( long pid
, Process
*process
)
199 struct kinfo_proc2
*p
;
200 if(!d
->readProc(pid
, &p
, NULL
)) return false;
201 d
->readProcStat(p
, process
);
202 d
->readProcStatus(p
, process
);
203 d
->readProcStatm(p
, process
);
204 if(!d
->readProcCmdline(p
, process
)) return false;
209 QSet
<long> ProcessesLocal::getAllPids( )
214 struct kinfo_proc2
*p
;
216 d
->readProc(0, &p
, &len
);
218 for (num
= 0; num
< len
; num
++)
220 long pid
= p
[num
].p_pid
;
221 long long ppid
= p
[num
].p_ppid
;
223 //skip all process with parent id = 0 but init
224 if(ppid
== 0 && pid
!= 1)
231 bool ProcessesLocal::sendSignal(long pid
, int sig
) {
232 if ( kill( (pid_t
)pid
, sig
) ) {
239 bool ProcessesLocal::setNiceness(long pid
, int priority
) {
240 if ( setpriority( PRIO_PROCESS
, pid
, priority
) ) {
241 //set niceness failed
247 bool ProcessesLocal::setScheduler(long pid
, int priorityClass
, int priority
)
249 if(priorityClass
== KSysGuard::Process::Other
|| priorityClass
== KSysGuard::Process::Batch
)
251 if(pid
<= 0) return false; // check the parameters
252 struct sched_param params
;
253 params
.sched_priority
= priority
;
254 switch(priorityClass
) {
255 case (KSysGuard::Process::Other
):
256 return (sched_setscheduler( pid
, SCHED_OTHER
, ¶ms
) == 0);
257 case (KSysGuard::Process::RoundRobin
):
258 return (sched_setscheduler( pid
, SCHED_RR
, ¶ms
) == 0);
259 case (KSysGuard::Process::Fifo
):
260 return (sched_setscheduler( pid
, SCHED_FIFO
, ¶ms
) == 0);
262 case (KSysGuard::Process::Batch
):
263 return (sched_setscheduler( pid
, SCHED_BATCH
, ¶ms
) == 0);
270 bool ProcessesLocal::setIoNiceness(long pid
, int priorityClass
, int priority
) {
271 return false; //Not yet supported
274 bool ProcessesLocal::supportsIoNiceness() {
278 long long ProcessesLocal::totalPhysicalMemory() {
282 len
= sizeof (Total
);
283 sysctlbyname("hw.physmem", &Total
, &len
, NULL
, 0);
284 return Total
/= 1024;
287 ProcessesLocal::~ProcessesLocal()