]> git.sur5r.net Git - i3/i3status/blobdiff - i3status.c
Allow to print eth information on NetBSD
[i3/i3status] / i3status.c
index e8e44d4245635498a48d3b5f977dfe2ea13804b1..e99e627be4557d386bd5de1c301c6e91596f7750 100644 (file)
 /* socket file descriptor for general purposes */
 int general_socket;
 
+static bool exit_upon_signal = false;
+
 cfg_t *cfg, *cfg_general, *cfg_section;
 
 /*
- * Exit upon SIGPIPE because when we have nowhere to write to, gathering
- * system information is pointless.
+ * Set the exit_upon_signal flag, because one cannot do anything in a safe
+ * manner in a signal handler (e.g. fprintf, which we really want to do for
+ * debugging purposes), see
+ * https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers
  *
  */
-void sigpipe(int signum) {
-        fprintf(stderr, "Received SIGPIPE, exiting\n");
-        exit(1);
+void fatalsig(int signum) {
+        exit_upon_signal = true;
 }
 
 /*
@@ -230,6 +233,7 @@ int main(int argc, char *argv[]) {
 
         cfg_opt_t battery_opts[] = {
                 CFG_STR("format", "%status %percentage %remaining", CFGF_NONE),
+                CFG_STR("format_down", "No battery", CFGF_NONE),
                 CFG_STR("path", "/sys/class/power_supply/BAT%d/uevent", CFGF_NONE),
                 CFG_INT("low_threshold", 30, CFGF_NONE),
                 CFG_STR("threshold_type", "time", CFGF_NONE),
@@ -257,7 +261,7 @@ int main(int argc, char *argv[]) {
 
         cfg_opt_t load_opts[] = {
                 CFG_STR("format", "%1min %5min %15min", CFGF_NONE),
-                CFG_INT("max_threshold", 5, CFGF_NONE),
+                CFG_FLOAT("max_threshold", 5, CFGF_NONE),
                 CFG_CUSTOM_COLOR_OPTS,
                 CFG_END()
         };
@@ -320,8 +324,15 @@ int main(int argc, char *argv[]) {
 
         struct sigaction action;
         memset(&action, 0, sizeof(struct sigaction));
-        action.sa_handler = sigpipe;
+        action.sa_handler = fatalsig;
+
+        /* Exit upon SIGPIPE because when we have nowhere to write to, gathering system
+         * information is pointless. Also exit explicitly on SIGTERM and SIGINT because
+         * only this will trigger a reset of the cursor in the terminal output-format.
+         */
         sigaction(SIGPIPE, &action, NULL);
+        sigaction(SIGTERM, &action, NULL);
+        sigaction(SIGINT, &action, NULL);
 
         memset(&action, 0, sizeof(struct sigaction));
         action.sa_handler = sigusr1;
@@ -375,6 +386,8 @@ int main(int argc, char *argv[]) {
                 output_format = O_XMOBAR;
         else if (strcasecmp(output_str, "i3bar") == 0)
                 output_format = O_I3BAR;
+        else if (strcasecmp(output_str, "term") == 0)
+                output_format = O_TERM;
         else if (strcasecmp(output_str, "none") == 0)
                 output_format = O_NONE;
         else die("Unknown output format: \"%s\"\n", output_str);
@@ -399,6 +412,12 @@ int main(int argc, char *argv[]) {
                 yajl_gen_array_open(json_gen);
                 yajl_gen_clear(json_gen);
         }
+        if (output_format == O_TERM) {
+                /* Save the cursor-position and hide the cursor */
+                printf("\033[s\033[?25l");
+                /* Undo at exit */
+                atexit(&reset_cursor);
+        }
 
         if ((general_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
                 die("Could not create socket\n");
@@ -414,10 +433,17 @@ int main(int argc, char *argv[]) {
         char buffer[4096];
 
         while (1) {
+                if (exit_upon_signal) {
+                        fprintf(stderr, "Exiting due to signal.\n");
+                        exit(1);
+                }
                 struct timeval tv;
                 gettimeofday(&tv, NULL);
                 if (output_format == O_I3BAR)
                         yajl_gen_array_open(json_gen);
+                else if (output_format == O_TERM)
+                        /* Restore the cursor-position, clear line */
+                        printf("\033[u\033[K");
                 for (j = 0; j < cfg_size(cfg, "order"); j++) {
                         if (j > 0)
                                 print_seperator();
@@ -444,7 +470,7 @@ int main(int argc, char *argv[]) {
 
                         CASE_SEC_TITLE("battery") {
                                 SEC_OPEN_MAP("battery");
-                                print_battery_info(json_gen, buffer, atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format"), cfg_getint(sec, "low_threshold"), cfg_getstr(sec, "threshold_type"), cfg_getbool(sec, "last_full_capacity"), cfg_getbool(sec, "integer_battery_capacity"));
+                                print_battery_info(json_gen, buffer, atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format"), cfg_getstr(sec, "format_down"), cfg_getint(sec, "low_threshold"), cfg_getstr(sec, "threshold_type"), cfg_getbool(sec, "last_full_capacity"), cfg_getbool(sec, "integer_battery_capacity"));
                                 SEC_CLOSE_MAP;
                         }
 
@@ -462,7 +488,7 @@ int main(int argc, char *argv[]) {
 
                         CASE_SEC("load") {
                                 SEC_OPEN_MAP("load");
-                                print_load(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getint(sec, "max_threshold"));
+                                print_load(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getfloat(sec, "max_threshold"));
                                 SEC_CLOSE_MAP;
                         }