[PATCH] Add acpi applet
Isaac Dunham
ibid.ag at gmail.com
Mon Dec 8 00:58:02 UTC 2014
On Fri, Oct 10, 2014 at 11:24:15PM -0700, Isaac Dunham wrote:
> On several occasions I've wished for a tool that can show battery charge,
> whether the power supply is working, and similar things.
> Some time back I wrote the original version of this for toybox;
> I just ported it to BusyBox.
>
> If anyone could review it, I'd appreciate that.
>
> Thanks,
> Isaac Dunham
Any comments? (Denys?)
Is it within scope?
(I'd love to hear anything, even if it's "that belongs elsewhere".
There's been a lot of silence...)
Thanks,
Isaac Dunham
> From 0c0fad3ae324aa2383a9367715d205e41269d0c0 Mon Sep 17 00:00:00 2001
> From: Isaac Dunham <ibid.ag at gmail.com>
> Date: Fri, 10 Oct 2014 22:53:36 -0700
> Subject: [PATCH] Add "acpi" applet.
>
> A tool to monitor power, temperature, and similar things.
> Ported from toybox; subset clone of acpi-1.7.
>
> function old new delta
> acpi_main - 919 +919
> .rodata 134270 134673 +403
> read_int_at - 129 +129
> read_type_at - 119 +119
> packed_usage 29647 29721 +74
> applet_names 2451 2456 +5
> applet_main 1428 1432 +4
> applet_nameofs 714 716 +2
> ------------------------------------------------------------------------------
> (add/remove: 4/0 grow/shrink: 5/0 up/down: 1655/0) Total: 1655 bytes
> text data bss dec hex filename
> 887409 7512 1644 896565 dae35 busybox_old
> 889140 7528 1644 898312 db508 busybox_unstripped
> ---
> miscutils/acpi.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 171 insertions(+)
> create mode 100644 miscutils/acpi.c
>
> diff --git a/miscutils/acpi.c b/miscutils/acpi.c
> new file mode 100644
> index 0000000..f2a5601
> --- /dev/null
> +++ b/miscutils/acpi.c
> @@ -0,0 +1,171 @@
> +/* acpi.c - show power state
> + *
> + * Copyright 2013-2014 A.D., Isaac Dunham
> + *
> + * Based on toybox 0.5.0+ acpi.
> + *
> + * Permission to use, copy, modify, and/or distribute this software for any
> + * purpose with or without fee is hereby granted.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +//config:config ACPI
> +//config: bool "acpi"
> +//config: default y
> +//config: select PLATFORM_LINUX
> +//config: help
> +//config: Show status of power sources and thermal devices.
> +
> +//applet:IF_ACPI(APPLET(acpi, BB_DIR_USR_BIN, BB_SUID_DROP))
> +//kbuild:lib-$(CONFIG_ACPI) += acpi.o
> +
> +//usage:#define acpi_trivial_usage
> +//usage: "[-abctV]"
> +//usage:#define acpi_full_usage "\n\n"
> +//usage: "Show status of power sources and thermal devices.\n"
> +//usage: "-a show power adapters\n"
> +//usage: "-b show batteries\n"
> +//usage: "-c show cooling device state\n"
> +//usage: "-t show temperatures\n"
> +//usage: "-V show everything"
> +
> +
> +#define FLAG_a 1
> +#define FLAG_b 2
> +#define FLAG_c 4
> +#define FLAG_t 8
> +#define FLAG_V 16
> +
> +#include "libbb.h"
> +#include <glob.h>
> +
> +#define G_BUFSIZ 64
> +struct globals {
> + int ac;
> + int bat;
> + int therm;
> + int cool;
> + char buf[G_BUFSIZ];
> +} FIX_ALIASING;
> +#define G (*(struct globals*)&bb_common_bufsiz1)
> +
> +static int read_int_at(int dirfd, const char *name)
> +{
> + int fd, ret = 0;
> + FILE *fil;
> +
> + if ((fd = openat(dirfd, name, O_RDONLY)) < 0)
> + return -1;
> + fscanf(fil = fdopen(fd, "r"), "%d", &ret);
> + fclose(fil);
> +
> + return ret;
> +}
> +
> +static char *read_type_at(int dirfd)
> +{
> + int fd;
> + if ((fd = openat(dirfd, "type", O_RDONLY)) < 0)
> + return 0;
> + read(fd, G.buf, G_BUFSIZ-1);
> + close(fd);
> + if errno
> + return 0;
> + return G.buf;
> +}
> +
> +int acpi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
> +int acpi_main(int argc UNUSED_PARAM, char **argv)
> +{
> + glob_t files;
> + int dfd, on, cur, max, temp, i;
> + unsigned opts = getopt32(argv, "abctV");
> +
> + if (opts & FLAG_V)
> + opts = FLAG_a | FLAG_b | FLAG_c | FLAG_t;
> + if (!opts)
> + opts = FLAG_b;
> + if (opts & (FLAG_a | FLAG_b)) {
> + glob("/sys/class/power_supply/*/", GLOB_NOSORT, NULL, &files);
> + for (i = 0; i < files.gl_pathc; i++) {
> + errno = 0;
> + if (0 <= (dfd = open(files.gl_pathv[i], O_RDONLY))) {
> + if (!read_type_at(dfd))
> + goto ab_done;
> +
> + if ((!strncmp(G.buf, "Battery", 7)) && (opts & FLAG_b)) {
> + int cap = read_int_at(dfd, "capacity");
> +
> + if (cap < 0) {
> + if ((max = read_int_at(dfd, "charge_full")) > 0)
> + cur = read_int_at(dfd, "charge_now");
> + else if ((max =
> + read_int_at(dfd, "energy_full")) > 0)
> + cur = read_int_at(dfd, "energy_now");
> + if (max > 0)
> + cap = 100 * cur / max;
> + }
> + if (cap >= 0)
> + printf("Battery %d: %d%%\n", G.bat++, cap);
> +
> + } else if ((opts & FLAG_a)
> + && ((on = read_int_at(dfd, "online")) >= 0)) {
> + printf("Adapter %d: %s-line\n", G.ac++,
> + (on ? "on" : "off"));
> + }
> + ab_done:
> + close(dfd);
> + }
> + }
> + globfree(&files);
> + }
> + if (opts & FLAG_t) {
> + glob("/sys/class/*/*/temp", GLOB_NOSORT, NULL, &files);
> + glob("/sys/class/*/*/temp*_input", GLOB_NOSORT | GLOB_APPEND, NULL,
> + &files);
> + for (i = 0; i < files.gl_pathc; i++) {
> + errno = 0;
> + if ((0 < (temp = read_int_at(AT_FDCWD, files.gl_pathv[i])))
> + || !errno) {
> + //some tempertures are in milli-C, some in deci-C
> + //reputedly some are in deci-K, but I have not seen them
> + if (((temp >= 1000) || (temp <= -1000))
> + && (temp % 100 == 0))
> + temp /= 100;
> + printf("Thermal %d: %d.%d degrees C\n", G.therm++,
> + temp / 10, temp % 10);
> + }
> + }
> + globfree(&files);
> + }
> + if (opts & FLAG_c) {
> + glob("/sys/class/thermal/*/", GLOB_NOSORT, NULL, &files);
> + for (i = 0; i < files.gl_pathc; i++) {
> + errno = 0;
> + memset(G.buf, 0, 64);
> + if (0 <= (dfd = open(files.gl_pathv[i], O_RDONLY))) {
> + if (read_type_at(dfd) && !errno) {
> + G.buf[strlen(G.buf) - 1] = 0;
> + cur = read_int_at(dfd, "cur_state");
> + max = read_int_at(dfd, "max_state");
> + if (errno)
> + printf("Cooling %d: %s no state information\n",
> + G.cool++, G.buf);
> + else
> + printf("Cooling %d: %s %d of %d\n", G.cool++, G.buf,
> + cur, max);
> + }
> + close(dfd);
> + }
> + }
> + globfree(&files);
> + }
> + return 0;
> +}
> --
> 2.1.2
>
More information about the busybox
mailing list