add more spacing
[personal-kdebase.git] / workspace / libs / ksysguard / processcore / processes_freebsd_p.cpp
blob0cec1c2fd581546081630834f1d1a5c3b48031d5
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"
21 #include "process.h"
23 #include <klocale.h>
25 #include <QSet>
27 #include <sys/param.h>
28 #include <sys/sysctl.h>
29 #include <sys/types.h>
30 #include <sys/user.h>
31 #include <sys/resource.h>
32 #if defined(__DragonFly__)
33 #include <sys/resourcevar.h>
34 #include <err.h>
35 #endif
36 #include <signal.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <sched.h>
43 namespace KSysGuard
46 class ProcessesLocal::Private
48 public:
49 Private() {;}
50 ~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)
60 int mib[4];
61 size_t len;
63 mib[0] = CTL_KERN;
64 mib[1] = KERN_PROC;
65 mib[2] = KERN_PROC_PID;
66 mib[3] = pid;
68 len = sizeof (struct kinfo_proc);
69 if (sysctl(mib, 4, p, &len, NULL, 0) == -1 || !len)
70 return false;
71 return true;
74 void ProcessesLocal::Private::readProcStatus(struct kinfo_proc *p, Process *process)
76 process->setUid(0);
77 process->setGid(0);
78 process->setTracerpid(0);
81 #if defined(__FreeBSD__)
82 process->setEuid(p->ki_uid);
83 process->setUid(p->ki_ruid);
84 process->setEgid(p->ki_svgid);
85 process->setGid(p->ki_rgid);
86 process->setName(QString(p->ki_comm ? p->ki_comm : "????"));
87 #elif defined(__DragonFly__) && __DragonFly_version >= 190000
88 process->setUid(p->kp_uid);
89 process->setGid(p->kp_pgid);
90 process->setName(QString(p->kp_comm ? p->kp_comm : "????"));
91 #else
92 process->setUid(p->kp_eproc.e_ucred.cr_uid);
93 process->setGid(p->kp_eproc.e_pgid);
94 #endif
97 void ProcessesLocal::Private::readProcStat(struct kinfo_proc *p, Process *ps)
99 int status;
100 struct rusage pru;
101 #if defined(__FreeBSD__)
102 ps->setUserTime(p->ki_rusage.ru_utime.tv_sec * 100 + p->ki_rusage.ru_utime.tv_usec / 10000);
103 ps->setSysTime(p->ki_rusage.ru_stime.tv_sec * 100 + p->ki_rusage.ru_stime.tv_usec / 10000);
104 ps->setNiceLevel(p->ki_nice);
105 ps->setVmSize(p->ki_size / 1024);
106 ps->setVmRSS(p->ki_rssize * getpagesize() / 1024);
107 status = p->ki_stat;
108 #elif defined(__DragonFly__)
109 #if __DragonFly_version >= 190000
110 if (!getrusage(p->kp_pid, &pru)) {
111 errx(1, "failed to get rusage info");
113 ps->setUserTime(pru.ru_utime.tv_usec / 1000); /*p_runtime / 1000*/
114 ps->setNiceLevel(p->kp_nice);
115 ps->setVmSize(p->kp_vm_map_size);
116 ps->setVmRSS(p->kp_vm_rssize * getpagesize());
117 status = p->kp_stat;
118 #else
119 ps->setUserTime(p->kp_proc.p_rtime.tv_sec*100+p->kp_proc.p_rtime.tv_usec/100);
120 ps->setNiceLevel(p->kp_proc.p_nice);
121 ps->setVmSize(p->kp_eproc.e_vm.vm_map.size);
122 ps->setVmRSS(p->kp_eproc.e_vm.vm_rssize * getpagesize());
123 status = p->kp_proc.p_stat;
124 #endif
125 ps->setSysTime(0);
126 #endif
128 // "idle","run","sleep","stop","zombie"
129 switch( status ) {
130 case SRUN:
131 ps->setStatus(Process::Running);
132 break;
133 case SSLEEP:
134 case SWAIT:
135 case SLOCK:
136 ps->setStatus(Process::Sleeping);
137 break;
138 case SSTOP:
139 ps->setStatus(Process::Stopped);
140 break;
141 case SZOMB:
142 ps->setStatus(Process::Zombie);
143 break;
144 default:
145 ps->setStatus(Process::OtherStatus);
146 break;
150 void ProcessesLocal::Private::readProcStatm(struct kinfo_proc *p, Process *process)
152 process->setVmURSS(-1);
155 bool ProcessesLocal::Private::readProcCmdline(long pid, Process *process)
157 int mib[4];
158 struct kinfo_proc p;
159 size_t buflen = 256;
160 char buf[256];
162 mib[0] = CTL_KERN;
163 mib[1] = KERN_PROC;
164 mib[2] = KERN_PROC_ARGS;
165 mib[3] = pid;
167 if (sysctl(mib, 4, buf, &buflen, NULL, 0) == -1 || !buflen)
168 return false;
169 QString command = QString(buf);
171 //cmdline seperates parameters with the NULL character
172 command = command.replace('\0', ' ');
173 process->setCommand(command.trimmed());
175 return true;
178 ProcessesLocal::ProcessesLocal() : d(new Private())
183 long ProcessesLocal::getParentPid(long pid) {
184 long long ppid = 0;
185 struct kinfo_proc p;
186 if(d->readProc(pid, &p))
188 #if defined(__FreeBSD__)
189 ppid = p.ki_ppid;
190 #elif defined(__DragonFly__) && __DragonFly_version >= 190000
191 ppid = p.kp_ppid;
192 #else
193 ppid = p.kp_eproc.e_ppid;
194 #endif
196 return ppid;
199 bool ProcessesLocal::updateProcessInfo( long pid, Process *process)
201 struct kinfo_proc p;
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;
208 return true;
211 QSet<long> ProcessesLocal::getAllPids( )
213 QSet<long> pids;
214 int mib[3];
215 size_t len;
216 size_t num;
217 struct kinfo_proc *p;
219 mib[0] = CTL_KERN;
220 mib[1] = KERN_PROC;
221 mib[2] = KERN_PROC_ALL;
222 if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1)
223 return pids;
224 if ((p = (kinfo_proc *) malloc(len)) == NULL)
225 return pids;
226 if (sysctl(mib, 3, p, &len, NULL, 0) == -1) {
227 free(p);
228 return pids;
231 for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
233 #if defined(__FreeBSD__)
234 long pid = p[num].ki_pid;
235 long long ppid = p[num].ki_ppid;
236 #elif defined(__DragonFly__) && __DragonFly_version >= 190000
237 long pid = p[num].kp_pid;
238 long long ppid = p[num].kp_ppid;
239 #else
240 long pid = p[num].kp_proc.p_pid;
241 long long ppid = p[num].kp_eproc.e_ppid;
242 #endif
243 //skip all process with parent id = 0 but init
244 if(ppid == 0 && pid != 1)
245 continue;
246 pids.insert(pid);
248 free(p);
249 return pids;
252 bool ProcessesLocal::sendSignal(long pid, int sig) {
253 if ( kill( (pid_t)pid, sig ) ) {
254 //Kill failed
255 return false;
257 return true;
260 bool ProcessesLocal::setNiceness(long pid, int priority) {
261 if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
262 //set niceness failed
263 return false;
265 return true;
268 bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
270 if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
271 priority = 0;
272 if(pid <= 0) return false; // check the parameters
273 struct sched_param params;
274 params.sched_priority = priority;
275 switch(priorityClass) {
276 case (KSysGuard::Process::Other):
277 return (sched_setscheduler( pid, SCHED_OTHER, &params) == 0);
278 case (KSysGuard::Process::RoundRobin):
279 return (sched_setscheduler( pid, SCHED_RR, &params) == 0);
280 case (KSysGuard::Process::Fifo):
281 return (sched_setscheduler( pid, SCHED_FIFO, &params) == 0);
282 #ifdef SCHED_BATCH
283 case (KSysGuard::Process::Batch):
284 return (sched_setscheduler( pid, SCHED_BATCH, &params) == 0);
285 #endif
286 default:
287 return false;
291 bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
292 return false; //Not yet supported
295 bool ProcessesLocal::supportsIoNiceness() {
296 return false;
299 long long ProcessesLocal::totalPhysicalMemory() {
301 size_t Total;
302 size_t len;
304 len = sizeof (Total);
305 if (sysctlbyname("hw.physmem", &Total, &len, NULL, 0) == -1)
306 return 0;
308 return Total /= 1024;
311 ProcessesLocal::~ProcessesLocal()
313 delete d;