#include #include #include #include #include #include "defs.h" #include "proc.h" /***************************************************************************************************\ \***************************************************************************************************/ int getCPULoad(unsigned *pUser, unsigned *pNice, unsigned *pSystem, unsigned *pIdle) { char buf[1000]; FILE *fp = fopen(CPULoad.file, "r"); if (!fp) return ERROR; if ( (5 > fscanf(fp, "%s %u %u %u %u", buf, pUser, pNice, pSystem, pIdle)) && (strcmp(buf, "cpu")) ) { fclose(fp); return ERROR; } fclose(fp); return NERROR; } /***************************************************************************************************\ \***************************************************************************************************/ int getProcess(const char* file, char* command, unsigned *pUser, unsigned *pSystem) { char buf[1000]; char buf1[100]; FILE *fp = fopen(file, "r"); int i; if (!fp) return ERROR; /* FIXME */ fread(buf,1,1000,fp); strtok(buf," "); if ( command != NULL ) { sscanf(strtok(NULL," "), "%s", buf1); if (strlen(buf1) <= COMMANDSTRLENGTH+2) { memcpy(command, buf1+1, strlen(buf1)-2); command[strlen(buf1)-2]='\0'; } else { memcpy(command, buf1+1, COMMANDSTRLENGTH); command[COMMANDSTRLENGTH]='\0'; } } else strtok(NULL," "); for (i=0; i<11; i++) strtok(NULL," "); sscanf(strtok(NULL," "),"%d",pSystem); sscanf(strtok(NULL," "),"%d",pUser); fclose(fp); return NERROR; } /***************************************************************************************************\ \***************************************************************************************************/ int initCPULoad() { if ( getCPULoad(&CPULoad.userTimeOld, &CPULoad.niceTimeOld, &CPULoad.systemTimeOld, &CPULoad.idleTimeOld) == ERROR) { fprintf(stderr,"Could not read procfs!\n"); return ERROR; } return NERROR; } /***************************************************************************************************\ \***************************************************************************************************/ void calculateCPULoad () { int u,n,s,i; if ( getCPULoad(&u, &n, &s, &i) == ERROR) { if ( (CPULoad.readError*Options.refresh) > 5 ) fprintf(stderr, "cpu: Could not read Procfs for %.1f s. Data may be currupt!\n", CPULoad.readError*Options.refresh); CPULoad.readError++; return; } else CPULoad.readError = 0; #ifdef __DEBUG__ if ( Options.debug ) { printf("Total ===================================================================================================\n"); printf("TimeOld:\tUser: %10d\tNice: %10d\tSystem: %10d\tIdle: %10d\n", CPULoad.userTimeOld, CPULoad.niceTimeOld, CPULoad.systemTimeOld, CPULoad.idleTimeOld); printf("Procfs:\t\tUser: %10d\tNice: %10d\tSystem: %10d\tIdle: %10d\n", u, n, s, i); } #endif CPULoad.user = u - CPULoad.userTimeOld; CPULoad.nice = n - CPULoad.niceTimeOld; CPULoad.system = s - CPULoad.systemTimeOld; CPULoad.idle = i - CPULoad.idleTimeOld; #ifdef __DEBUG__ if ( Options.debug ) { printf("Differenz:\tUser: %10d\tNice: %10d\tSystem: %10d\tIdle: %10d\n", CPULoad.user, CPULoad.nice, CPULoad.system, CPULoad.idle); } #endif CPULoad.userTimeOld = u; CPULoad.niceTimeOld = n; CPULoad.systemTimeOld = s;; CPULoad.idleTimeOld = i; CPULoad.sum = CPULoad.user + CPULoad.nice + CPULoad.system + CPULoad.idle; #ifdef __DEBUG__ if ( Options.debug ) { printf("Sum: %10d <--\n", CPULoad.sum); } #endif if (CPULoad.sum) { CPULoad.user = ( CPULoad.user * 1000 ) / CPULoad.sum; CPULoad.nice = ( CPULoad.nice * 1000 ) / CPULoad.sum; CPULoad.system = ( CPULoad.system * 1000 ) / CPULoad.sum; CPULoad.idle = ( CPULoad.idle * 1000 ) / CPULoad.sum; } #ifdef __DEBUG__ if ( Options.debug ) { printf("Prozentual:\tUser: %10d\tNice: %10d\tSystem: %10d\tIdle: %10d\n", CPULoad.user, CPULoad.nice, CPULoad.system, CPULoad.idle); } #endif } /***************************************************************************************************\ \***************************************************************************************************/ struct __Process* initProcess(const int pid) { static struct __Process *process; ProcessCount++; if ( ( process = (struct __Process*)malloc(sizeof(struct __Process)) ) == NULL) { fprintf(stderr, "Cpu: Not enough memory!\n"); return NULL; } INIT_LIST_HEAD(&process->list); process->pid=pid; process->system=0; process->user=0; return process; } /***************************************************************************************************\ \***************************************************************************************************/ int filter(const struct dirent *dir) { char *endptr; strtol(dir->d_name, &endptr, 10); if (endptr[0] == '\0') return 1; else return 0; } /***************************************************************************************************\ \***************************************************************************************************/ int compare(const void *dirent1, const void *dirent2) { if ( atoi((*(struct dirent**)dirent1)->d_name) < atoi((*(struct dirent**)dirent2)->d_name) ) return -1; else if ( atoi((*(struct dirent**)dirent1)->d_name) == atoi((*(struct dirent**)dirent2)->d_name) ) return 0; else return 1; } /***************************************************************************************************\ \***************************************************************************************************/ void emptyList() { struct list_head *hl, *thl; struct __Process *p; if ( !list_empty(&Root) ) { list_for_each_safe(hl, thl, &Root) { p=list_entry(hl, struct __Process, list); list_del(hl); free(p); } } } /***************************************************************************************************\ \***************************************************************************************************/ int scanInitProcesses() { struct dirent **direntries; int i, count, initError=0; struct __Process *p; emptyList(); if ( (count = scandir("/proc", &direntries, &filter, compare)) < 0) { perror("scandir"); return ERROR; } else { for (i=0; id_name)) ) == NULL ) initError=1; else list_add_tail(&p->list, &Root); } free(direntries[i]); } free(direntries); } if (initError) return ERROR; else return NERROR; } /***************************************************************************************************\ \***************************************************************************************************/ int initProcesses() { struct list_head *lh, *tlh; struct __Process *p; char buf[100]; if ( Options.all || Options.summarize) { if ( scanInitProcesses() == ERROR ) return ERROR;; } else { if ( ( p = initProcess((int)getpid()) ) == NULL ) return ERROR; else list_add_tail(&p->list, &Root); } list_for_each_safe(lh, tlh, &Root) { p = list_entry(lh, struct __Process, list); sprintf(buf,"/proc/%d/stat",p->pid); if ( getProcess(buf, p->command, &p->systemTimeOld, &p->userTimeOld) == ERROR ) { list_del(lh); if ( Options.verbose ) { if ( !Options.all && !Options.summarize ) printf("%d: no such process!\n", p->pid); else printf("%d: process terminated\n", p->pid); } free(p); ProcessCount--; } } return NERROR; } /***************************************************************************************************\ \***************************************************************************************************/ int updateProcesses() { struct dirent **direntries; int i=0, count, initError=0, exists=0, inserted=0;; struct list_head *lh, *tlh; struct __Process *p, *pnew; char buf[100]; if ( Options.all || Options.summarize) { if ( (count = scandir("/proc", &direntries, &filter, &compare)) < 0) { perror("cpu: scandir"); return ERROR; } else { for (i=0; id_name) == p->pid ) { exists=1; break; } } if ( !exists ) { if ( Options.verbose ) { printf("New process: %s\n", direntries[i]->d_name); } if ( ( pnew = initProcess(atoi(direntries[i]->d_name)) ) == NULL ) initError=1; else { sprintf(buf, "/proc/%d/stat", pnew->pid); if ( getProcess(buf, pnew->command, &pnew->systemTimeOld, &pnew->userTimeOld) == ERROR ) { if ( Options.verbose ) { fprintf(stderr,"%d: process terminated!\n", pnew->pid); } free(pnew); } else { ProcessCount++; list_for_each_safe(lh, tlh, &Root) { p = list_entry(lh, struct __Process, list); if ( atoi(direntries[i]->d_name) < p->pid ) { list_add_tail(&pnew->list, &p->list); inserted=1; break; } } if ( !inserted ) list_add_tail(&pnew->list, &Root); } } } } free(direntries[i]); } free(direntries); } } if (initError) return ERROR; else return NERROR; } /***************************************************************************************************\ \***************************************************************************************************/ void calculateProcesses() { struct list_head *lh, *tlh; struct __Process *p; char buf[100]; int s,u; list_for_each_safe(lh, tlh, &Root) { p = list_entry(lh, struct __Process, list); sprintf(buf,"/proc/%d/stat",p->pid); if ( getProcess(buf, NULL, &s, &u) == ERROR ) { list_del(lh); if ( Options.verbose ) { printf("%d: process terminated!\n", p->pid); } free(p); ProcessCount--; } else { #ifdef __DEBUG__ if ( Options.debug ) { printf("PID: %d -------------------------------------------------------------------------\n", p->pid); printf("TimeOld:\tUser: %10d\t\t\t\tSystem: %10d\n", p->userTimeOld, p->systemTimeOld); printf("Procfs:\t\tUser: %10d\t\t\t\tSystem: %10d\n", u, s); } #endif p->system = s - p->systemTimeOld; p->user = u - p->userTimeOld; #ifdef __DEBUG__ if ( Options.debug ) { printf("Differenz:\tUser: %10d\t\t\t\tSystem: %10d\n", p->user, p->system); } #endif p->systemTimeOld = s; p->userTimeOld = u; if ( CPULoad.sum ) { p->system = ( p->system * 1000 * Options.mult) / CPULoad.sum; p->user = ( p->user * 1000 * Options.mult) / CPULoad.sum; } #ifdef __DEBUG__ if ( Options.debug ) { printf("Prozentual:\tUser: %10d\t\t\t\tSystem: %10d\n", p->user, p->system); } #endif } } }