]> git.sur5r.net Git - i3/i3status/blobdiff - i3status.c
Bugfix: Exit upon errors from printf in dzen2-mode (usually SIGPIPE because dzen2...
[i3/i3status] / i3status.c
index cc98fa0db792b90f1d914a166ee11ef5630d666f..fd781cb344423f5a3db5ae96850dfe08ad514c20 100644 (file)
@@ -5,6 +5,7 @@
  *
  *
  * Copyright © 2008-2009 Michael Stapelberg and contributors
+ * Copyright © 2009 Thorsten Toepper <atsutane at freethoughts dot de>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification,
@@ -71,7 +72,9 @@
 #define BAR "^fg(#333333)^p(5;-2)^ro(2)^p()^fg()^p(5)"
 
 struct battery {
-        const char *path;
+        char *path;
+        /* Use last full capacity instead of design capacity */
+        bool use_last_full;
         SIMPLEQ_ENTRY(battery) batteries;
 };
 
@@ -84,9 +87,10 @@ static const char *wlan_interface;
 static const char *eth_interface;
 static char *wmii_path;
 static const char *time_format;
-static const char *battery_path;
 static bool use_colors;
 static bool get_ethspeed;
+static bool get_cpu_temperature;
+static char *thermal_zone;
 static const char *wmii_normcolors = "#222222 #333333";
 static char order[MAX_ORDER][2];
 static const char **run_watches;
@@ -199,8 +203,8 @@ static void setup(void) {
                 create_file(concat(order[ORDER_WLAN],"wlan"));
         if (eth_interface)
                 create_file(concat(order[ORDER_ETH],"eth"));
-        if (battery_path)
-                create_file(concat(order[ORDER_BATTERY],"battery"));
+        if (get_cpu_temperature)
+                create_file(concat(order[ORDER_CPU_TEMPERATURE], "cpu_temperature"));
         create_file(concat(order[ORDER_LOAD],"load"));
         if (time_format)
                 create_file(concat(order[ORDER_TIME],"time"));
@@ -217,11 +221,18 @@ static void setup(void) {
 static void write_to_statusbar(const char *name, const char *message, bool final_entry) {
 #ifdef DZEN
         if (final_entry) {
-                (void)printf("%s^p(6)\n", message);
+                if (printf("%s^p(6)\n", message) < 0) {
+                        perror("printf");
+                        exit(1);
+                }
+
                 fflush(stdout);
                 return;
         }
-        (void)printf("%s" BAR, message);
+        if (printf("%s" BAR, message) < 0) {
+                perror("printf");
+                exit(1);
+        }
         return;
 #endif
 
@@ -254,15 +265,16 @@ static void write_error_to_statusbar(const char *message) {
  *
  */
 void die(const char *fmt, ...) {
-        if (wmii_path != NULL) {
-                char buffer[512];
-                va_list ap;
-                va_start(ap, fmt);
-                (void)vsnprintf(buffer, sizeof(buffer), fmt, ap);
-                va_end(ap);
+        char buffer[512];
+        va_list ap;
+        va_start(ap, fmt);
+        (void)vsnprintf(buffer, sizeof(buffer), fmt, ap);
+        va_end(ap);
 
+        if (wmii_path != NULL)
                 write_error_to_statusbar(buffer);
-        }
+        else
+                fprintf(stderr, "%s", buffer);
         exit(EXIT_FAILURE);
 }
 
@@ -289,7 +301,7 @@ static char *skip_character(char *input, char character, int amount) {
  * worn off your battery is.
  *
  */
-static char *get_battery_info(const char *path) {
+static char *get_battery_info(struct battery *bat) {
         char buf[1024];
         static char part[512];
         char *walk, *last;
@@ -299,27 +311,44 @@ static char *get_battery_info(const char *path) {
             present_rate = -1;
         charging_status_t status = CS_DISCHARGING;
 
-        if ((fd = open(path, O_RDONLY)) == -1)
+        if ((fd = open(bat->path, O_RDONLY)) == -1)
                 return "No battery found";
 
         memset(part, 0, sizeof(part));
         (void)read(fd, buf, sizeof(buf));
-        for (walk = buf, last = buf; (walk-buf) < 1024; walk++)
-                if (*walk == '=') {
-                        if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL_DESIGN") ||
-                            BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL_DESIGN"))
-                                full_design = atoi(walk+1);
-                        else if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW") ||
-                                 BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW"))
-                                remaining = atoi(walk+1);
-                        else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW"))
-                                present_rate = atoi(walk+1);
-                        else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Charging"))
-                                status = CS_CHARGING;
-                        else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full"))
-                                status = CS_FULL;
-                } else if (*walk == '\n')
+        for (walk = buf, last = buf; (walk-buf) < 1024; walk++) {
+                if (*walk == '\n') {
                         last = walk+1;
+                        continue;
+                }
+
+                if (*walk != '=')
+                        continue;
+
+                if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW") ||
+                    BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW"))
+                        remaining = atoi(walk+1);
+                else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW"))
+                        present_rate = atoi(walk+1);
+                else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Charging"))
+                        status = CS_CHARGING;
+                else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full"))
+                        status = CS_FULL;
+                else {
+                        /* The only thing left is the full capacity */
+                        if (bat->use_last_full) {
+                                if (!BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL") &&
+                                    !BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL"))
+                                        continue;
+                        } else {
+                                if (!BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL_DESIGN") &&
+                                    !BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL_DESIGN"))
+                                        continue;
+                        }
+
+                        full_design = atoi(walk+1);
+                }
+        }
         (void)close(fd);
 
         if ((full_design == 1) || (remaining == -1))
@@ -462,6 +491,33 @@ static char *get_eth_info() {
         return part;
 }
 
+/*
+ * Reads the CPU temperature from /sys/class/thermal/thermal_zone0/temp and
+ * returns the temperature in degree celcius.
+ *
+ */
+static char *get_cpu_temperature_info() {
+        static char part[16];
+        char buf[16];
+        int temp;
+        int fd;
+
+        memset(buf, 0, sizeof(buf));
+        memset(part, 0, sizeof(part));
+
+        if ((fd = open(thermal_zone, O_RDONLY)) == -1)
+                die("Could not open %s\n", thermal_zone);
+        (void)read(fd, buf, sizeof(buf));
+        (void)close(fd);
+
+        if (sscanf(buf, "%d", &temp) != 1)
+                (void)snprintf(part, sizeof(part), "T: ? C");
+        else
+                (void)snprintf(part, sizeof(part), "T: %d C", (temp/1000));
+
+        return part;
+}
+
 /*
  * Checks if the PID in path is still valid by checking:
  *  (Linux) if /proc/<pid> exists
@@ -536,17 +592,35 @@ static int load_configuration(const char *configfile) {
                         eth_interface = strdup(dest_value);
                 OPT("time_format")
                         time_format = strdup(dest_value);
-                OPT("battery_path") {
+                OPT("battery") {
                         struct battery *new = calloc(1, sizeof(struct battery));
                         if (new == NULL)
                                 die("Could not allocate memory\n");
-                        new->path = strdup(dest_value);
+                        if (asprintf(&(new->path), "/sys/class/power_supply/BAT%d/uevent", atoi(dest_value)) == -1)
+                                die("Could not build battery path\n");
+
+                        /* check if flags were specified for this battery */
+                        if (strstr(dest_value, ",") != NULL) {
+                                char *flags = strstr(dest_value, ",");
+                                flags++;
+                                if (*flags == 'f')
+                                        new->use_last_full = true;
+                        }
                         SIMPLEQ_INSERT_TAIL(&batteries, new, batteries);
                 } OPT("color")
                         use_colors = true;
                 OPT("get_ethspeed")
                         get_ethspeed = true;
-                OPT("normcolors")
+                OPT("get_cpu_temperature") {
+                        get_cpu_temperature = true;
+                        if (strlen(dest_value) > 0) {
+                                if (asprintf(&thermal_zone, "/sys/class/thermal/thermal_zone%d/temp", atoi(dest_value)) == -1)
+                                        die("Could not build thermal_zone path\n");
+                        } else {
+                                 if (asprintf(&thermal_zone, "/sys/class/thermal/thermal_zone0/temp") == -1)
+                                        die("Could not build thermal_zone path\n");
+                        }
+                } OPT("normcolors")
                         wmii_normcolors = strdup(dest_value);
                 OPT("interval")
                         interval = atoi(dest_value);
@@ -595,6 +669,7 @@ static int load_configuration(const char *configfile) {
                                 SET_ORDER("wlan", ORDER_WLAN);
                                 SET_ORDER("eth", ORDER_ETH);
                                 SET_ORDER("battery", ORDER_BATTERY);
+                                SET_ORDER("cpu_temperature", ORDER_CPU_TEMPERATURE);
                                 SET_ORDER("load", ORDER_LOAD);
                                 SET_ORDER("time", ORDER_TIME);
                                 token = walk;
@@ -669,8 +744,10 @@ int main(int argc, char *argv[]) {
                         write_to_statusbar(concat(order[ORDER_ETH], "eth"), get_eth_info(), false);
                 struct battery *current_battery;
                 SIMPLEQ_FOREACH(current_battery, &batteries, batteries) {
-                        write_to_statusbar(concat(order[ORDER_BATTERY], "battery"), get_battery_info(current_battery->path), false);
+                        write_to_statusbar(concat(order[ORDER_BATTERY], "battery"), get_battery_info(current_battery), false);
                 }
+                if (get_cpu_temperature)
+                        write_to_statusbar(concat(order[ORDER_CPU_TEMPERATURE], "cpu_temperature"), get_cpu_temperature_info(), false);
 
                 /* Get load */
 #ifdef LINUX