免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4804 | 回复: 4
打印 上一主题 下一主题

我自己写的ps命令 ---采用遍历/proc目录的方法(OS Linux--2.4.20-8smp) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-26 13:42 |只看该作者 |倒序浏览
前几天在帖子上看了别人写的一个ps命令(http://bbs.chinaunix.net/viewthr ... &extra=page%3D1),觉得挺不错的,可是自己对内核几乎不懂,翻了翻《情景分析》,对/proc目录下的东东有了点了解,便想些个ps命令试试,忙了近3天终于成了,这个办法实在有点傻,不过也算一种方法,希望能与大家分享,高人多提意见!!!!

  1. /********************MyPS.c*******************************/
  2. /**********/         OS Linux--2.4.20-8smp        /*****************/
  3. 此伪PS命令是采用遍历/proc目录的方法
  4. */
  5. #define MAX_NAME 128
  6. #include <sys/types.h>
  7. #include <dirent.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <unistd.h>
  12. /*
  13. 自己定义的进程结构体,信息不太全
  14. */
  15. typedef struct Proc_entry
  16. {
  17.         char name[MAX_NAME];//进程名(不是路径,路径在'cmdline'文件里面)
  18.         char status;//状态
  19.         int pid;//进程ID
  20.         int Ppid;//父进程ID
  21.         struct Proc_entry * next;//链向下一个进程节点的指针
  22. }* Proc_entry_list;
  23. //获得进程列表,仅仅含有ID信息
  24. Proc_entry_list GetProcList(char* dir);
  25. //填充进程列表
  26. void FillProcList(Proc_entry_list L);
  27. //初始化一个进程节点
  28. void initProcEntry(Proc_entry_list L);
  29. //检验是否是一个有效的进程节点
  30. int checkProcEntry(Proc_entry_list L);
  31. //填充一个进程节点,之后含有所有定义的信息
  32. int FillProcInfo(Proc_entry_list pro,char * dir);
  33. //判断这个目录名是否是数字组成的
  34. int IsDigit(char *);
  35. //释放进程链表的空间
  36. int FreeProcList(Proc_entry_list root);
  37. //打印进程列表,类似于PS命令
  38. void PrintProcList(Proc_entry_list);
  39. /****************************************************************/
  40. int main(int argc, char * argv[])
  41. {
  42.         Proc_entry_list PROCESS = NULL;
  43.         PROCESS = GetProcList("/proc");
  44.         FillProcList(PROCESS);
  45.         PrintProcList(PROCESS);
  46.         FreeProcList(PROCESS);       
  47.         exit(0);
  48. }
  49. // scanning directory '/proc' and  getting a process list,for each process we just have its name/pid
  50. // then we will poll its detailed information from files under the directory named by the process' id.  
  51. Proc_entry_list GetProcList(char* dir)
  52. {
  53.     DIR * dp;
  54.         struct dirent * dirp;
  55.     Proc_entry_list head = NULL,p = NULL;
  56.         // try to open the directory
  57.         if( (dp = opendir(dir))== NULL)
  58.         {
  59.                 printf("%s%s\n", "Can not open directory ", dir);
  60.                 return NULL;   
  61.         }
  62.         // read all the directories or files under the dir
  63.         while ((dirp = readdir(dp)) != NULL)
  64.         {
  65.                 // judging whether the directory name is composed by digitals,if so,we will
  66.                 // check whether there are files under the directory ,these files includes
  67.                 //all detailed information about the process
  68.                 if((IsDigit(dirp->d_name) == 0))
  69.                 {
  70.                         Proc_entry_list s = (Proc_entry_list)malloc(sizeof(struct Proc_entry));
  71.                        
  72.                         if(s == NULL)
  73.                         {
  74.                                 perror("malloc error\n");
  75.                                 //释放以前申请到的空间
  76.                                 return NULL;
  77.                         }
  78.                         initProcEntry(s);
  79.                         s->pid = atoi(dirp->d_name);
  80.                         if(head == NULL)
  81.                         {
  82.                                 head = p = s;
  83.                         }
  84.                         else
  85.                         {
  86.                                 p->next = s;
  87.                                 p = p->next;
  88.                         }
  89.                         p->next = NULL;
  90.                 }//end if IsDigit
  91.         }//end while
  92.         closedir(dp);
  93.         return head;
  94. }
  95. int IsDigit(char*a)
  96. {
  97.         int size,i;
  98.         size = strlen(a);
  99.         if(size == 0) return -1;
  100.         for(i = 0; i< size; i++)
  101.                 if(a[i] <'0' || a[i] > '9') return -1;
  102.                 return 0;
  103. }

  104. int FillProcInfo(Proc_entry_list root,char * dir)
  105. {
  106.    
  107.         FILE * fp;
  108.         char buff[MAX_NAME];
  109.         char name[MAX_NAME];
  110.         chdir(dir);
  111.         fp =fopen("status","r");
  112.         if(fp == NULL)
  113.         {
  114.                 perror("open file status fail\n");
  115.                 return -1;
  116.         }
  117.         while(fgets(buff,MAX_NAME-1,fp))
  118.         {
  119.                 if(strstr(buff,"Name:"))
  120.                 {
  121.                         sscanf(buff,"%s %s",name,root->name);
  122.                 }else
  123.                        
  124.                         if(strstr(buff,"PPid:"))
  125.                         {
  126.                                 sscanf(buff,"%s %d",name,&(root->Ppid));
  127.                         }else
  128.                                 if(strstr(buff,"State:"))
  129.                                 {
  130.                                         sscanf(buff,"%s %c",name,&(root->status));
  131.                                 }
  132.                                 memset(buff,MAX_NAME,0);
  133.                                 memset(name,0,MAX_NAME);
  134.         }
  135.     fclose(fp);
  136.         return checkProcEntry(root);
  137. }

  138. void PrintProcList(Proc_entry_list root)
  139. {
  140.         Proc_entry_list p = root;
  141.         int n =0;
  142.         printf("*******name\tpid\tppid\tstatus***********\n");
  143.         while(p!=NULL)
  144.         {
  145.                 if(checkProcEntry(p)==0)
  146.                         printf("%d->\t%s   %d  %d  %c\n",++n,p->name,p->pid,p->Ppid,p->status);
  147.                 p=p->next;
  148.         }
  149. }
  150. /******************************/
  151. void initProcEntry(Proc_entry_list L)
  152. {
  153.         memset(L->name,0,MAX_NAME);
  154.         L->pid = L->Ppid = -1;
  155.         L->status = '0';
  156. }
  157. int checkProcEntry(Proc_entry_list L)
  158. {
  159.         if(strlen(L->name)==0 || L->pid == -1 || L->Ppid == -1 || L->status == '0')
  160.                 return -1;
  161.         return 0;
  162. }
  163. /**************************************/
  164. void FillProcList(Proc_entry_list L)
  165. {
  166.     char dir[20],data[10];
  167.         Proc_entry_list p = L;
  168.         while(p != NULL)
  169.         {
  170.                 memset(dir,0,20);
  171.                 memset(data,0,10);
  172.                 strcat(dir,"/proc/");
  173.                 sprintf(data,"%d/",p->pid);
  174.                 strcat(dir,data);
  175.                 if(FillProcInfo(p,dir)<0)
  176.                         initProcEntry(p);
  177.                 p = p->next;
  178.         }
  179. }
  180. int FreeProcList(Proc_entry_list root)
  181. {
  182.         Proc_entry_list p = root;
  183.         if(root == NULL) return 0;
  184.         if(root->next == NULL)
  185.     {
  186.                 free(root);
  187.                 return 0;
  188.     }
  189.         p = p->next;
  190.         while(p != NULL)
  191.         {
  192.                 free(root);
  193.                 root = p;
  194.                 p = p->next;
  195.         }
  196.         free(root);
  197.         return 0;
  198. }
  199. /********************MyPS.c*************************/
复制代码

#gcc MyPS.c -o MyPS
# chmod u+x MyPS
#./MyPS
你就可以看到所有进程了。

[ 本帖最后由 duanjigang 于 2006-4-12 08:56 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2005-11-26 19:46 |只看该作者
我也来贴一个:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>

#include <sys/types.h>

#define NAME_SIZE 20
#define BUF_SIZE 50

struct proc_list{
        pid_t pid;
        pid_t ppid;
        char name[NAME_SIZE];
        char status;
        struct proc_list *next;
};

struct proc_list *inport_list(char *);
void show_info(struct proc_list *);
int read_info(char *,struct proc_list *);
void free_list(struct proc_list *);
int is_num(char *);

int main()
{
        struct proc_list *head = inport_list("/proc");
        if(head==NULL){
                printf("inport list failed !\n");       
        }       
        show_info(head);
        free_list(head);
        return 0;
}

struct proc_list *inport_list(char *dir){
        DIR *dsptr;
        struct dirent *dptr;
        struct proc_list *head=NULL,*ptr=NULL;
        if((dsptr=opendir(dir))==NULL){
                printf("Error open the dir %s\n",dir);
                exit(-1);               
        }
       
        // read all the dir and file under directory "dir" ;
        while((dptr=readdir(dsptr))!=NULL){
                if(is_num(dptr->d_name)==0){ // determine if the d_name is a number ;
                       
                        // request some memeory , some = sizeof(struct proc_list) ;
                        struct proc_list *item = (struct proc_list *)malloc(sizeof(struct proc_list));
               
                        if(item==NULL){
                                printf("memory allocate error !\n");
                                // must do some free() work here !
                                free_list(head);
                                exit(-1);
                        }
               
                        memset(item,0,sizeof(struct proc_list));
                       
                        // link the item to proc_list list ;
                        if(head==NULL)
                                        head=ptr=item;
                        else{
                                ptr->next=item;
                                ptr=ptr->next;                       
                        }
               
                        item->pid = atoi(dptr->d_name);
                       
                        if(read_info(dptr->d_name,item)!=0){ // determine if read error occurred ;
                                // must do some free() work here ;
                                free_list(head);
                                exit(-1);                       
                        }                       
                }
        }
        closedir(dsptr);
        return head;
}

int read_info(char *d_name,struct proc_list *item){
        char dir[20];
        char name[NAME_SIZE];
        char buffer[BUF_SIZE];
        FILE *fptr;
       
        sprintf(dir,"%s%s","/proc/",d_name);
        chdir(dir);
       
        fptr=fopen("status","r");
        if(fptr==NULL){
                printf("Error reading %s%s\n",dir,"status");
                return -1;
        }
       
        while(fgets(buffer,BUF_SIZE-1,fptr))
    {
             if(strstr(buffer,"Name:")){
                sscanf(buffer,"%s%s",name,item->name);
                }else if(strstr(buffer,"PPid:")){
                sscanf(buffer,"%s%d",name,&(item->ppid));
        }else if(strstr(buffer,"State:")){
            sscanf(buffer,"%s %c",name,&(item->status));
        }
        }
        fclose(fptr);
        return 0;
}

void free_list(struct proc_list *head){
        struct proc_list *ptr;
        while(head!=NULL){
                ptr=head;
                head=head->next;
                free(ptr);
        }
}

void show_info(struct proc_list *head){
        struct proc_list *ptr;
        printf("pid\tppid\tstatus\tname\n");
        for(ptr=head;ptr!=NULL;ptr=ptr->next)
                printf("%d\t%d\t%c\t%s\n",ptr->pid,ptr->ppid,ptr->status,ptr->name);
}

int is_num(char *d_name){
        int i,size;
        size = strlen(d_name);
        if(size==0) return -1;
       
        // determine if the dir name is number ;
        for(i=0;i<size;i++)
                if(d_name[i]<'0' || d_name[i]>'9') return -1;
        return 0;
}

论坛徽章:
0
3 [报告]
发表于 2005-11-26 20:37 |只看该作者
老兄,怪了哦,咱俩的程序好像是双胞胎啊,太象了吧!!!

论坛徽章:
0
4 [报告]
发表于 2005-11-26 20:44 |只看该作者
在你的基础上改的. 修改了一些我个人认为可以改进的地方.

论坛徽章:
0
5 [报告]
发表于 2005-11-26 20:49 |只看该作者
好吧,刚才我还火着呢,反正都是学习,算了吧,这几天我觉得自己考虑的还算周到,不过肯定还有许多遗漏,修该吧!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP