c++ 获取某个用户的所有进程 pid name cmdline

高版本的gcc可以直接用下面这个

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <pwd.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>

using namespace std;

class Process {
public:
    int _pid;
    int _uid;
    string _name;
    string _cmdline;

    Process(const int& pid, const int& uid, const string& name, const string& cmdline):
    _pid(pid), _uid(uid), _name(name), _cmdline(cmdline) {};
};

uid_t getUserUid(string userName) {
    //获得指定用户名的ID
    uid_t uid = -1;
    struct passwd *pwd = getpwnam(userName.c_str());
    if(pwd != nullptr){
        uid = pwd->pw_uid;
    }
    return uid;
}

vector<string> getAllProcessPid() {
    vector<string> allProcessPid;
    //打开目录 /proc
    DIR *dir = opendir("/proc");
    if(dir == nullptr){
        return allProcessPid;
    }

    struct dirent *pid_dir;
    while(pid_dir = readdir(dir)){
        //是pid目录
        if((pid_dir->d_name)[0] <= '9' && (pid_dir->d_name)[0] >= '1'){
            allProcessPid.push_back(pid_dir->d_name);
        }
    }

    closedir(dir);
    return allProcessPid;
}

vector<Process> getUserAllProcess(string userName) {
    vector<Process> userAllProcess;
    uid_t uid = getUserUid(userName);
    //cout<<userName<<" uid is: "<<uid<<endl;
    vector<string> allProcessPid = getAllProcessPid();

    vector<string>::iterator it;
    for(it=allProcessPid.begin();it!=allProcessPid.end();++it) {
        string& pidStr = *it;
        string statusFile = "/proc/" + pidStr + "/status";
        string cmdlineFile = "/proc/" + pidStr + "/cmdline";
        int pid = atoi(pidStr.c_str());
        string name = "";
        string cmdline = "";

        ifstream ifs;
        ifs.open(statusFile, ios::in);
        if(ifs.is_open()) {
            string tName = "";
            string line;
            getline(ifs, line);
            // Name:\t<name>
            int startPos = 6;
            tName = line.substr(startPos, line.size()-startPos);
            int index = -1;
            while(getline(ifs, line)) {
                index = line.find("Uid");
                if(index==0) {
                    // Uid:\t<uid>
                    index = 5;
                    string uidStr = "";
                    while(line[index]!='\t'&&index<line.size()) {
                        uidStr+=line[index++];
                    }
                    int tUid = atoi(uidStr.c_str());
                    if(tUid==uid) {
                        name = tName;
                    }
                    break;
                }
            }
        }
        ifs.close();
        if(name.empty()) continue;
        //cout<<pid<<" "<<name<<endl;
        ifs.open(cmdlineFile, ios::in);
        if(ifs.is_open()) {
            string line;
            while(getline(ifs, line, '\0')) {
                if(cmdline!="")cmdline+=" ";
                cmdline += line;
            }
        }
        ifs.close();
        userAllProcess.emplace_back(Process(pid, uid, name, cmdline));
    }
    return userAllProcess;
}

int main(int argc, char const *argv[])
{
    //判断参数是否合法
    if(argc != 2) {
        cout<<"getAllProcess <userName>"<<endl;
        return 0;
    }
    string userName=argv[1];
    vector<Process> userAllProcess = getUserAllProcess(userName);
    if(userAllProcess.size()) {
        cout<<"pid\tExecutableFile\tcmdline"<<endl;
    }
    vector<Process>::iterator it;
    for(it=userAllProcess.begin();it!=userAllProcess.end();++it) {
        cout<<it->_pid<<"\t"<<it->_name<<"\t"<<it->_cmdline<<endl;
    }

    return 0;
}

低版本的gcc 比如说 gcc (GCC) 4.4.7

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <pwd.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>

using namespace std;

class Process {
public:
    int _pid;
    int _uid;
    string _name;
    string _cmdline;

    Process(const int& pid, const int& uid, const string& name, const string& cmdline):
    _pid(pid), _uid(uid), _name(name), _cmdline(cmdline) {};
};

uid_t getUserUid(string userName) {
    //获得指定用户名的ID
    uid_t uid = -1;
    struct passwd *pwd = getpwnam(userName.c_str());
    if(pwd != NULL){
        uid = pwd->pw_uid;
    }
    return uid;
}

vector<string> getAllProcessPid() {
    vector<string> allProcessPid;
    //打开目录 /proc
    DIR *dir = opendir("/proc");
    if(dir == NULL){
        return allProcessPid;
    }

    struct dirent *pid_dir;
    while(pid_dir = readdir(dir)){
        //是pid目录
        if((pid_dir->d_name)[0] <= '9' && (pid_dir->d_name)[0] >= '1'){
            allProcessPid.push_back(pid_dir->d_name);
        }
    }

    closedir(dir);
    return allProcessPid;
}

vector<Process> getUserAllProcess(string userName) {
    vector<Process> userAllProcess;
    uid_t uid = getUserUid(userName);
    //cout<<userName<<" uid is: "<<uid<<endl;
    vector<string> allProcessPid = getAllProcessPid();

    vector<string>::iterator it;
    for(it=allProcessPid.begin();it!=allProcessPid.end();++it) {
        string& pidStr = *it;
        string statusFile = "/proc/" + pidStr + "/status";
        string cmdlineFile = "/proc/" + pidStr + "/cmdline";
        int pid = atoi(pidStr.c_str());
        string name = "";
        string cmdline = "";

        ifstream ifs;
        ifs.open(statusFile.c_str(), ios::in);
        if(ifs.is_open()) {
            string tName = "";
            string line;
            getline(ifs, line);
            // Name:\t<name>
            int startPos = 6;
            tName = line.substr(startPos, line.size()-startPos);
            int index = -1;
            while(getline(ifs, line)) {
                index = line.find("Uid");
                if(index==0) {
                    // Uid:\t<uid>
                    index = 5;
                    string uidStr = "";
                    while(line[index]!='\t'&&index<line.size()) {
                        uidStr+=line[index++];
                    }
                    int tUid = atoi(uidStr.c_str());
                    if(tUid==uid) {
                        name = tName;
                    }
                    break;
                }
            }
        }
        ifs.close();
        if(name.empty()) continue;
        //cout<<pid<<" "<<name<<endl;
        ifs.open(cmdlineFile.c_str(), ios::in);
        if(ifs.is_open()) {
            string line;
            while(getline(ifs, line, '\0')) {
                if(cmdline!="")cmdline+=" ";
                cmdline += line;
            }
        }
        ifs.close();
        userAllProcess.push_back(Process(pid, uid, name, cmdline));
    }
    return userAllProcess;
}

int main(int argc, char const *argv[])
{
    //判断参数是否合法
    if(argc != 2) {
        cout<<"getAllProcess <userName>"<<endl;
        return 0;
    }
    string userName=argv[1];
    vector<Process> userAllProcess = getUserAllProcess(userName);
    if(userAllProcess.size()) {
        cout<<"pid\tExecutableFile\tcmdline"<<endl;
    }
    vector<Process>::iterator it;
    for(it=userAllProcess.begin();it!=userAllProcess.end();++it) {
        cout<<it->_pid<<"\t"<<it->_name<<"\t"<<it->_cmdline<<endl;
    }

    return 0;
}
文章目录