1
/* This file is part of the KDE project
2
Copyright (C) 2007 Adriaan de Groot <groot@kde.org>
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
/* Stop <sys/procfs.h> from crapping out on 32-bit architectures. */
22
#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
23
# undef _FILE_OFFSET_BITS
24
# define _FILE_OFFSET_BITS 32
27
#include "processes_local_p.h"
35
#include <sys/param.h>
36
#include <sys/types.h>
38
#include <sys/resource.h>
50
#include <sys/resource.h>
52
#define PROCESS_BUFFER_SIZE 512
53
#define PROCDIR "/proc"
58
class ProcessesLocal::Private
61
Private() { mProcDir = opendir( PROCDIR ); };
63
char mBuf[PROCESS_BUFFER_SIZE+1]; //used as a buffer to read data into
67
ProcessesLocal::ProcessesLocal() : d(new Private())
71
long ProcessesLocal::getParentPid(long pid) {
76
snprintf( d->mBuf, PROCESS_BUFFER_SIZE - 1, "%s/%ld/psinfo", PROCDIR, pid );
77
if( (fd = open( d->mBuf, O_RDONLY )) < 0 ) {
78
return -1; /* process has terminated in the meantime */
81
if( read( fd, &psinfo, sizeof( psinfo_t )) != sizeof( psinfo_t )) {
86
ppid = psinfo.pr_ppid;
91
bool ProcessesLocal::updateProcessInfo( long pid, Process *process)
97
snprintf( d->mBuf, PROCESS_BUFFER_SIZE - 1, "%s/%ld/psinfo", PROCDIR, pid );
98
if( (fd = open( d->mBuf, O_RDONLY )) < 0 ) {
99
return false; /* process has terminated in the meantime */
102
snprintf( d->mBuf, PROCESS_BUFFER_SIZE - 1, "%s/%ld/usage", PROCDIR, pid );
103
if( (pfd = open( d->mBuf, O_RDONLY )) < 0 ) {
105
return false; /* process has terminated in the meantime */
110
process->tracerpid = -1;
113
if( read( fd, &psinfo, sizeof( psinfo_t )) != sizeof( psinfo_t )) {
119
if( read( pfd, &prusage, sizeof( prusage_t )) != sizeof( prusage_t )) {
125
process->setUid( psinfo.pr_uid );
126
process->setEuid( psinfo.pr_euid );
127
process->setGid( psinfo.pr_gid );
128
process->setEgid( psinfo.pr_egid );
130
switch( (int) psinfo.pr_lwp.pr_state ) {
134
process->setStatus(Process::Sleeping);
138
process->setStatus(Process::Running);
141
process->setStatus(Process::Zombie);
144
process->setStatus(Process::Stopped);
147
process->setStatus(Process::OtherStatus);
151
process->setVmRSS(psinfo.pr_rssize);
152
process->setVmSize(psinfo.pr_size);
153
process->setVmURSS(-1);
155
if (process->command.isNull()) {
156
QString name(psinfo.pr_fname);
158
name = name.trimmed();
159
if(!name.isEmpty()) {
160
name.remove(QRegExp("^[^ ]*/"));
162
process->setName(name);
163
name = psinfo.pr_fname;
164
name.append(psinfo.pr_psargs);
165
process->setCommand(name);
168
// Approximations, not quite accurate. Needs more changes in ksysguard to map
169
// RR and FIFO to current Solaris classes.
170
if (strcmp(psinfo.pr_lwp.pr_clname, "TS") == 0 || strcmp(psinfo.pr_lwp.pr_clname, "SYS") == 0 ||
171
strcmp(psinfo.pr_lwp.pr_clname, "FSS") == 0) {
172
process->setscheduler( KSysGuard::Process::Other );
174
} else if (strcmp(psinfo.pr_lwp.pr_clname, "FX") == 0 || strcmp(psinfo.pr_lwp.pr_clname, "RT") == 0) {
175
process->setscheduler( KSysGuard::Process::RoundRobin );
177
} else if (strcmp(psinfo.pr_lwp.pr_clname, "IA") == 0) {
178
process->setscheduler( KSysGuard::Process::Interactive );
180
process->setNiceLevel( psinfo.pr_lwp.pr_pri );
181
process->setUserTime( prusage.pr_utime.tv_sec * 100 + prusage.pr_utime.tv_nsec / 10000000.0);
182
process->setSysTime( prusage.pr_stime.tv_sec * 100 + prusage.pr_stime.tv_nsec / 10000000.0);
186
QSet<long> ProcessesLocal::getAllPids( )
191
if(d->mProcDir==NULL) return pids; //There's not much we can do without /proc
192
struct dirent* entry;
193
rewinddir(d->mProcDir);
194
while ( ( entry = readdir( d->mProcDir ) ) )
195
if ( entry->d_name[ 0 ] >= '0' && entry->d_name[ 0 ] <= '9' ) {
196
pid = atol( entry->d_name );
197
// Skip all processes with parent id = 0 except init
198
if (pid == 1 || getParentPid(pid) > 0) {
205
bool ProcessesLocal::sendSignal(long pid, int sig) {
206
if ( kill( (pid_t)pid, sig ) ) {
216
bool ProcessesLocal::setNiceness(long pid, int priority) {
220
bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
225
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
226
return false; //Not yet supported
229
bool ProcessesLocal::supportsIoNiceness() {
233
long long ProcessesLocal::totalPhysicalMemory() {
234
long long memory = ((long long)sysconf(_SC_PHYS_PAGES)) * (sysconf(_SC_PAGESIZE)/1024);
235
if(memory > 0) return memory;
239
ProcessesLocal::~ProcessesLocal()