cpu.c (3296B)
1 #include <stdio.h> 2 #include <errno.h> 3 #include <ctype.h> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <unistd.h> 7 #include <sys/stat.h> 8 #include "status2d.h" 9 10 #define MAXCORES 1024 /* moore's law, man */ 11 12 #ifdef __linux__ 13 #define CPUTOKS 11 /* grep '^cpu' < /proc/stat | awk '{print NF}' */ 14 static FILE * 15 statopen(void) { 16 FILE *ret; 17 if ((ret = fopen("/proc/stat", "r")) == NULL) { 18 s2d_print("%s: %s", strerror(errno)); 19 s2d_finish(); 20 exit(EXIT_FAILURE); 21 } 22 return ret; 23 } 24 #endif /* __linux__ */ 25 26 int 27 main(void) { 28 int percent[MAXCORES]; 29 int avgtemp; 30 int cores = 0; 31 char *col; 32 memset(percent, 0, sizeof(percent)); 33 34 #ifdef __linux__ 35 long long unsigned total[MAXCORES]; 36 long long unsigned idle[MAXCORES]; 37 long long unsigned ltotal, lidle, used, diff; 38 struct stat st; 39 FILE *f; 40 char buf[BUFSIZ]; 41 char *toks[CPUTOKS]; 42 char *p; 43 int i, j; 44 int temptotal, tempn; 45 46 memset(total, 0, sizeof(total)); 47 memset(idle, 0, sizeof(idle)); 48 49 f = statopen(); 50 while ((fgets(buf, sizeof(buf), f)) != NULL) { 51 buf[strlen(buf) - 1] = '\0'; /* remove \n */ 52 if (strncmp(buf, "cpu", 3) == 0 && isdigit(*(buf+3))) { 53 for (j = 0; j < CPUTOKS; j++) 54 toks[j] = strtok(j ? NULL : buf, " "); 55 p = toks[0]; 56 p += 3; /* "cpu" */ 57 i = strtoll(p, NULL, 10); 58 if (i >= MAXCORES) { 59 s2d_print("MAXCORES exceeded"); 60 s2d_finish(); 61 return 1; 62 } 63 if (i + 1 > cores) 64 cores = i + 1; 65 for (j = 1; j < CPUTOKS; j++) 66 total[i] += strtoll(toks[j], NULL, 10); 67 idle[i] = strtoll(toks[4], NULL, 10); 68 } 69 } 70 fclose(f); 71 72 sleep(1); 73 74 f = statopen(); 75 while ((fgets(buf, sizeof(buf), f)) != NULL) { 76 buf[strlen(buf) - 1] = '\0'; 77 if (strncmp(buf, "cpu", 3) == 0 && isdigit(*(buf+3))) { 78 for (j = 0; j < CPUTOKS; j++) 79 toks[j] = strtok(j ? NULL : buf, " "); 80 p = toks[0]; 81 p += 3; /* "cpu" */ 82 i = strtoll(p, NULL, 10); 83 if (i >= MAXCORES) { 84 s2d_print("MAXCORES exceeded"); 85 s2d_finish(); 86 return 1; 87 } 88 if (i + 1 > cores) 89 cores = i + 1; 90 for (j = 1, ltotal = 0; j < CPUTOKS; j++) 91 ltotal += strtoll(toks[j], NULL, 10); 92 diff = ltotal - total[i]; 93 lidle = strtoll(toks[4], NULL, 10) - idle[i]; 94 used = 100 * (diff - lidle); 95 percent[i] = used / diff; 96 } 97 } 98 fclose(f); 99 100 for (temptotal = tempn = i = 0; i < MAXCORES && i < cores; i++) { 101 snprintf(buf, sizeof(buf), "/sys/class/thermal/thermal_zone%d/temp", i); 102 if (stat(buf, &st) == -1) 103 continue; 104 if (!S_ISREG(st.st_mode)) 105 continue; 106 if ((f = fopen(buf, "r")) == NULL) 107 continue; 108 fread(buf, sizeof(char), BUFSIZ, f); 109 buf[5] = '\0'; 110 tempn++; 111 temptotal += strtol(buf, NULL, 10) / 1000; 112 fclose(f); 113 } 114 115 avgtemp = temptotal / tempn; 116 #else 117 s2d_print("no handler for this OS"); 118 s2d_finish(); 119 return 1; 120 #endif 121 for (i = 0; percent[i] && i < MAXCORES; i++) { 122 s2d_bg(BRBG); 123 if (percent[i] >= 86) 124 s2d_fg(RED); 125 else if (percent[i] >= 63) 126 s2d_fg(ORANGE); 127 else if (percent[i] >= 50) 128 s2d_fg(YELLOW); 129 else 130 s2d_fg(GREEN); 131 s2d_bar(0, 2, 3, bar_height - 4, 1, percent[i]); 132 s2d_reset(0, 1); 133 s2d_forward(-1); 134 s2d_forward(2); 135 } 136 if (avgtemp) { 137 if (avgtemp >= 70) 138 s2d_fg(RED); 139 else if (avgtemp >= 65) 140 s2d_fg(ORANGE); 141 else if (avgtemp >= 60) 142 s2d_fg(YELLOW); 143 else 144 s2d_reset(1, 1); 145 s2d_print("%d°", avgtemp); 146 } 147 s2d_finish(); 148 }