- 论坛徽章:
- 0
|
前几天在帖子上看了别人写的一个ps命令(http://bbs.chinaunix.net/viewthr ... &extra=page%3D1),觉得挺不错的,可是自己对内核几乎不懂,翻了翻《情景分析》,对/proc目录下的东东有了点了解,便想些个ps命令试试,忙了近3天终于成了,这个办法实在有点傻,不过也算一种方法,希望能与大家分享,高人多提意见!!!!
- /********************MyPS.c*******************************/
- /**********/ OS Linux--2.4.20-8smp /*****************/
- 此伪PS命令是采用遍历/proc目录的方法
- */
- #define MAX_NAME 128
- #include <sys/types.h>
- #include <dirent.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- /*
- 自己定义的进程结构体,信息不太全
- */
- typedef struct Proc_entry
- {
- char name[MAX_NAME];//进程名(不是路径,路径在'cmdline'文件里面)
- char status;//状态
- int pid;//进程ID
- int Ppid;//父进程ID
- struct Proc_entry * next;//链向下一个进程节点的指针
- }* Proc_entry_list;
- //获得进程列表,仅仅含有ID信息
- Proc_entry_list GetProcList(char* dir);
- //填充进程列表
- void FillProcList(Proc_entry_list L);
- //初始化一个进程节点
- void initProcEntry(Proc_entry_list L);
- //检验是否是一个有效的进程节点
- int checkProcEntry(Proc_entry_list L);
- //填充一个进程节点,之后含有所有定义的信息
- int FillProcInfo(Proc_entry_list pro,char * dir);
- //判断这个目录名是否是数字组成的
- int IsDigit(char *);
- //释放进程链表的空间
- int FreeProcList(Proc_entry_list root);
- //打印进程列表,类似于PS命令
- void PrintProcList(Proc_entry_list);
- /****************************************************************/
- int main(int argc, char * argv[])
- {
- Proc_entry_list PROCESS = NULL;
- PROCESS = GetProcList("/proc");
- FillProcList(PROCESS);
- PrintProcList(PROCESS);
- FreeProcList(PROCESS);
- exit(0);
- }
- // scanning directory '/proc' and getting a process list,for each process we just have its name/pid
- // then we will poll its detailed information from files under the directory named by the process' id.
- Proc_entry_list GetProcList(char* dir)
- {
- DIR * dp;
- struct dirent * dirp;
- Proc_entry_list head = NULL,p = NULL;
- // try to open the directory
- if( (dp = opendir(dir))== NULL)
- {
- printf("%s%s\n", "Can not open directory ", dir);
- return NULL;
- }
- // read all the directories or files under the dir
- while ((dirp = readdir(dp)) != NULL)
- {
- // judging whether the directory name is composed by digitals,if so,we will
- // check whether there are files under the directory ,these files includes
- //all detailed information about the process
- if((IsDigit(dirp->d_name) == 0))
- {
- Proc_entry_list s = (Proc_entry_list)malloc(sizeof(struct Proc_entry));
-
- if(s == NULL)
- {
- perror("malloc error\n");
- //释放以前申请到的空间
- return NULL;
- }
- initProcEntry(s);
- s->pid = atoi(dirp->d_name);
- if(head == NULL)
- {
- head = p = s;
- }
- else
- {
- p->next = s;
- p = p->next;
- }
- p->next = NULL;
- }//end if IsDigit
- }//end while
- closedir(dp);
- return head;
- }
- int IsDigit(char*a)
- {
- int size,i;
- size = strlen(a);
- if(size == 0) return -1;
- for(i = 0; i< size; i++)
- if(a[i] <'0' || a[i] > '9') return -1;
- return 0;
- }
- int FillProcInfo(Proc_entry_list root,char * dir)
- {
-
- FILE * fp;
- char buff[MAX_NAME];
- char name[MAX_NAME];
- chdir(dir);
- fp =fopen("status","r");
- if(fp == NULL)
- {
- perror("open file status fail\n");
- return -1;
- }
- while(fgets(buff,MAX_NAME-1,fp))
- {
- if(strstr(buff,"Name:"))
- {
- sscanf(buff,"%s %s",name,root->name);
- }else
-
- if(strstr(buff,"PPid:"))
- {
- sscanf(buff,"%s %d",name,&(root->Ppid));
- }else
- if(strstr(buff,"State:"))
- {
- sscanf(buff,"%s %c",name,&(root->status));
- }
- memset(buff,MAX_NAME,0);
- memset(name,0,MAX_NAME);
- }
- fclose(fp);
- return checkProcEntry(root);
- }
- void PrintProcList(Proc_entry_list root)
- {
- Proc_entry_list p = root;
- int n =0;
- printf("*******name\tpid\tppid\tstatus***********\n");
- while(p!=NULL)
- {
- if(checkProcEntry(p)==0)
- printf("%d->\t%s %d %d %c\n",++n,p->name,p->pid,p->Ppid,p->status);
- p=p->next;
- }
- }
- /******************************/
- void initProcEntry(Proc_entry_list L)
- {
- memset(L->name,0,MAX_NAME);
- L->pid = L->Ppid = -1;
- L->status = '0';
- }
- int checkProcEntry(Proc_entry_list L)
- {
- if(strlen(L->name)==0 || L->pid == -1 || L->Ppid == -1 || L->status == '0')
- return -1;
- return 0;
- }
- /**************************************/
- void FillProcList(Proc_entry_list L)
- {
- char dir[20],data[10];
- Proc_entry_list p = L;
- while(p != NULL)
- {
- memset(dir,0,20);
- memset(data,0,10);
- strcat(dir,"/proc/");
- sprintf(data,"%d/",p->pid);
- strcat(dir,data);
- if(FillProcInfo(p,dir)<0)
- initProcEntry(p);
- p = p->next;
- }
- }
- int FreeProcList(Proc_entry_list root)
- {
- Proc_entry_list p = root;
- if(root == NULL) return 0;
- if(root->next == NULL)
- {
- free(root);
- return 0;
- }
- p = p->next;
- while(p != NULL)
- {
- free(root);
- root = p;
- p = p->next;
- }
- free(root);
- return 0;
- }
- /********************MyPS.c*************************/
复制代码
#gcc MyPS.c -o MyPS
# chmod u+x MyPS
#./MyPS
你就可以看到所有进程了。
[ 本帖最后由 duanjigang 于 2006-4-12 08:56 编辑 ] |
|