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(0);
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()