changeset 1064:0d7d6fed8141 draft

I got tired of trying to guess how much terminal time I could get in on my phone, so here's a basic acpi. I could probably add -c fairly easily (print type, cur_state, and max_state) -t is more difficult, since temperatures are reported in at least 1000 * degrees F and 10 * degrees C.
author Isaac Dunham <ibid.ag@gmail.com>
date Mon, 09 Sep 2013 11:19:59 -0500
parents 51f0dda223b8
children 9211bc984285
files toys/other/acpi.c
diffstat 1 files changed, 83 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/other/acpi.c	Mon Sep 09 11:19:59 2013 -0500
@@ -0,0 +1,83 @@
+/* acpi.c - show power state
+ * Written by Isaac Dunham, 2013
+ * No standard.
+USE_ACPI(NEWTOY(acpi, "ab", TOYFLAG_USR|TOYFLAG_BIN))
+
+config ACPI
+  bool "acpi"
+  default n
+  help
+    usage: acpi [-ab]
+    
+    Show status of power sources.
+    -a   show power adapters
+    -b   show batteries
+*/
+
+#define FOR_acpi
+#include "toys.h"
+
+GLOBALS(
+int ac;
+int bat;
+)
+
+int read_int_at(int dirfd, char *name) {
+  int fd, ret=0;
+  if ((fd=openat(dirfd, name, O_RDONLY)) < 0)
+    return -1;
+  FILE * fil = xfdopen(fd, "r");
+  fscanf(fil, "%d", &ret);
+  fclose(fil);
+  return ret;
+}
+
+int acpi_callback(struct dirtree *tree)
+{
+  errno = 0;
+
+  if (tree->name[0]=='.')
+    return 0;
+  if (strlen(dirtree_path(tree, NULL)) < 26) {
+    return (DIRTREE_RECURSE | DIRTREE_SYMFOLLOW);
+  }
+  int dfd=open(dirtree_path(tree, NULL), O_RDONLY);
+  if (dfd > 0) {
+    int fd;
+    if ((fd = openat(dfd, "type", O_RDONLY)) < 0) {
+      close(dfd);
+      return 0;
+    }
+    read(fd, toybuf, 4096);
+    close(fd);
+    if (0 == strncmp(toybuf, "Battery", 7)) {
+      if (toys.optflags & FLAG_b || (!toys.optflags)) {
+        int cap = 0, curr = 0, max = 0;
+        if ((cap = read_int_at(dfd, "capacity")) < 0) {
+          if ((max = read_int_at(dfd, "charge_full")) > 0) {
+            curr = read_int_at(dfd, "charge_now");
+          } else if ((max = read_int_at(dfd, "energy_full")) > 0) {
+            curr = read_int_at(dfd, "energy_now");
+          }
+          if (max > 0 && (curr >= 0))
+            cap = 100 * curr / max;
+        }
+        if (cap >= 0) printf("Battery %d: %d%%\n", TT.bat++, cap);
+      }
+    } else {
+      //ac
+      if (toys.optflags & FLAG_a) {
+        int on;
+        if ((on = read_int_at(dfd, "online")) >= 0)
+          printf("Adapter %d: %s-line\n", TT.ac++, (on ? "on" : "off"));
+      }
+    }
+    close(dfd);
+  }
+  return 0;
+}
+
+void acpi_main(void)
+{
+  dirtree_read("/sys/class/power_supply", acpi_callback);
+}