
先用系統函數 `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;
}
