Changeset View
Changeset View
Standalone View
Standalone View
processcore/processes_linux_p.cpp
Context not available. | |||||
29 | #include <QSet> | 29 | #include <QSet> | ||
---|---|---|---|---|---|
30 | #include <QByteArray> | 30 | #include <QByteArray> | ||
31 | #include <QTextStream> | 31 | #include <QTextStream> | ||
32 | #include <QRegularExpression> | ||||
32 | 33 | | |||
33 | //for sysconf | 34 | //for sysconf | ||
34 | #include <unistd.h> | 35 | #include <unistd.h> | ||
Context not available. | |||||
115 | inline bool readProcCGroup(const QString &dir, Process *process); | 116 | inline bool readProcCGroup(const QString &dir, Process *process); | ||
116 | inline bool readProcAttr(const QString &dir, Process *process); | 117 | inline bool readProcAttr(const QString &dir, Process *process); | ||
117 | inline bool readProcSmaps(const QString &dir, Process *process); | 118 | inline bool readProcSmaps(const QString &dir, Process *process); | ||
119 | inline bool readProcSMapsDetails(const QString &dir, Process *process); | ||||
118 | inline bool getNiceness(long pid, Process *process); | 120 | inline bool getNiceness(long pid, Process *process); | ||
119 | inline bool getIOStatistics(const QString &dir, Process *process); | 121 | inline bool getIOStatistics(const QString &dir, Process *process); | ||
120 | QFile mFile; | 122 | QFile mFile; | ||
Context not available. | |||||
144 | process->setNoNewPrivileges(0); | 146 | process->setNoNewPrivileges(0); | ||
145 | 147 | | |||
146 | int size; | 148 | int size; | ||
149 | const int goalFields = 7; | ||||
147 | int found = 0; //count how many fields we found | 150 | int found = 0; //count how many fields we found | ||
148 | while( (size = mFile.readLine( mBuffer, sizeof(mBuffer))) > 0) { //-1 indicates an error | 151 | while( (size = mFile.readLine( mBuffer, sizeof(mBuffer))) > 0) { //-1 indicates an error | ||
149 | switch( mBuffer[0]) { | 152 | switch( mBuffer[0]) { | ||
Context not available. | |||||
151 | if((unsigned int)size > sizeof("Name:") && qstrncmp(mBuffer, "Name:", sizeof("Name:")-1) == 0) { | 154 | if((unsigned int)size > sizeof("Name:") && qstrncmp(mBuffer, "Name:", sizeof("Name:")-1) == 0) { | ||
152 | if(process->command().isEmpty()) | 155 | if(process->command().isEmpty()) | ||
153 | process->setName(QString::fromLocal8Bit(mBuffer + sizeof("Name:")-1, size-sizeof("Name:")+1).trimmed()); | 156 | process->setName(QString::fromLocal8Bit(mBuffer + sizeof("Name:")-1, size-sizeof("Name:")+1).trimmed()); | ||
154 | if(++found == 6) goto finish; | 157 | if(++found == goalFields) goto finish; | ||
155 | } else if((unsigned int)size > sizeof("NoNewPrivs:") && qstrncmp(mBuffer, "NoNewPrivs:", sizeof("NoNewPrivs:")-1) == 0) { | 158 | } else if((unsigned int)size > sizeof("NoNewPrivs:") && qstrncmp(mBuffer, "NoNewPrivs:", sizeof("NoNewPrivs:")-1) == 0) { | ||
156 | process->setNoNewPrivileges(atol(mBuffer + sizeof("NoNewPrivs:")-1)); | 159 | process->setNoNewPrivileges(atol(mBuffer + sizeof("NoNewPrivs:")-1)); | ||
157 | if(++found == 6) goto finish; | 160 | if(++found == goalFields) goto finish; | ||
158 | } | 161 | } | ||
159 | break; | 162 | break; | ||
160 | case 'U': | 163 | case 'U': | ||
Context not available. | |||||
168 | process->setEuid(euid); | 171 | process->setEuid(euid); | ||
169 | process->setSuid(suid); | 172 | process->setSuid(suid); | ||
170 | process->setFsuid(fsuid); | 173 | process->setFsuid(fsuid); | ||
171 | if(++found == 6) goto finish; | 174 | if(++found == goalFields) goto finish; | ||
172 | } | 175 | } | ||
173 | break; | 176 | break; | ||
174 | case 'G': | 177 | case 'G': | ||
Context not available. | |||||
179 | process->setEgid(egid); | 182 | process->setEgid(egid); | ||
180 | process->setSgid(sgid); | 183 | process->setSgid(sgid); | ||
181 | process->setFsgid(fsgid); | 184 | process->setFsgid(fsgid); | ||
182 | if(++found == 6) goto finish; | 185 | if(++found == goalFields) goto finish; | ||
183 | } | 186 | } | ||
184 | break; | 187 | break; | ||
185 | case 'T': | 188 | case 'T': | ||
Context not available. | |||||
187 | process->setTracerpid(atol(mBuffer + sizeof("TracerPid:")-1)); | 190 | process->setTracerpid(atol(mBuffer + sizeof("TracerPid:")-1)); | ||
188 | if (process->tracerpid() == 0) | 191 | if (process->tracerpid() == 0) | ||
189 | process->setTracerpid(-1); | 192 | process->setTracerpid(-1); | ||
190 | if(++found == 6) goto finish; | 193 | if(++found == goalFields) goto finish; | ||
191 | } else if((unsigned int)size > sizeof("Threads:") && qstrncmp(mBuffer, "Threads:", sizeof("Threads:")-1) == 0) { | 194 | } else if((unsigned int)size > sizeof("Threads:") && qstrncmp(mBuffer, "Threads:", sizeof("Threads:")-1) == 0) { | ||
192 | process->setNumThreads(atol(mBuffer + sizeof("Threads:")-1)); | 195 | process->setNumThreads(atol(mBuffer + sizeof("Threads:")-1)); | ||
193 | if(++found == 6) goto finish; | 196 | if(++found == goalFields) goto finish; | ||
194 | } | 197 | } | ||
195 | break; | 198 | break; | ||
199 | case 'v': | ||||
200 | if((unsigned int)size > sizeof("voluntary_ctxt_switches:") && qstrncmp(mBuffer, "voluntary_ctxt_switches:", sizeof("voluntary_ctxt_switches:")-1) == 0) { | ||||
201 | process->setVoluntaryCtxSwitches(atol(mBuffer + sizeof("voluntary_ctxt_switches:")-1)); | ||||
202 | if(++found == goalFields) goto finish; | ||||
203 | } | ||||
204 | break; | ||||
205 | case 'n': | ||||
206 | if((unsigned int)size > sizeof("nonvoluntary_ctxt_switches:") && qstrncmp(mBuffer, "nonvoluntary_ctxt_switches:", sizeof("voluntary_ctxt_switches:")-1) == 0) { | ||||
207 | process->setNonvoluntaryCtxSwitches(atol(mBuffer + sizeof("nonvoluntary_ctxt_switches:")-1)); | ||||
208 | if(++found == goalFields) goto finish; | ||||
209 | } | ||||
210 | break; | ||||
196 | default: | 211 | default: | ||
197 | break; | 212 | break; | ||
198 | } | 213 | } | ||
199 | } | 214 | } | ||
200 | 215 | | |||
201 | finish: | 216 | finish: | ||
Context not available. | |||||
327 | } | 342 | } | ||
328 | } | 343 | } | ||
329 | break; | 344 | break; | ||
345 | case 9: //minFlt | ||||
346 | ps->setMinFlt(atoll(word+1)); | ||||
347 | break; | ||||
348 | case 11: //majFlt | ||||
349 | ps->setMajFlt(atoll(word+1)); | ||||
350 | break; | ||||
330 | case 13: //userTime | 351 | case 13: //userTime | ||
331 | ps->setUserTime(atoll(word+1)); | 352 | ps->setUserTime(atoll(word+1)); | ||
332 | break; | 353 | break; | ||
Context not available. | |||||
477 | return true; | 498 | return true; | ||
478 | } | 499 | } | ||
479 | 500 | | |||
501 | bool ProcessesLocal::Private::readProcSMapsDetails(const QString &dir, Process *process) | ||||
502 | { | ||||
503 | if (!process->memmapRequested()) { | ||||
504 | return true; //if memmap is not requested, do nothing. | ||||
505 | } | ||||
506 | process->memmap().clear(); | ||||
507 | mFile.setFileName(dir + QStringLiteral("smaps")); | ||||
508 | if(!mFile.open(QIODevice::ReadOnly)) { | ||||
509 | return true; //this function never fails. Empty memmap vector indicates permission denied. | ||||
510 | } | ||||
511 | process->memmap().push_back(QVector<QString>()); | ||||
512 | process->memmap()[0].push_back(QString::fromUtf8("Address")); | ||||
513 | process->memmap()[0].push_back(QString::fromUtf8("Permission")); | ||||
514 | process->memmap()[0].push_back(QString::fromUtf8("Filename")); | ||||
515 | | ||||
516 | QRegularExpression head_rx(QString::fromUtf8("^([0-9A-Fa-f]+-[0-9A-Fa-f]+) +([rwxp\\-]*) +([0-9A-Fa-f]+) +([0-9A-Fa-f]+:[0-9A-Fa-f]+) +(\\d+) +(.*)$")); | ||||
517 | QRegularExpression line_rx(QString::fromUtf8("^([^ ]+): +(.*)$")); | ||||
518 | | ||||
519 | int size; | ||||
520 | int first = 1; | ||||
521 | | ||||
522 | while ( (size = mFile.readLine( mBuffer, sizeof(mBuffer))) > 0) { //-1 indicates an error | ||||
523 | QRegularExpressionMatch head_rxm = head_rx.match(QString::fromUtf8(mBuffer)); | ||||
524 | if (head_rxm.hasMatch()) { | ||||
525 | if (first == 2) { | ||||
526 | first = 0; | ||||
527 | } else if(first == 1) { | ||||
528 | first = 2; | ||||
529 | } | ||||
530 | | ||||
531 | process->memmap().push_back(QVector<QString>()); | ||||
532 | process->memmap().back().push_back(head_rxm.captured(1).trimmed()); | ||||
533 | process->memmap().back().push_back(head_rxm.captured(2).trimmed()); | ||||
534 | process->memmap().back().push_back(head_rxm.captured(6).trimmed()); | ||||
535 | } else { | ||||
536 | QRegularExpressionMatch line_rxm = line_rx.match(QString::fromUtf8(mBuffer)); | ||||
537 | if (line_rxm.hasMatch()) { | ||||
538 | process->memmap().back().push_back(line_rxm.captured(2).trimmed()); | ||||
539 | | ||||
540 | if (first == 2) { | ||||
541 | process->memmap()[0].push_back(line_rxm.captured(1).trimmed()); | ||||
542 | } | ||||
543 | } | ||||
544 | } | ||||
545 | } | ||||
546 | | ||||
547 | mFile.close(); | ||||
548 | return true; | ||||
549 | } | ||||
550 | | ||||
480 | bool ProcessesLocal::Private::getNiceness(long pid, Process *process) { | 551 | bool ProcessesLocal::Private::getNiceness(long pid, Process *process) { | ||
481 | int sched = sched_getscheduler(pid); | 552 | int sched = sched_getscheduler(pid); | ||
482 | switch(sched) { | 553 | switch(sched) { | ||
Context not available. | |||||
580 | if(!d->readProcCGroup(dir, process)) success = false; | 651 | if(!d->readProcCGroup(dir, process)) success = false; | ||
581 | if(!d->readProcAttr(dir, process)) success = false; | 652 | if(!d->readProcAttr(dir, process)) success = false; | ||
582 | if(!d->readProcSmaps(dir, process)) success = false; | 653 | if(!d->readProcSmaps(dir, process)) success = false; | ||
654 | if(!d->readProcSMapsDetails(dir, process)) success = false; | ||||
583 | if(!d->getNiceness(pid, process)) success = false; | 655 | if(!d->getNiceness(pid, process)) success = false; | ||
584 | if(mUpdateFlags.testFlag(Processes::IOStatistics) && !d->getIOStatistics(dir, process)) success = false; | 656 | if(mUpdateFlags.testFlag(Processes::IOStatistics) && !d->getIOStatistics(dir, process)) success = false; | ||
585 | 657 | | |||
Context not available. |