1 /* This file is part of the KDE project
3 Copyright (C) 2007 John Tapsell <tapsell@kde.org>
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_remote_p.h"
38 class ProcessesRemote::Private
41 Private() {havePsInfo
= false; pidColumn
= 1;
42 ppidColumn
= nameColumn
= uidColumn
= gidColumn
=
43 statusColumn
= userColumn
= systemColumn
= niceColumn
=
44 vmSizeColumn
= vmRSSColumn
= loginColumn
= commandColumn
=
45 tracerPidColumn
= ttyColumn
= ioprioClassColumn
= ioprioColumn
=
47 usedMemory
= freeMemory
;}
50 QList
<QByteArray
> lastAnswer
;
52 QHash
<long, QList
<QByteArray
> > processByPid
;
70 int ioprioClassColumn
;
80 ProcessesRemote::ProcessesRemote(const QString
&hostname
) : d(new Private())
83 QTimer::singleShot(0, this, SLOT(setup()));
86 void ProcessesRemote::setup() {
87 emit
runCommand("mem/physical/used", (int)UsedMemory
);
88 emit
runCommand("mem/physical/free", (int)FreeMemory
);
89 emit
runCommand("ps?", (int)PsInfo
);
90 emit
runCommand("ps", (int)Ps
);
94 long ProcessesRemote::getParentPid(long pid
) {
95 if(!d
->processByPid
.contains(pid
)) {
96 kDebug() << "Parent pid requested for pid that we do not have info on " << pid
;
99 if(d
->ppidColumn
== -1) {
100 kDebug() << "ppid column not known ";
103 return d
->processByPid
[pid
].at(d
->ppidColumn
).toLong();
105 bool ProcessesRemote::updateProcessInfo( long pid
, Process
*process
)
107 Q_CHECK_PTR(process
);
108 if(!d
->processByPid
.contains(pid
)) {
109 kDebug() << "update request for pid that we do not have info on " << pid
;
112 QList
<QByteArray
> p
= d
->processByPid
[pid
];
114 if(d
->nameColumn
!= -1) process
->setName(p
.at(d
->nameColumn
));
115 if(d
->uidColumn
!= -1) process
->setUid(p
.at(d
->uidColumn
).toLong());
116 if(d
->gidColumn
!= -1) process
->setGid(p
.at(d
->gidColumn
).toLong());
117 if(d
->statusColumn
!= -1) {
118 switch( p
.at(d
->statusColumn
)[0] ) {
120 process
->setStatus(Process::Sleeping
);
123 process
->setStatus(Process::Running
);
127 if(d
->userColumn
!= -1) process
->setUserTime(p
.at(d
->userColumn
).toLong());
128 if(d
->systemColumn
!= -1) process
->setSysTime(p
.at(d
->systemColumn
).toLong());
129 if(d
->niceColumn
!= -1) process
->setNiceLevel(p
.at(d
->niceColumn
).toLong());
130 if(d
->vmSizeColumn
!= -1) process
->setVmSize(p
.at(d
->vmSizeColumn
).toLong());
131 if(d
->vmRSSColumn
!= -1) process
->setVmRSS(p
.at(d
->vmRSSColumn
).toLong());
132 if(d
->vmURSSColumn
!= -1) process
->setVmURSS(p
.at(d
->vmURSSColumn
).toLong());
133 if(d
->loginColumn
!= -1) process
->setLogin(QString::fromUtf8(p
.at(d
->loginColumn
).data()));
134 if(d
->commandColumn
!= -1) process
->setCommand(QString::fromUtf8(p
.at(d
->commandColumn
).data()));
135 if(d
->tracerPidColumn
!= -1) process
->setTracerpid(p
.at(d
->tracerPidColumn
).toLong());
136 if(d
->vmURSSColumn
!= -1) process
->setVmURSS(p
.at(d
->vmURSSColumn
).toLong());
137 if(d
->ttyColumn
!= -1) process
->setTty(p
.at(d
->ttyColumn
));
138 if(d
->ioprioColumn
!= -1) process
->setIoniceLevel(p
.at(d
->ioprioColumn
).toInt());
139 if(d
->ioprioClassColumn
!= -1) process
->setIoPriorityClass((KSysGuard::Process::IoPriorityClass
)(p
.at(d
->ioprioClassColumn
).toInt()));
144 void ProcessesRemote::updateAllProcesses()
147 emit
runCommand("ps?", (int)PsInfo
);
148 emit
runCommand("ps", (int)Ps
);
150 QSet
<long> ProcessesRemote::getAllPids( )
153 d
->processByPid
.clear();
154 foreach(const QByteArray
&process
, d
->lastAnswer
) {
155 QList
<QByteArray
> info
= process
.split('\t');
156 if(info
.size() == d
->numColumns
) {
157 int pid
= info
.at(d
->pidColumn
).toLong();
158 Q_ASSERT(! d
->pids
.contains(pid
));
160 d
->processByPid
[pid
] = info
;
166 bool ProcessesRemote::sendSignal(long pid
, int sig
) {
167 //TODO run the proper command for all these functions below
168 emit
runCommand("kill " + QString::number(pid
) + " " + QString::number(sig
), (int)Kill
);
171 bool ProcessesRemote::setNiceness(long pid
, int priority
) {
172 emit
runCommand("setpriority " + QString::number(pid
) + " " + QString::number(priority
), (int)Renice
);
176 bool ProcessesRemote::setIoNiceness(long pid
, int priorityClass
, int priority
) {
177 emit
runCommand("ionice " + QString::number(pid
) + " " + QString::number(priorityClass
) + " " + QString::number(priority
), (int)Ionice
);
181 bool ProcessesRemote::setScheduler(long pid
, int priorityClass
, int priority
) {
185 bool ProcessesRemote::supportsIoNiceness() {
189 long long ProcessesRemote::totalPhysicalMemory() {
190 return d
->usedMemory
+ d
->freeMemory
;
192 long ProcessesRemote::numberProcessorCores() {
196 void ProcessesRemote::answerReceived( int id
, const QList
<QByteArray
>& answer
) {
199 if(answer
.isEmpty()) return; //Invalid data
200 QList
<QByteArray
> info
= answer
.at(0).split('\t');
201 d
->numColumns
= info
.size();
202 for(int i
=0; i
< d
->numColumns
; i
++) {
203 if(info
[i
] == "Name")
205 else if(info
[i
] == "PID")
207 else if(info
[i
] == "PPID")
209 else if(info
[i
] == "UID")
211 else if(info
[i
] == "GID")
213 else if(info
[i
] == "TracerPID")
214 d
->tracerPidColumn
= i
;
215 else if(info
[i
] == "Status")
217 else if(info
[i
] == "User Time")
219 else if(info
[i
] == "System Time")
221 else if(info
[i
] == "Nice")
223 else if(info
[i
] == "VmSize")
225 else if(info
[i
] == "VmRss")
227 else if(info
[i
] == "VmURss")
229 else if(info
[i
] == "Login")
231 else if(info
[i
] == "TTY")
233 else if(info
[i
] == "Command")
234 d
->commandColumn
= i
;
235 else if(info
[i
] == "IO Priority Class")
236 d
->ioprioClassColumn
= i
;
237 else if(info
[i
] == "IO Priority")
240 d
->havePsInfo
= true;
244 d
->lastAnswer
= answer
;
245 if(!d
->havePsInfo
) return; //Not setup yet. Should never happen
246 emit
processesUpdated();
248 if(answer
.isEmpty()) return; //Invalid data
249 d
->freeMemory
= answer
[0].toLong();
252 if(answer
.isEmpty()) return; //Invalid data
253 d
->usedMemory
= answer
[0].toLong();
259 ProcessesRemote::~ProcessesRemote()
266 #include "processes_remote_p.moc"