📄 readinfo.c~
字号:
#include<unistd.h>#include<stdio.h>#include<errno.h>#include<sys/types.h>#include<dirent.h>#include"view&model_rc.c"#define NAMELEN 20 /* the max len of proc name OR a file name */#define ENVNLEN 40 /* the max len of enrivon in string form */#define CMDLEN 100 /* the max len of cmdline */#define LINELEN 80 /* the max len of a line */#define NULLLEN 20typedef struct _procInfo{ char procName[NAMELEN]; unsigned int pid; /* process ID */ unsigned int vmsize; /* in KB */ char status; unsigned int usedcpu; char environ[ENVNLEN]; char cmdline[CMDLEN]; int priority; unsigned int tps; /* total program size */ unsigned int rss; /* resident set size */ unsigned int sharepg; /* shared pages */ //maybe,there is other info pertain to this process...}procInfo;int isinteger(char *str){ char *temp; temp=str; while(isdigit(*temp))temp++; if((*temp)=='\0')return 1; return 0;}int change_info(procInfo info,GtkTreeStore *model){ GtkTreeIter iter; gboolean valid; int isnew=0; /* flag if the proc has existed,isnew=0,else isnew=1 */ int count=0; procInfo oldinfo; g_return_if_fail(model!=NULL); /* get first row in tree store */ valid=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model),&iter); while(valid){ ++count; /* retrieve the old proc info, then comp with new info, if needed, we changed the row */ gtk_tree_model_get(model,&iter, /* COL_PROCESS_NAME,&(oldinfo.procName), */ COL_STAT,&(oldinfo.status), COL_VM_SIZE,&(oldinfo.vmsize), COL_CPU_USED,&(oldinfo.usedcpu), COL_ID,&(oldinfo.pid), /* COL_ENVIRON,&(oldinfo.environ), */ /* COL_PARAM,&(oldinfo.cmdline), */ COL_TPS,&(oldinfo.tps), COL_RSS,&(oldinfo.rss), COL_SHARED_PAGES,&(oldinfo.sharepg), -1); /* comp in pid area */ if(oldinfo.pid==info.pid){ /* comp in stat area */ if(oldinfo.status!=info.status){ gtk_tree_store_set(model,&iter, COL_STAT,info.status, -1); } /* comp in vmsize area */ if(oldinfo.vmsize!=info.vmsize){ gtk_tree_store_set(model,&iter, COL_VM_SIZE,info.vmsize, -1); } /* comp in %cpu area */ if(oldinfo.usedcpu!=info.usedcpu){ gtk_tree_store_set(model,&iter, COL_CPU_USED,info.usedcpu, -1); } /* comp in total_program_size area */ if(oldinfo.tps!=info.tps){ gtk_tree_store_set(model,&iter, COL_TPS,info.tps, -1); } /* comp in resident_set_size area */ if(oldinfo.rss!=info.rss){ gtk_tree_store_set(model,&iter, COL_RSS,info.rss, -1); } /* comp in shared_pages area */ if(oldinfo.sharepg!=info.sharepg){ gtk_tree_store_set(model,&iter, COL_SHARED_PAGES,info.sharepg, -1); } //maybe we need comp in other areas... /* set the existed flag,indicating that the process exists indeed, which should not be removed */ gtk_tree_store_set(model,&iter, COL_EXISTED,TRUE, -1); }/* end of if */ else ++isnew; /* make iter point to the next row in the tree store */ valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(model),&iter); }/* end of while */ /* check if the info is a new proc's info */ return ((isnew==count)? 1 : 0);}void add_proc(procInfo info,gpointer model){ GtkTreeIter iter; /* append an empty new row to the tree store. Iter will point to the new row */ gtk_tree_store_append(model,&iter,NULL); /* fill fields with info of new process */ gtk_tree_store_set(model,&iter, COL_PROCESS_NAME,info.procName, COL_STAT,info.status, COL_VM_SIZE,info.vmsize, COL_CPU_USED,info.usedcpu, COL_ID,info.pid, COL_ENVIRON,info.environ, COL_PARAM,info.cmdline, COL_TPS,info.tps, COL_RSS,info.rss, COL_SHARED_PAGES,info.sharepg, //maybe there are other fields to be assigned... COL_EXISTED,TRUE,/* funcs as before, indicating the addition proc existed, which should not be removed */ -1);}gboolean foreach_func(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, GList **rowref_list){ gboolean doesExist; g_assert(rowref_list!=NULL); gtk_tree_model_get(model,iter,COL_EXISTED,&doesExist,-1); if(!doesExist){ GtkTreeRowReference *rowref; rowref=gtk_tree_row_reference_new(model,path); *rowref_list=g_list_append(*rowref_list,rowref); } else{ /* if the proc reaching to now exists, we should unset the existed flag, avoiding bringing the unpredicable result after, because we do not know whether this right proc still exists */ gtk_tree_store_set(model,iter, COL_EXISTED,FALSE, -1); } return FALSE; /* do not stop walking the store, call us with next row */}void remove_proc(GtkWidget *model){ GList *rr_list=NULL; /* list of GtkTreeRowReferences to remove */ GList *node; gtk_tree_model_foreach(GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)foreach_func, &rr_list); for(node=rr_list;node!=NULL;node=node->next){ GtkTreePath *path; path=gtk_tree_row_reference_get_path((GtkTreeRowReference *)node->data); if(path){ GtkTreeIter iter; if(gtk_tree_model_get_iter(GTK_TREE_MODEL(model),&iter,path)){ gtk_tree_store_remove(model,&iter); } }/* end of outer-if */ }/* end of for */ g_list_foreach(rr_list,(GFunc)gtk_tree_row_reference_free,NULL); g_list_free(rr_list);}gintprogress_timeout(GtkWidget *view){ /* the var associated with read dir and file */ DIR *dirp; /* file dir pointer */ FILE *fp; /* file pointer, to get info of proc,we will read two files(.i.e,"/proc/xxxx/cmdline","/proc/xxxx/status") */ struct dirent *direntp; /* dir entry pointer */ procInfo info; /* contains a proc's info */ char linebuf[LINELEN]; /* contains a line of a file */ unsigned int lineno; char null[NULLLEN]; char filename[NAMELEN]="/proc/";/* contains the filenames("/proc/xxxx/cmdline","/proc/xxxx/status" */ char *notEnvn="root:system_r:unconfined_t";/* as its name, this var does not contain the environ variable. we just use it to take the place of real environ, which I do not do with now */ /* var associated with gtk_tree_view */ GtkWidget *model; model=gtk_tree_view_get_model(GTK_TREE_VIEW(view)); if((dirp=opendir("/proc"))==NULL){ fprintf(stderr,"Open Directory /proc Error:%s\n",strerror(errno)); exit(1); } while((direntp=readdir(dirp))!=NULL){ if(isinteger(direntp->d_name)){ /* if it is a proc ID */ /* get the information about this process */ /* read file "/proc/xxxx/cmdline". */ strcat(filename,direntp->d_name); strcat(filename,"/cmdline"); if((fp=fopen(filename,"r"))!=NULL){ fgets(info.cmdline,CMDLEN,fp); } fclose(fp); strcpy(filename,"/proc/"); /* restore the content of filename as before */ /* read file "/proc/xxxx/status". */ strcat(filename,direntp->d_name); strcat(filename,"/status"); if((fp=fopen(filename,"r"))!=NULL){ for(lineno=1;fgets(linebuf,LINELEN,fp)!=NULL;++lineno){ switch(lineno){ case 1: sscanf(linebuf,"%s%s",null,info.procName); /* format:Name: firefox */ break; case 2: sscanf(linebuf,"%s %c",null,&(info.status)); /* format:State: S (sleeping) */ break; case 5: sscanf(linebuf,"%s%d",null,&(info.pid)); /* format:Pid: 1886 */ break; case 13: sscanf(linebuf,"%s%d",null,&(info.vmsize)); /* format:VmSize: 5400 kB */ break; //maybe,there are other cases... default: ; /* do nothing */ }/* end of switch */ }/* end of for */ }/* end of if */ fclose(fp); strcpy(filename,"/proc/"); /* read file "/proc/xxxx/statm" for memory information */ strcat(filename,direntp->d_name); strcat(filename,"/statm"); if((fp=fopen(filename,"r"))!=NULL){ fgets(linebuf,LINELEN,fp); sscanf(linebuf,"%ld%ld%ld",&(info.tps),&(info.rss),&(info.sharepg)); //maybe we can extract more information from file "/proc/xxxx/statm"... } fclose(fp); strcpy(filename,"/proc/"); //maybe,we need read other files with regard to this process... info.usedcpu=0; /* I don't know how to get %cpu of a process */ strcpy(info.environ,notEnvn); /* just as above */ /* update the tree store */ if(change_info(info,model)) add_proc(info,model); }/* end of outer-if */ }/* end of while */ remove_proc(model); closedir(dirp); /* close the dir "/proc" */ return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -