實現思路是:遍歷/proc目錄下的所有進程描述文件夾,從而獲取進程列表。
代碼如下:
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
pid_t pid;
char name[256];//進程名稱
int vmsize;//虛擬內存信息
}proc_info_st;//保存讀取的進程信息
#define PROC_NAME_LINE 1//名稱所在行
#define PROC_PID_LINE 4//pid所在行
#define PROC_VMSIZE_LINE 12//虛擬內存所在行
#define BUFF_LEN 1024 //行緩衝區的長度
void read_proc(proc_info_st* info,const char* c_pid);//讀取進程信息
int read_line(FILE* fp,char* buff,int b_l,int l);//讀取一行
int main()
{
//打開目錄
DIR *dir;
struct dirent *ptr;
if (!(dir = opendir("/proc")))
return 0;
//讀取目錄
while (ptr = readdir(dir))
{//循環讀取出所有的進程文件
if (ptr->d_name[0] > '0' && ptr->d_name[0] <= '9')
{
//獲取進程信息
proc_info_st info;
read_proc(&info,ptr->d_name);//讀取信息
printf("pid:%d\npname:%s\nvmsize:%d\n",info.pid,info.name,info.vmsize);
printf("\n\n");//再空兩行
}
}
closedir(dir);
}
/**************************************************
**說明:根據進程pid獲取進程信息,存放在proc_info_st結構體中
**
**輸入:
** /proc_info_st* info 返回進程信息
** /char* c_pid 進程pid的字符串形式
**
**
**
*************************************************/
void read_proc(proc_info_st* info,const char* c_pid)
{
FILE* fp = NULL;
char file[512] = {0};
char line_buff[BUFF_LEN] = {0};//讀取行的緩衝區
sprintf(file,"/proc/%s/status",c_pid);//讀取status文件
if (!(fp = fopen(file,"r")))
{
printf("read %s file fail!\n",file);
return;
}
char name[32];
//先讀取進程名稱
if (read_line(fp,line_buff,BUFF_LEN,PROC_NAME_LINE))
{
sscanf(line_buff,"%s %s",name,(info->name));
}
fseek(fp,0,SEEK_SET);//回到文件頭部
//讀取進程pid
if (read_line(fp,line_buff,BUFF_LEN,PROC_PID_LINE))
{
sscanf(line_buff,"%s %d",name,&(info->pid));
}
fseek(fp,0,SEEK_SET);//回到文件頭部
//讀取進程vmsize
if (read_line(fp,line_buff,BUFF_LEN,PROC_VMSIZE_LINE))
{
sscanf(line_buff,"%s %d",name,&(info->vmsize));
}
fclose(fp);
}
/**************************************************
**說明:讀取文件的一行到buff
**
**輸入:
** /FILE* fp 文件指針
** /char* buff 緩衝區
** /int b_l 緩衝區的長度
** /l 指定行
**
**輸出:
** /true 讀取成功
** /false 讀取失敗
*************************************************/
int read_line(FILE* fp,char* buff,int b_l,int l)
{
if (!fp)
return false;
char line_buff[b_l];
int i;
//讀取指定行的前l-1行,轉到指定行
for (i = 0; i < l-1; i++)
{
if (!fgets (line_buff, sizeof(line_buff), fp))
{
return false;
}
}
//讀取指定行
if (!fgets (line_buff, sizeof(line_buff), fp))
{
return false;
}
memcpy(buff,line_buff,b_l);
return true;
}