📄 top.c
字号:
mfree /= 1024; shared /= 1024; buffers /= 1024; cached /= 1024; /* output memory info and load average */ /* clear screen & go to top */ printf("\e[H\e[J" "Mem: " "%ldK used, %ldK free, %ldK shrd, %ldK buff, %ldK cached\n", used, mfree, shared, buffers, cached); printf("Load average: %.2f, %.2f, %.2f " "(State: S=sleeping R=running, W=waiting)\n", avg1, avg2, avg3); return total / 1024;}/* display process statuses */static void display_status(int count, int col){ status_t *s = top; char rss_str_buf[8]; unsigned long total_memory = display_generic(); #ifdef FEATURE_CPU_USAGE_PERCENTAGE /* what info of the processes is shown */ printf("\n\e[7m PID USER STATUS RSS PPID %%CPU %%MEM COMMAND\e[0m\n");#else printf("\n\e[7m PID USER STATUS RSS PPID %%MEM COMMAND\e[0m\n");#endif while (count--) { char *namecmd = s->cmd; int pmem; pmem = 1000.0 * s->rss / total_memory; if (pmem > 999) pmem = 999; if(s->rss > 10*1024) sprintf(rss_str_buf, "%6ldM", s->rss/1024); else sprintf(rss_str_buf, "%7ld", s->rss);#ifdef FEATURE_CPU_USAGE_PERCENTAGE printf("%5d %-8s %s %s %5d %2d.%d %2u.%u ",#else printf("%5d %-8s %s %s %5d %2u.%u ",#endif s->pid, s->user, s->state, rss_str_buf, s->ppid,#ifdef FEATURE_CPU_USAGE_PERCENTAGE s->pcpu/10, s->pcpu%10,#endif pmem/10, pmem%10); if(namecmd != 0 && namecmd[0] != 0) { if(strlen(namecmd) > col) namecmd[col] = 0; printf("%s\n", namecmd); } else { namecmd = s->short_cmd; if(strlen(namecmd) > (col-2)) namecmd[col-2] = 0; printf("[%s]\n", namecmd); } s++; }}/* returns true for file names which are PID dirs * (i.e. start with number) */static int filter_pids(const struct dirent *dir){ char *name = dir->d_name; int n; char status[20]; char buf[1024]; FILE *fp; status_t curstatus; int pid; long tasknice; struct stat sb; if (!(*name >= '0' && *name <= '9')) return 0; if(stat(name, &sb)) return 0; memset(&curstatus, 0, sizeof(status_t)); pid = atoi(name); curstatus.pid = pid; my_getpwuid(curstatus.user, sb.st_uid); sprintf(status, "%d/stat", pid); if((fp = fopen(status, "r")) == NULL) return 0; name = fgets(buf, sizeof(buf), fp); fclose(fp); if(name == NULL) return 0; name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */ if(name == 0 || name[1] != ' ') return 0; *name = 0; sscanf(buf, "%*s (%15c", curstatus.short_cmd); n = sscanf(name+2, "%c %d " "%*s %*s %*s %*s " /* pgrp, session, tty, tpgid */ "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */#ifdef FEATURE_CPU_USAGE_PERCENTAGE "%lu %lu "#else "%*s %*s "#endif "%*s %*s %*s " /* cutime, cstime, priority */ "%ld " "%*s %*s %*s " /* timeout, it_real_value, start_time */ "%*s " /* vsize */ "%ld", curstatus.state, &curstatus.ppid,#ifdef FEATURE_CPU_USAGE_PERCENTAGE &curstatus.utime, &curstatus.stime,#endif &tasknice, &curstatus.rss);#ifdef FEATURE_CPU_USAGE_PERCENTAGE if(n != 6)#else if(n != 4)#endif return 0; if (curstatus.rss == 0 && curstatus.state[0] != 'Z') curstatus.state[1] = 'W'; else curstatus.state[1] = ' '; if (tasknice < 0) curstatus.state[2] = '<'; else if (tasknice > 0) curstatus.state[2] = 'N'; else curstatus.state[2] = ' '; curstatus.rss <<= (PAGE_SHIFT - 10); /* 2**10 = 1kb */ sprintf(status, "%d/cmdline", pid); if((fp = fopen(status, "r")) == NULL) return 0; if(fgets(buf, sizeof(buf), fp) != NULL) { name = strchr(buf, '\n'); if(name != NULL) *name = 0; if(buf[0]) curstatus.cmd = strdup(buf); /* if NULL it work true also */ } fclose(fp); n = ntop; top = xrealloc(top, (++ntop)*sizeof(status_t)); memcpy(top + n, &curstatus, sizeof(status_t)); return 1;}static struct dirent **namelist;static void clearmems(void) { int i; for(i = 0; i < ntop; i++) { free(top[i].cmd); free(namelist[i]); } free(top); free(namelist); top = 0; namelist = 0; ntop = 0;}#if defined BB_FEATURE_USE_TERMIOS#include <termios.h>#include <sys/time.h>#include <signal.h>static struct termios initial_settings;static void reset_term(void){ tcsetattr(0, TCSANOW, (void *) &initial_settings);#ifdef CONFIG_FEATURE_CLEAN_UP clearmems();#ifdef FEATURE_CPU_USAGE_PERCENTAGE free(save_history);#endif#endif /* CONFIG_FEATURE_CLEAN_UP */} static void sig_catcher (int sig){ reset_term();}#endif /* BB_FEATURE_USE_TERMIOS */int top_main(int argc, char **argv){ int opt, interval, lines, col;#if defined BB_FEATURE_USE_TERMIOS struct termios new_settings; struct timeval tv; fd_set readfds; unsigned char c; struct sigaction sa;#if defined BB_FEATURE_AUTOWIDTH struct winsize win = { 0, 0, 0, 0 };#endif#endif /* BB_FEATURE_USE_TERMIOS */ /* Default update rate is 5 seconds */ interval = 5; /* do normal option parsing */ while ((opt = getopt(argc, argv, "d:")) > 0) { switch (opt) { case 'd': interval = atoi(optarg); break; default: show_usage(); } } /* Default to 25 lines - 5 lines for status */ lines = 25 - 5; /* Default CMD format size */#ifdef FEATURE_CPU_USAGE_PERCENTAGE col = 35 - 6;#else col = 35;#endif /* change to proc */ if (chdir("/proc") < 0) { perror_msg_and_die("chdir('/proc')"); }#if defined BB_FEATURE_USE_TERMIOS tcgetattr(0, (void *) &initial_settings); memcpy(&new_settings, &initial_settings, sizeof(struct termios)); new_settings.c_lflag &= ~(ISIG | ICANON); /* unbuffered input */ /* Turn off echoing */ new_settings.c_lflag &= ~(ECHO | ECHONL); signal (SIGTERM, sig_catcher); sigaction (SIGTERM, (struct sigaction *) 0, &sa); sa.sa_flags |= SA_RESTART; sa.sa_flags &= ~SA_INTERRUPT; sigaction (SIGTERM, &sa, (struct sigaction *) 0); sigaction (SIGINT, &sa, (struct sigaction *) 0); tcsetattr(0, TCSANOW, (void *) &new_settings); atexit(reset_term);#if defined BB_FEATURE_AUTOWIDTH ioctl(0, TIOCGWINSZ, &win); if (win.ws_row > 4) { lines = win.ws_row - 5;#ifdef FEATURE_CPU_USAGE_PERCENTAGE col = win.ws_col - 80 + 35 - 6;#else col = win.ws_col - 80 + 35;#endif }#endif#endif /* BB_FEATURE_USE_TERMIOS */#ifdef FEATURE_CPU_USAGE_PERCENTAGE sort_function[0] = pcpu_sort; sort_function[1] = mem_sort; sort_function[2] = time_sort;#else sort_function = mem_sort;#endif while (1) { /* read process IDs & status for all the processes */ if (scandir(".", &namelist, filter_pids, 0) < 0) { perror_msg_and_die("scandir('/proc')"); }#ifdef FEATURE_CPU_USAGE_PERCENTAGE if(!Hertz) { init_Hertz_value(); do_stats(); sleep(1); clearmems(); continue; } do_stats();#else qsort(top, ntop, sizeof(status_t), (void*)sort_function);#endif opt = lines; if (opt > ntop) { opt = ntop; } /* show status for each of the processes */ display_status(opt, col);#if defined BB_FEATURE_USE_TERMIOS tv.tv_sec = interval; tv.tv_usec = 0; FD_ZERO (&readfds); FD_SET (0, &readfds); select (1, &readfds, NULL, NULL, &tv); if (FD_ISSET (0, &readfds)) { if (read (0, &c, 1) <= 0) { /* signal */ return EXIT_FAILURE; } if(c == 'q' || c == initial_settings.c_cc[VINTR]) return EXIT_SUCCESS; if(c == 'M') {#ifdef FEATURE_CPU_USAGE_PERCENTAGE sort_function[0] = mem_sort; sort_function[1] = pcpu_sort; sort_function[2] = time_sort;#else sort_function = mem_sort;#endif }#ifdef FEATURE_CPU_USAGE_PERCENTAGE if(c == 'P') { sort_function[0] = pcpu_sort; sort_function[1] = mem_sort; sort_function[2] = time_sort; } if(c == 'T') { sort_function[0] = time_sort; sort_function[1] = mem_sort; sort_function[2] = pcpu_sort; }#endif if(c == 'N') {#ifdef FEATURE_CPU_USAGE_PERCENTAGE sort_function[0] = pid_sort;#else sort_function = pid_sort;#endif } }#else sleep(interval);#endif /* BB_FEATURE_USE_TERMIOS */ clearmems(); } return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -