ProcDataList processList(const ProcDataList & /*previous*/) { ProcDataList rc; PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) return rc; for (bool hasNext = Process32First(snapshot, &pe); hasNext; hasNext = Process32Next(snapshot, &pe)) { ProcData procData; procData.ppid = QString::number(pe.th32ProcessID); procData.name = QString::fromUtf16(reinterpret_cast<ushort *>(pe.szExeFile)); const ProcessInfo processInf = processInfo(pe.th32ProcessID); procData.image = processInf.imageName; procData.user = processInf.processOwner; procData.abi = s_abiDetector.abiForProcess(pe.th32ProcessID); rc.push_back(procData); } CloseHandle(snapshot); return rc; }
// Determine UNIX processes by running ps static ProcDataList unixProcessListPS(const ProcDataList &previous) { #ifdef Q_OS_MAC // command goes last, otherwise it is cut off static const char formatC[] = "pid state user command"; #else static const char formatC[] = "pid,state,user,cmd"; #endif ProcDataList rc; QProcess psProcess; QStringList args; args << QLatin1String("-e") << QLatin1String("-o") << QLatin1String(formatC); psProcess.start(QLatin1String("ps"), args); if (!psProcess.waitForStarted()) { return rc; } psProcess.waitForFinished(); QByteArray output = psProcess.readAllStandardOutput(); // Split "457 S+ /Users/foo.app" const QStringList lines = QString::fromLocal8Bit(output).split(QLatin1Char('\n')); const int lineCount = lines.size(); const QChar blank = QLatin1Char(' '); for (int l = 1; l < lineCount; l++) { // Skip header const QString line = lines.at(l).simplified(); // we can't just split on blank as the process name might // contain them const int endOfPid = line.indexOf(blank); const int endOfState = line.indexOf(blank, endOfPid+1); const int endOfUser = line.indexOf(blank, endOfState+1); if (endOfPid >= 0 && endOfState >= 0 && endOfUser >= 0) { ProcData procData; procData.ppid = line.left(endOfPid); procData.state = line.mid(endOfPid+1, endOfState-endOfPid-1); procData.user = line.mid(endOfState+1, endOfUser-endOfState-1); procData.name = line.right(line.size()-endOfUser-1); ProcDataList::ConstIterator it = std::find_if(previous.constBegin(), previous.constEnd(), PidAndNameMatch(procData.ppid, procData.name)); if (it != previous.constEnd()) { procData.type = it->type; } else { procData.type = processIsQtApp(procData.ppid) ? ProcData::QtApp : ProcData::NoQtApp; } rc.push_back(procData); } } return rc; }
// Determine UNIX processes by reading "/proc". Default to ps if // it does not exist ProcDataList processList(const ProcDataList& previous) { const QDir procDir(QLatin1String("/proc/")); if (!procDir.exists()) return unixProcessListPS(previous); ProcDataList rc; const QStringList procIds = procDir.entryList(); if (procIds.isEmpty()) return rc; foreach (const QString &procId, procIds) { if (!isUnixProcessId(procId)) continue; QString filename = QLatin1String("/proc/"); filename += procId; filename += QLatin1String("/stat"); QFile file(filename); if (!file.open(QIODevice::ReadOnly)) continue; // process may have exited const QStringList data = QString::fromLocal8Bit(file.readAll()).split(' '); ProcData proc; proc.ppid = procId; proc.name = data.at(1); if (proc.name.startsWith(QLatin1Char('(')) && proc.name.endsWith(QLatin1Char(')'))) { proc.name.truncate(proc.name.size() - 1); proc.name.remove(0, 1); } proc.state = data.at(2); // PPID is element 3 proc.user = QFileInfo(file).owner(); file.close(); QFile cmdFile(QLatin1String("/proc/") + procId + QLatin1String("/cmdline")); if(cmdFile.open(QFile::ReadOnly)) { QByteArray cmd = cmdFile.readAll(); cmd.replace('\0', ' '); if ( !cmd.isEmpty() ) proc.name = QString::fromLocal8Bit(cmd); } cmdFile.close(); QFile maps(QLatin1String("/proc/") + procId + QLatin1String("/maps")); if (!maps.open(QIODevice::ReadOnly)) continue; // process may have exited proc.type = ProcData::NoQtApp; forever { const QByteArray line = maps.readLine(); if (line.isEmpty()) { break; } if (line.contains(QByteArray("/libQtCore.so"))) { proc.type = ProcData::QtApp; break; } } rc.push_back(proc); } return rc; }