~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to libs/ksysguard/processcore/processes_dragonfly_p.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is part of the KDE project
 
2
    Copyright (C) 2007 Manolo Valdes <nolis71cu@gmail.com>
 
3
    Copyright (C) 2010 Alex Hornung <ahornung@gmail.com>
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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.
 
19
*/
 
20
 
 
21
#include "processes_local_p.h"
 
22
#include "process.h"
 
23
 
 
24
#include <klocale.h>
 
25
 
 
26
#include <QSet>
 
27
 
 
28
#include <sys/param.h>
 
29
#include <sys/sysctl.h>
 
30
#include <sys/types.h>
 
31
#include <sys/user.h>
 
32
#include <sys/resource.h>
 
33
#include <sys/resourcevar.h>
 
34
#include <err.h>
 
35
#include <signal.h>
 
36
#include <unistd.h>
 
37
#include <stdlib.h>
 
38
#include <sched.h>
 
39
 
 
40
#define PP(pp, field) ((pp)->kp_ ## field)
 
41
#define LP(pp, field) ((pp)->kp_lwp.kl_ ## field)
 
42
#define VP(pp, field) ((pp)->kp_vm_ ## field)
 
43
 
 
44
namespace KSysGuard
 
45
{
 
46
 
 
47
  class ProcessesLocal::Private
 
48
  {
 
49
    public:
 
50
      Private() {}
 
51
      ~Private() {}
 
52
      inline bool readProc(long pid, struct kinfo_proc *p);
 
53
      inline void readProcStatus(struct kinfo_proc *p, Process *process);
 
54
      inline void readProcStat(struct kinfo_proc *p, Process *process);
 
55
      inline void readProcStatm(struct kinfo_proc *p, Process *process);
 
56
      inline bool readProcCmdline(long pid, Process *process);
 
57
    };
 
58
 
 
59
bool ProcessesLocal::Private::readProc(long pid, struct kinfo_proc *p)
 
60
{
 
61
    int mib[4];
 
62
    size_t len;
 
63
 
 
64
    mib[0] = CTL_KERN;
 
65
    mib[1] = KERN_PROC;
 
66
    mib[2] = KERN_PROC_PID;
 
67
    mib[3] = pid;
 
68
 
 
69
    len = sizeof (struct kinfo_proc);
 
70
    if (sysctl(mib, 4, p, &len, NULL, 0) == -1 || !len)
 
71
        return false;
 
72
    return true;
 
73
}
 
74
 
 
75
void ProcessesLocal::Private::readProcStatus(struct kinfo_proc *p, Process *process)
 
76
{
 
77
    process->setUid(0);
 
78
    process->setGid(0);
 
79
    process->setTracerpid(-1);
 
80
 
 
81
    process->setEuid(PP(p, uid));
 
82
    process->setUid(PP(p, ruid));
 
83
    process->setEgid(PP(p, svgid));
 
84
    process->setGid(PP(p, rgid));
 
85
    process->setName(QString(PP(p, comm)));
 
86
}
 
87
 
 
88
void ProcessesLocal::Private::readProcStat(struct kinfo_proc *p, Process *ps)
 
89
{
 
90
    ps->setUserTime(LP(p, uticks) / 10000);
 
91
    ps->setSysTime((LP(p, sticks) + LP(p, iticks)) / 10000);
 
92
    ps->setNiceLevel(PP(p, nice));
 
93
    ps->setVmSize(VP(p, map_size) / 1024); /* convert to KiB */
 
94
    ps->setVmRSS(VP(p, prssize) * getpagesize() / 1024); /* convert to KiB */
 
95
 
 
96
// "idle","run","sleep","stop","zombie"
 
97
    switch( LP(p, stat) ) {
 
98
      case LSRUN:
 
99
        ps->setStatus(Process::Running);
 
100
        break;
 
101
      case LSSLEEP:
 
102
        ps->setStatus(Process::Sleeping);
 
103
        break;
 
104
      case LSSTOP:
 
105
        ps->setStatus(Process::Stopped);
 
106
        break;
 
107
      default:
 
108
        ps->setStatus(Process::OtherStatus);
 
109
        break;
 
110
    }
 
111
    if (PP(p, stat) == SZOMB)
 
112
        ps->setStatus(Process::Zombie);
 
113
}
 
114
 
 
115
void ProcessesLocal::Private::readProcStatm(struct kinfo_proc *p, Process *process)
 
116
{
 
117
    process->setVmURSS(-1);
 
118
}
 
119
 
 
120
bool ProcessesLocal::Private::readProcCmdline(long pid, Process *process)
 
121
{
 
122
    int mib[4];
 
123
    size_t buflen = 256;
 
124
    char buf[256];
 
125
 
 
126
    mib[0] = CTL_KERN;
 
127
    mib[1] = KERN_PROC;
 
128
    mib[2] = KERN_PROC_ARGS;
 
129
    mib[3] = pid;
 
130
 
 
131
    if (sysctl(mib, 4, buf, &buflen, NULL, 0) == -1 || (buflen == 0))
 
132
        return false;
 
133
    QString command = QString(buf);
 
134
 
 
135
    //cmdline seperates parameters with the NULL character
 
136
    command = command.replace('\0', ' ');
 
137
    process->setCommand(command.trimmed());
 
138
 
 
139
    return true;
 
140
}
 
141
 
 
142
ProcessesLocal::ProcessesLocal() : d(new Private())
 
143
{
 
144
}
 
145
 
 
146
long ProcessesLocal::getParentPid(long pid)
 
147
{
 
148
    long long ppid = -1;
 
149
    struct kinfo_proc p;
 
150
 
 
151
    if(d->readProc(pid, &p))
 
152
        ppid = PP(&p, ppid);
 
153
 
 
154
    return ppid;
 
155
}
 
156
 
 
157
bool ProcessesLocal::updateProcessInfo( long pid, Process *process)
 
158
{
 
159
    struct kinfo_proc p;
 
160
 
 
161
    if(!d->readProc(pid, &p)) {
 
162
        return false;
 
163
    }
 
164
 
 
165
    d->readProcStat(&p, process);
 
166
    d->readProcStatus(&p, process);
 
167
    d->readProcStatm(&p, process);
 
168
    if(!d->readProcCmdline(pid, process)) {
 
169
        return false;
 
170
    }
 
171
 
 
172
    return true;
 
173
}
 
174
 
 
175
QSet<long> ProcessesLocal::getAllPids( )
 
176
{
 
177
    QSet<long> pids;
 
178
    int mib[3];
 
179
    size_t len;
 
180
    size_t num;
 
181
    struct kinfo_proc *p;
 
182
 
 
183
    mib[0] = CTL_KERN;
 
184
    mib[1] = KERN_PROC;
 
185
    mib[2] = KERN_PROC_ALL;
 
186
    if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1)
 
187
        return pids;
 
188
    if ((p = (kinfo_proc *) malloc(len)) == NULL)
 
189
        return pids;
 
190
    if (sysctl(mib, 3, p, &len, NULL, 0) == -1) {
 
191
        free(p);
 
192
        return pids;
 
193
    }
 
194
 
 
195
    for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
 
196
    {
 
197
        long pid = PP((&p[num]), pid);
 
198
        long long ppid = PP((&p[num]), ppid);
 
199
 
 
200
        //skip all process with parent id = 0 but init
 
201
        if(ppid <= 0 && pid != 1)
 
202
            continue;
 
203
        pids.insert(pid);
 
204
    }
 
205
    free(p);
 
206
    return pids;
 
207
}
 
208
 
 
209
bool ProcessesLocal::sendSignal(long pid, int sig) {
 
210
    if ( kill( (pid_t)pid, sig ) ) {
 
211
        //Kill failed
 
212
        return false;
 
213
    }
 
214
    return true;
 
215
}
 
216
 
 
217
bool ProcessesLocal::setNiceness(long pid, int priority) {
 
218
    if ( setpriority( PRIO_PROCESS, pid, priority ) ) {
 
219
            //set niceness failed
 
220
            return false;
 
221
    }
 
222
    return true;
 
223
}
 
224
 
 
225
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
 
226
{
 
227
    if(priorityClass == KSysGuard::Process::Other || priorityClass == KSysGuard::Process::Batch)
 
228
            priority = 0;
 
229
    if(pid <= 0) return false; // check the parameters
 
230
    struct sched_param params;
 
231
    params.sched_priority = priority;
 
232
    switch(priorityClass) {
 
233
      case (KSysGuard::Process::Other):
 
234
            return (sched_setscheduler( pid, SCHED_OTHER, &params) == 0);
 
235
      case (KSysGuard::Process::RoundRobin):
 
236
            return (sched_setscheduler( pid, SCHED_RR, &params) == 0);
 
237
      case (KSysGuard::Process::Fifo):
 
238
            return (sched_setscheduler( pid, SCHED_FIFO, &params) == 0);
 
239
#ifdef SCHED_BATCH
 
240
      case (KSysGuard::Process::Batch):
 
241
            return (sched_setscheduler( pid, SCHED_BATCH, &params) == 0);
 
242
#endif
 
243
      default:
 
244
            return false;
 
245
    }
 
246
}
 
247
 
 
248
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
 
249
    return false; //Not yet supported
 
250
}
 
251
 
 
252
bool ProcessesLocal::supportsIoNiceness() {
 
253
    return false;
 
254
}
 
255
 
 
256
long long ProcessesLocal::totalPhysicalMemory() {
 
257
 
 
258
    size_t Total;
 
259
    size_t len;
 
260
 
 
261
    len = sizeof (Total);
 
262
    if (sysctlbyname("hw.physmem", &Total, &len, NULL, 0) == -1)
 
263
        return 0;
 
264
 
 
265
    Total *= getpagesize() / 1024;
 
266
    return Total;
 
267
}
 
268
 
 
269
ProcessesLocal::~ProcessesLocal()
 
270
{
 
271
   delete d;
 
272
}
 
273
 
 
274
}