s2dblocks

[archived] statusbar blocks for dwm
git clone https://hhvn.uk/s2dblocks
git clone git://hhvn.uk/s2dblocks
Log | Files | Refs

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 }