From ce255302720ab5c53f0fcb04abbe2c4738ae251d Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 5 Feb 2019 13:51:30 +0100 Subject: Initial --- .gitignore | 2 + Makefile | 10 ++++ batwarn_daemon.c | 85 +++++++++++++++++++++++++++ old/batwarn.sh | 26 +++++++++ old/syscalls_per_iteration.txt | 126 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 batwarn_daemon.c create mode 100755 old/batwarn.sh create mode 100644 old/syscalls_per_iteration.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbf6ab9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +batwarn_daemon +compile_commands.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..206a678 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CC = gcc +CFLAGS = -Wall -Wextra -std=c11 -O3 -fwrapv +TARGET = batwarn_daemon + +.PHONY: all clean + +all: $(TARGET) + +clean: + rm -f $(TARGET) diff --git a/batwarn_daemon.c b/batwarn_daemon.c new file mode 100644 index 0000000..1cd1d17 --- /dev/null +++ b/batwarn_daemon.c @@ -0,0 +1,85 @@ +// For nanosleep(), pread() +#define _POSIX_C_SOURCE 200809L + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// Warning when battery percentage is <= this +static const int WARN_PERC = 10; + +// Time to sleep between checks +static const struct timespec SLEEP_SPEC = {60, 0}; + +// Format string with percentage %d +static const char *MESSAGE_FORMAT = "Battery at %d%%!"; + + +static inline void parse(const char *buffer, bool *discharging, int *charge, int *full) { + while (true) { + if (memcmp(buffer, "POWER_SUPPLY_STATUS", 19) == 0) { + *discharging = memcmp(buffer + 20, "Discharging", 11) == 0; + } else if (memcmp(buffer, "POWER_SUPPLY_CHARGE_NOW", 23) == 0) { + *charge = strtol(buffer + 24, NULL, 10); + } else if (memcmp(buffer, "POWER_SUPPLY_CHARGE_FULL_DESIGN", 31) == 0) { + *full = strtol(buffer + 32, NULL, 10); + } + buffer = strchr(buffer, '\n'); + if (buffer != NULL) buffer++; + else break; + } +} + +int main(void) { + int fd = open("/sys/class/power_supply/BAT1/uevent", O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } + + char buffer[1024]; + + while (true) { + ssize_t nr = pread(fd, buffer, sizeof buffer, 0); + if (nr < 0) { + perror("pread"); + break; + } + + bool discharging = false; + int charge = 1, full = 1; + parse(buffer, &discharging, &charge, &full); + + if (full > 0 && discharging && charge * 100 / full <= WARN_PERC) { + pid_t pid = fork(); + if (pid < 0) perror("fork"); + else if (pid == 0) { + char msg[strlen(MESSAGE_FORMAT) + 16]; + snprintf(msg, sizeof msg, MESSAGE_FORMAT, charge * 100 / full); + char *argv[4] = {"i3-nagbar", "-m", msg, NULL}; + execv("/usr/bin/i3-nagbar", argv); + perror("execv"); + exit(255); + } else { + int status; + do if (waitpid(pid, &status, 0) < 0 && errno == ECHILD) break; + while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + } + + (void)nanosleep(&SLEEP_SPEC, NULL); + } + + if (close(fd) < 0) { + perror("close"); + return 1; + } +} diff --git a/old/batwarn.sh b/old/batwarn.sh new file mode 100755 index 0000000..2556a70 --- /dev/null +++ b/old/batwarn.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +function get_props_key() { + local v="$(grep "$1" <<<"$props")" + echo "${v/*=}" +} + +function do_check() { + while read line; do + key="${line/=*}" + value="${line/*=}" + [[ $key = "POWER_SUPPLY_STATUS" ]] && status="$value" + [[ $key = "POWER_SUPPLY_CHARGE_NOW" ]] && charge="$value" + [[ $key = "POWER_SUPPLY_CHARGE_FULL_DESIGN" ]] && full="$value" + done