先用系統函數 `getpwnam` 獲得指定用戶名的 UID,然后遍歷 /proc/ 中所有 PID 目錄,如果 /proc/PID/status 中的 UID 是輸入用戶名對應的 UID 則輸出該 status 文件中的進程名,進程ID就是目錄名。
#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> int main(int argc, char const *argv[]) { //判斷參數是否合法 if(argc != 2) { perror("Arguments error: lack of username"); exit(EXIT_FAILURE); } //獲得指定用戶名的ID errno = 0; struct passwd *pwd = getpwnam(argv[1]); if(NULL == pwd){ if(errno == 0){ char err_meg[50]; sprintf(err_meg, "Not found the user: %s", argv[1]); } else { perror(strerror(errno)); } exit(EXIT_FAILURE); } uid_t uid = pwd->pw_uid; //printf("%d\n", uid); //打開目錄 /proc DIR *dir = opendir("/proc"); if(NULL == dir){ perror(strerror(errno)); exit(EXIT_FAILURE); } errno = 0; struct dirent *pid_dir; while(pid_dir = readdir(dir)){ // puts(pid_dir->d_name); //是pid目錄 if((pid_dir->d_name)[0] <= '9' && (pid_dir->d_name)[0] >= '1'){ //構造 /proc/PID/status 文件名 char status[50] = "/proc/"; strcat(status, pid_dir->d_name); strcat(status, "/status"); //打開 int fd = open(status, O_RDONLY); if(fd == -1){ perror(strerror(errno)); exit(EXIT_FAILURE); } //讀取 char buffer[512]; read(fd, buffer, 512); char* uid_ptr = strstr(buffer, "Uid") + 5; //UID在字符'Uid'位置向后偏移5個字符 if((uid_t)(strtol(uid_ptr, NULL, 10)) == uid){ //strtol:將字符形式的UID轉換為long,然后再轉換成uit_t int i = 6; //進程名的在status文件開頭位置向后偏移6個字符 printf("%s\t",pid_dir->d_name); while(*(buffer + i) != '\n'){ //輸出進程名字 printf("%c", *(buffer + i)); i++; } puts(""); } //關閉 close(fd); } } if(0 != errno){ perror("readdir"); exit(EXIT_FAILURE); } closedir(dir); return 0; }