]> git.sur5r.net Git - i3/i3status/blob - src/print_cpu_temperature.c
Properly output JSON with libyajl
[i3/i3status] / src / print_cpu_temperature.c
1 // vim:ts=8:expandtab
2 #include <stdlib.h>
3 #include <limits.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <yajl/yajl_gen.h>
7
8 #include "i3status.h"
9
10 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
11 #include <err.h>
12 #include <sys/types.h>
13 #include <sys/sysctl.h>
14 #define TZ_ZEROC 2732
15 #define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), abs(((x) - TZ_ZEROC) % 10)
16 #endif
17
18 static char *thermal_zone;
19
20 /*
21  * Reads the CPU temperature from /sys/class/thermal/thermal_zone0/temp and
22  * returns the temperature in degree celcius.
23  *
24  */
25 void print_cpu_temperature_info(yajl_gen json_gen, char *buffer, int zone, const char *path, const char *format) {
26 #ifdef THERMAL_ZONE
27         const char *walk;
28         char *outwalk = buffer;
29         static char buf[16];
30
31         if (path == NULL) {
32                 asprintf(&thermal_zone, THERMAL_ZONE, zone);
33                 path = thermal_zone;
34         }
35
36         INSTANCE(path);
37
38         for (walk = format; *walk != '\0'; walk++) {
39                 if (*walk != '%') {
40                         *(outwalk++) = *walk;
41                         continue;
42                 }
43
44                 if (BEGINS_WITH(walk+1, "degrees")) {
45 #if defined(LINUX)
46                         long int temp;
47                         if (!slurp(path, buf, sizeof(buf)))
48                                 goto error;
49                         temp = strtol(buf, NULL, 10);
50                         if (temp == LONG_MIN || temp == LONG_MAX || temp <= 0)
51                                 *(outwalk++) = '?';
52                         else
53                                 outwalk += sprintf(outwalk, "%ld", (temp/1000));
54 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
55                         int sysctl_rslt;
56                         size_t sysctl_size = sizeof(sysctl_rslt);
57                         if (sysctlbyname(path, &sysctl_rslt, &sysctl_size, NULL, 0))
58                                 goto error;
59
60                         outwalk += sprintf(outwalk, "%d.%d", TZ_KELVTOC(sysctl_rslt));
61 #endif
62                         walk += strlen("degrees");
63                 }
64         }
65
66         OUTPUT_FULL_TEXT(buffer);
67         return;
68 error:
69 #endif
70         (void)fputs("Cannot read temperature\n", stderr);
71 }