From b68156c241cacfecff77f15e0f86b0bde0ba7681 Mon Sep 17 00:00:00 2001 From: nikl Date: Sat, 13 Apr 2024 12:04:58 +0200 Subject: [PATCH 1/6] Restructured the file hierarchy and added developer comment in README --- Makefile | 15 +++++++++------ README.md | 8 ++++++++ battery.h => include/battery.h | 0 main.h => include/main.h | 0 notify.h => include/notify.h | 0 options.h => include/options.h | 0 battery.c => src/battery.c | 0 main.c => src/main.c | 0 notify.c => src/notify.c | 0 options.c => src/options.c | 0 10 files changed, 17 insertions(+), 6 deletions(-) rename battery.h => include/battery.h (100%) rename main.h => include/main.h (100%) rename notify.h => include/notify.h (100%) rename options.h => include/options.h (100%) rename battery.c => src/battery.c (100%) rename main.c => src/main.c (100%) rename notify.c => src/notify.c (100%) rename options.c => src/options.c (100%) diff --git a/Makefile b/Makefile index 20e9f27..66447c7 100644 --- a/Makefile +++ b/Makefile @@ -13,9 +13,11 @@ SED = sed GREP = grep CUT = cut -VERSION != $(GREP) VERSION main.h | $(CUT) -d \" -f2 -PROGNAME != $(GREP) PROGNAME main.h | $(CUT) -d \" -f2 -PROGUPPER != $(GREP) PROGUPPER main.h | $(CUT) -d \" -f2 +MAIN_HEADER := include/main.h + +VERSION != $(GREP) VERSION $(MAIN_HEADER) | $(CUT) -d \" -f2 +PROGNAME != $(GREP) PROGNAME $(MAIN_HEADER) | $(CUT) -d \" -f2 +PROGUPPER != $(GREP) PROGUPPER $(MAIN_HEADER) | $(CUT) -d \" -f2 PREFIX = /usr/local @@ -25,6 +27,7 @@ MANPREFIX.=/usr/share/man MANPREFIX=$(MANPREFIX.$(PREFIX)) INCLUDES != pkg-config --cflags libnotify +INCLUDES := $(INCLUDES) -I./include/ CFLAGS_EXTRA = -pedantic -Wall -Wextra -Werror -Wno-unused-parameter -Os CFLAGS := $(CFLAGS_EXTRA) $(INCLUDES) $(CFLAGS) @@ -33,9 +36,9 @@ LIBS := $(LIBS) -lm LDFLAGS_EXTRA = -s LDFLAGS := $(LDFLAGS_EXTRA) $(LDFLAGS) -SRC = main.c options.c battery.c notify.c +SRC = $(wildcard src/*.c) OBJ = $(SRC:.c=.o) -HDR = $(SRC:.c=.h) +HDR = include/*.h .PHONY: all install install-service clean test compile-test @@ -46,7 +49,7 @@ $(TARGET): $(OBJ) %.o: $(HDR) -$(TARGET).1: $(TARGET).1.in main.h +$(TARGET).1: $(TARGET).1.in $(MAIN_HEADER) $(SED) "s/VERSION/$(VERSION)/g" < $(TARGET).1.in | $(SED) "s/PROGNAME/$(PROGNAME)/g" | $(SED) "s/PROGUPPER/$(PROGUPPER)/g" > $@ install: all diff --git a/README.md b/README.md index e69030f..7559a16 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,14 @@ Authors batsignal is written by Corey Hinshaw. It was originally forked from juiced by Aaron Marcher. +Development Notes +----------------- + +For supporting language-server freatures, the `compile_commands.json` file is necessary (at least for the clangd-lsp). +This can be generated with [Bear](https://github.com/rizsotto/Bear): + + $ bear -- make + License and Copyright --------------------- Copyright (c) 2018-2024 Corey Hinshaw diff --git a/battery.h b/include/battery.h similarity index 100% rename from battery.h rename to include/battery.h diff --git a/main.h b/include/main.h similarity index 100% rename from main.h rename to include/main.h diff --git a/notify.h b/include/notify.h similarity index 100% rename from notify.h rename to include/notify.h diff --git a/options.h b/include/options.h similarity index 100% rename from options.h rename to include/options.h diff --git a/battery.c b/src/battery.c similarity index 100% rename from battery.c rename to src/battery.c diff --git a/main.c b/src/main.c similarity index 100% rename from main.c rename to src/main.c diff --git a/notify.c b/src/notify.c similarity index 100% rename from notify.c rename to src/notify.c diff --git a/options.c b/src/options.c similarity index 100% rename from options.c rename to src/options.c From 50d2a1d377ccf4b1597a77f1fd7ce53601173b90 Mon Sep 17 00:00:00 2001 From: nikl Date: Sun, 23 Jun 2024 03:55:49 +0200 Subject: [PATCH 2/6] added first implementation for initilising battery charging state change recognition using inotify --- include/battery.h | 10 +++++++++- src/battery.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- src/main.c | 19 ++++++++++++------- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/include/battery.h b/include/battery.h index 6c2c12d..92c6d48 100644 --- a/include/battery.h +++ b/include/battery.h @@ -5,7 +5,9 @@ #ifndef BATTERY_H #define BATTERY_H +#include #include +#include /* battery states */ #define STATE_AC 0 @@ -34,10 +36,16 @@ typedef struct BatteryState { int level; int energy_full; int energy_now; + int inotify_fd; + int *watch_fds; + pthread_cond_t *bat_state_change; + pthread_mutex_t *state_change_mut; } BatteryState; +BatteryState init_batteries(char **battery_names, int battery_count); +void uninit_batteries(BatteryState * battery); int find_batteries(char ***battery_names); int validate_batteries(char **battery_names, int battery_count); -void update_battery_state(BatteryState *battery, bool required); +void wait_for_update_battery_state(BatteryState *battery, bool required); #endif diff --git a/src/battery.c b/src/battery.c index 170e282..e3054f4 100644 --- a/src/battery.c +++ b/src/battery.c @@ -2,10 +2,12 @@ * Copyright (c) 2018-2024 Corey Hinshaw */ -#define _DEFAULT_SOURCE +#include +#include #include #include #include +#include #include #include #include @@ -110,6 +112,47 @@ int find_batteries(char ***battery_names) return battery_count; } +BatteryState init_batteries(char **battery_names, int battery_count) { + BatteryState battery; + battery.names = battery_names; + battery.count = battery_count; + + // initialise conditional variable and mutex + // for battery charging state changes on all batteries + pthread_cond_init(battery.bat_state_change, NULL); + pthread_mutex_init(battery.state_change_mut, NULL); + + // init inotify-fd for notification on battery charging state changes + battery.inotify_fd = inotify_init1(IN_NONBLOCK); + if (battery.inotify_fd==-1) { + perror("Error on initialising inotify"); + return battery; + } + battery.watch_fds = calloc(battery_count, sizeof(int)); + if (battery.watch_fds==NULL) { + perror("Error while creating memory for inotify watch fds"); + return battery; + } + + // add watch fds for file modifications for each battery charge state file + for (int i = 0; i Date: Sun, 23 Jun 2024 23:38:04 +0200 Subject: [PATCH 3/6] finished initilisation and deinit of inotify file change detection --- include/battery.h | 9 ++- src/battery.c | 161 ++++++++++++++++++++++++++++++++++++++++------ src/main.c | 72 +++++++++++---------- 3 files changed, 184 insertions(+), 58 deletions(-) diff --git a/include/battery.h b/include/battery.h index 92c6d48..0e9fede 100644 --- a/include/battery.h +++ b/include/battery.h @@ -5,7 +5,8 @@ #ifndef BATTERY_H #define BATTERY_H -#include +#include +#include #include #include @@ -40,12 +41,14 @@ typedef struct BatteryState { int *watch_fds; pthread_cond_t *bat_state_change; pthread_mutex_t *state_change_mut; + pthread_t *thread_ids; + atomic_bool *watching; } BatteryState; -BatteryState init_batteries(char **battery_names, int battery_count); +BatteryState* init_batteries(char **battery_names, int battery_count); void uninit_batteries(BatteryState * battery); int find_batteries(char ***battery_names); int validate_batteries(char **battery_names, int battery_count); -void wait_for_update_battery_state(BatteryState *battery, bool required); +void wait_for_update_battery_state(BatteryState *battery, bool required, struct timespec timeout); #endif diff --git a/src/battery.c b/src/battery.c index e3054f4..23740db 100644 --- a/src/battery.c +++ b/src/battery.c @@ -2,18 +2,25 @@ * Copyright (c) 2018-2024 Corey Hinshaw */ +#include "battery.h" #include -#include +#include +#include #include +#include #include #include -#include #include +#include +#include #include #include #include +#include +#include #include -#include "battery.h" + +#define INOTIFY_BUF_SIZE 4096 static char *attr_path = NULL; @@ -112,45 +119,149 @@ int find_batteries(char ***battery_names) return battery_count; } -BatteryState init_batteries(char **battery_names, int battery_count) { - BatteryState battery; - battery.names = battery_names; - battery.count = battery_count; +struct BatteryStateWrapper { + BatteryState *battery; + int bat_id; +}; + +void *watch_for_file_changes(void *battery) { + struct BatteryStateWrapper *bat = battery; + char buf[INOTIFY_BUF_SIZE]; + while (bat->battery->watching) { + // blocks here, until the watched file changes or a signal is send to the thread + printf("Waiting for filechange\n"); + int len = read(bat->battery->watch_fds[bat->bat_id],&buf,sizeof(buf)); + + // error while reading -> signal was send to stop or IO-Error + if (len==-1) { + switch (errno) { + case EINTR: + pthread_cond_broadcast(bat->battery->bat_state_change); + printf("Thread stopped\n"); + return NULL; + default:{ + perror("Unexpected Error in inotify thread"); + printf("Thread stopped\n"); + return NULL; + } + } + } + + // file changed, update request with conditional variable + pthread_cond_signal(bat->battery->bat_state_change); + } + printf("Thread stopped\n"); + return NULL; +} + +void inotify_sig_handler(int sig, siginfo_t *_, void *__) { + printf("Received signal to stop inotify threads, stopping now\n"); +} + +BatteryState *init_batteries(char **battery_names, int battery_count) { + BatteryState *battery; + battery = calloc(1, sizeof(*battery)); + battery->names = battery_names; + battery->count = battery_count; + battery->bat_state_change = calloc(1, sizeof(*battery->bat_state_change)); + battery->state_change_mut = calloc(1, sizeof(*battery->state_change_mut)); + if (battery->bat_state_change == NULL || battery->state_change_mut == NULL) { + perror("Error on initialising conditional var"); + return battery; + } // initialise conditional variable and mutex // for battery charging state changes on all batteries - pthread_cond_init(battery.bat_state_change, NULL); - pthread_mutex_init(battery.state_change_mut, NULL); + pthread_cond_init(battery->bat_state_change, NULL); + pthread_mutex_init(battery->state_change_mut, NULL); + battery->watching = calloc(1, sizeof(*battery->watching)); + if (battery->watching == NULL) { + perror("Error on initialising atomic variable for inotify"); + return battery; + } + *battery->watching = ATOMIC_VAR_INIT(true); // init inotify-fd for notification on battery charging state changes - battery.inotify_fd = inotify_init1(IN_NONBLOCK); - if (battery.inotify_fd==-1) { + battery->inotify_fd = inotify_init1(IN_NONBLOCK); + if (battery->inotify_fd == -1) { perror("Error on initialising inotify"); return battery; } - battery.watch_fds = calloc(battery_count, sizeof(int)); - if (battery.watch_fds==NULL) { + battery->watch_fds = calloc(battery_count, sizeof(int)); + if (battery->watch_fds == NULL) { perror("Error while creating memory for inotify watch fds"); return battery; } + // use sigaction to mask the signal which should be used + // for cancel the threads created below + struct sigaction sa; + sa.sa_sigaction = &inotify_sig_handler; + + if (sigaction(SIGUSR2, &sa, NULL) != 0) { + perror("Error while registering the signal handler for inotify"); + return battery; + } + + battery->thread_ids = calloc(battery->count, sizeof(*battery->thread_ids)); + if (battery->thread_ids == NULL) { + perror("Error while creating memory for inotify thread infos"); + return battery; + } + // add watch fds for file modifications for each battery charge state file - for (int i = 0; icount; i++) { + sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/status", battery->names[i]); + battery->watch_fds[i] = + inotify_add_watch(battery->inotify_fd, attr_path, IN_MODIFY); + if (battery->watch_fds[i] == -1) { + fprintf(stderr, "Cannot watch '%s': %s\n", attr_path, strerror(errno)); continue; } + struct BatteryStateWrapper *b_state = calloc(1, sizeof(struct BatteryStateWrapper)); + if (b_state == NULL) { + perror("Error while creating memory for battery-state wrapper"); + continue; + } + b_state->battery = battery; + b_state->bat_id = i; + // start a thread polling the watch_fd + int ret = pthread_create(&battery->thread_ids[i], NULL, + &watch_for_file_changes, b_state); + if (ret != 0) { + printf("Couldn't start the inotify thread for %s\n", battery->names[i]); + } } return battery; } void uninit_batteries(BatteryState *battery) { - + if (battery->inotify_fd != -1) { + //stopping threads + battery->watching = false; + if (battery->thread_ids!=NULL) { + for (int i = 0; icount; i++) { + printf("Stopping threads\n"); + pthread_kill(battery->thread_ids[i], SIGUSR2); + pthread_join(battery->thread_ids[i], NULL); + } + } + pthread_cond_broadcast(battery->bat_state_change); + + // close watch fds + if (battery->watch_fds != NULL) { + for (int i = 0; i < battery->count; i++) { + if (battery->watch_fds[i] != -1) { + close(battery->watch_fds[i]); + } + } + // stop inotify + close(battery->inotify_fd); + } + } } int validate_batteries(char **battery_names, int battery_count) @@ -175,13 +286,15 @@ int validate_batteries(char **battery_names, int battery_count) return return_value; } -void wait_for_update_battery_state(BatteryState *battery, bool required) +void wait_for_update_battery_state(BatteryState *battery, bool required, + struct timespec timeout) { char state[15]; char *now_attribute; char *full_attribute; unsigned int tmp_now; unsigned int tmp_full; + struct timespec ts; FILE *file; battery->discharging = false; @@ -190,6 +303,14 @@ void wait_for_update_battery_state(BatteryState *battery, bool required) battery->energy_full = 0; set_attributes(battery->names[0], &now_attribute, &full_attribute); + //wait for changes on the state files or for timeout + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += timeout.tv_sec; + ts.tv_nsec += timeout.tv_nsec; + pthread_mutex_lock(battery->state_change_mut); + pthread_cond_timedwait(battery->bat_state_change, battery->state_change_mut, &ts); + pthread_mutex_unlock(battery->state_change_mut); + /* iterate through all batteries */ for (int i = 0; i < battery->count; i++) { sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/status", battery->names[i]); diff --git a/src/main.c b/src/main.c index 5ab06a6..6ecd9c9 100644 --- a/src/main.c +++ b/src/main.c @@ -28,7 +28,7 @@ #include "notify.h" #include "options.h" -BatteryState battery; +BatteryState *battery; void print_version(void) { @@ -82,8 +82,8 @@ void cleanup(void) if (notify_is_initted()) { notify_uninit(); } - if (battery.inotify_fd!=-1) { - uninit_batteries(&battery); + if (battery->inotify_fd!=-1) { + uninit_batteries(battery); } } @@ -98,10 +98,15 @@ int main(int argc, char *argv[]) bool previous_discharging_status; sigset_t sigs; struct timespec timeout = { .tv_sec = 0 }; + struct timespec time_0 = {0,0}; int bat_index; char *config_file = NULL; int conf_argc = 0; char **conf_argv; + battery = calloc(1, sizeof(*battery)); + if (battery==NULL) { + err(EXIT_FAILURE, "Failed to allocate memory for battery struct"); + } Config config = { .daemonize = false, @@ -180,70 +185,67 @@ int main(int argc, char *argv[]) err(EXIT_FAILURE, "Failed to daemonize"); } - battery.names = config.battery_names; - battery.count = config.battery_count; battery = init_batteries(config.battery_names, config.battery_count); - wait_for_update_battery_state(&battery, config.battery_required); + wait_for_update_battery_state(battery, config.battery_required, timeout); for(;;) { - previous_discharging_status = battery.discharging; - wait_for_update_battery_state(&battery, config.battery_required); + previous_discharging_status = battery->discharging; duration = config.multiplier; - if (battery.discharging) { /* discharging */ - if (config.danger && battery.level <= config.danger) { - if (battery.state != STATE_DANGER) { - battery.state = STATE_DANGER; + if (battery->discharging) { /* discharging */ + if (config.danger && battery->level <= config.danger) { + if (battery->state != STATE_DANGER) { + battery->state = STATE_DANGER; if (config.dangercmd[0] != '\0') if (system(config.dangercmd) == -1) { /* Ignore command errors... */ } } - } else if (config.critical && battery.level <= config.critical) { - if (battery.state != STATE_CRITICAL) { - battery.state = STATE_CRITICAL; - notify(config.criticalmsg, NOTIFY_URGENCY_CRITICAL, battery); + } else if (config.critical && battery->level <= config.critical) { + if (battery->state != STATE_CRITICAL) { + battery->state = STATE_CRITICAL; + notify(config.criticalmsg, NOTIFY_URGENCY_CRITICAL, *battery); } - } else if (config.warning && battery.level <= config.warning) { + } else if (config.warning && battery->level <= config.warning) { if (!config.fixed) - duration = (battery.level - config.critical) * config.multiplier; + duration = (battery->level - config.critical) * config.multiplier; - if (battery.state != STATE_WARNING) { - battery.state = STATE_WARNING; - notify(config.warningmsg, NOTIFY_URGENCY_NORMAL, battery); + if (battery->state != STATE_WARNING) { + battery->state = STATE_WARNING; + notify(config.warningmsg, NOTIFY_URGENCY_NORMAL, *battery); } } else { - if (config.show_charging_msg && battery.discharging != previous_discharging_status) { - notify(config.dischargingmsg, NOTIFY_URGENCY_NORMAL, battery); - } else if (battery.state == STATE_FULL) { + if (config.show_charging_msg && battery->discharging != previous_discharging_status) { + notify(config.dischargingmsg, NOTIFY_URGENCY_NORMAL, *battery); + } else if (battery->state == STATE_FULL) { close_notification(); } - battery.state = STATE_DISCHARGING; + battery->state = STATE_DISCHARGING; if (!config.fixed) - duration = (battery.level - config.warning) * config.multiplier; + duration = (battery->level - config.warning) * config.multiplier; } } else { /* charging */ - if ((config.full && battery.state != STATE_FULL) && (battery.level >= config.full || battery.full)) { - battery.state = STATE_FULL; - notify(config.fullmsg, NOTIFY_URGENCY_NORMAL, battery); + if ((config.full && battery->state != STATE_FULL) && (battery->level >= config.full || battery->full)) { + battery->state = STATE_FULL; + notify(config.fullmsg, NOTIFY_URGENCY_NORMAL, *battery); - } else if (config.show_charging_msg && battery.discharging != previous_discharging_status) { - battery.state = STATE_AC; - notify(config.chargingmsg, NOTIFY_URGENCY_NORMAL, battery); + } else if (config.show_charging_msg && battery->discharging != previous_discharging_status) { + battery->state = STATE_AC; + notify(config.chargingmsg, NOTIFY_URGENCY_NORMAL, *battery); } else { - battery.state = STATE_AC; + battery->state = STATE_AC; close_notification(); } } if (config.multiplier == 0) { - sigwaitinfo(&sigs, NULL); + wait_for_update_battery_state(battery, config.battery_required, time_0); } else { timeout.tv_sec = duration; - sigtimedwait(&sigs, NULL, &timeout); + wait_for_update_battery_state(battery, config.battery_required, timeout); } if (config.run_once) break; From f5c3c3365691986af4e643e9eafa909f7541b519 Mon Sep 17 00:00:00 2001 From: nikl174 Date: Mon, 24 Jun 2024 14:24:30 +0200 Subject: [PATCH 4/6] used pthread_cancle instead of kill for stopping the threads and removed unecessary signal handling --- src/battery.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/battery.c b/src/battery.c index 23740db..833e6ea 100644 --- a/src/battery.c +++ b/src/battery.c @@ -134,17 +134,9 @@ void *watch_for_file_changes(void *battery) { // error while reading -> signal was send to stop or IO-Error if (len==-1) { - switch (errno) { - case EINTR: - pthread_cond_broadcast(bat->battery->bat_state_change); - printf("Thread stopped\n"); - return NULL; - default:{ perror("Unexpected Error in inotify thread"); printf("Thread stopped\n"); return NULL; - } - } } // file changed, update request with conditional variable @@ -154,10 +146,6 @@ void *watch_for_file_changes(void *battery) { return NULL; } -void inotify_sig_handler(int sig, siginfo_t *_, void *__) { - printf("Received signal to stop inotify threads, stopping now\n"); -} - BatteryState *init_batteries(char **battery_names, int battery_count) { BatteryState *battery; battery = calloc(1, sizeof(*battery)); @@ -193,15 +181,6 @@ BatteryState *init_batteries(char **battery_names, int battery_count) { return battery; } - // use sigaction to mask the signal which should be used - // for cancel the threads created below - struct sigaction sa; - sa.sa_sigaction = &inotify_sig_handler; - - if (sigaction(SIGUSR2, &sa, NULL) != 0) { - perror("Error while registering the signal handler for inotify"); - return battery; - } battery->thread_ids = calloc(battery->count, sizeof(*battery->thread_ids)); if (battery->thread_ids == NULL) { @@ -244,8 +223,7 @@ void uninit_batteries(BatteryState *battery) { battery->watching = false; if (battery->thread_ids!=NULL) { for (int i = 0; icount; i++) { - printf("Stopping threads\n"); - pthread_kill(battery->thread_ids[i], SIGUSR2); + pthread_cancel(battery->thread_ids[i]); pthread_join(battery->thread_ids[i], NULL); } } From 6772b3d74dbfa92ef1937f309a8cc3e03345ea2d Mon Sep 17 00:00:00 2001 From: nikl174 Date: Wed, 26 Jun 2024 22:58:44 +0200 Subject: [PATCH 5/6] fixed file watching (wrong file descriptor) --- src/battery.c | 82 +++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/battery.c b/src/battery.c index 833e6ea..a4366ef 100644 --- a/src/battery.c +++ b/src/battery.c @@ -3,20 +3,20 @@ */ #include "battery.h" -#include #include -#include #include -#include #include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include @@ -24,8 +24,8 @@ static char *attr_path = NULL; -static void set_attributes(char *battery_name, char **now_attribute, char **full_attribute) -{ +static void set_attributes(char *battery_name, char **now_attribute, + char **full_attribute) { sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/charge_now", battery_name); if (access(attr_path, F_OK) == 0) { *now_attribute = "charge_now"; @@ -42,22 +42,21 @@ static void set_attributes(char *battery_name, char **now_attribute, char **full } } -static bool is_type_battery(char *name) -{ +static bool is_type_battery(char *name) { FILE *file; char type[11] = ""; sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/type", name); file = fopen(attr_path, "r"); if (file != NULL) { - if (fscanf(file, "%10s", type) == 0) { /* Continue... */ } + if (fscanf(file, "%10s", type) == 0) { /* Continue... */ + } fclose(file); } return strcmp(type, "Battery") == 0; } -static bool has_capacity_field(char *name) -{ +static bool has_capacity_field(char *name) { FILE *file; int capacity = -1; char *now_attribute; @@ -69,7 +68,8 @@ static bool has_capacity_field(char *name) sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/capacity", name); file = fopen(attr_path, "r"); if (file != NULL) { - if (fscanf(file, "%d", &capacity) == 0) { /* Continue... */ } + if (fscanf(file, "%d", &capacity) == 0) { /* Continue... */ + } fclose(file); } } else { @@ -78,14 +78,13 @@ static bool has_capacity_field(char *name) return capacity >= 0; } -static bool is_battery(char *name) -{ +static bool is_battery(char *name) { return is_type_battery(name) && has_capacity_field(name); } -int find_batteries(char ***battery_names) -{ - unsigned int path_len = strlen(POWER_SUPPLY_SUBSYSTEM) + POWER_SUPPLY_ATTR_LENGTH; +int find_batteries(char ***battery_names) { + unsigned int path_len = + strlen(POWER_SUPPLY_SUBSYSTEM) + POWER_SUPPLY_ATTR_LENGTH; unsigned int entry_name_len = 5; int battery_count = 0; DIR *dir; @@ -104,7 +103,8 @@ int find_batteries(char ***battery_names) } if (is_battery(entry->d_name)) { - *battery_names = realloc(*battery_names, sizeof(char *) * (battery_count+1)); + *battery_names = + realloc(*battery_names, sizeof(char *) * (battery_count + 1)); if (*battery_names == NULL) err(EXIT_FAILURE, "Memory allocation failed"); (*battery_names)[battery_count] = strdup(entry->d_name); @@ -128,15 +128,16 @@ void *watch_for_file_changes(void *battery) { struct BatteryStateWrapper *bat = battery; char buf[INOTIFY_BUF_SIZE]; while (bat->battery->watching) { - // blocks here, until the watched file changes or a signal is send to the thread + // blocks here, until the watched file changes or a signal is send to the + // thread printf("Waiting for filechange\n"); - int len = read(bat->battery->watch_fds[bat->bat_id],&buf,sizeof(buf)); + int len = read(bat->battery->inotify_fd, &buf, sizeof(buf)); // error while reading -> signal was send to stop or IO-Error - if (len==-1) { - perror("Unexpected Error in inotify thread"); - printf("Thread stopped\n"); - return NULL; + if (len == -1) { + perror("Unexpected Error in inotify thread"); + printf("Thread stopped\n"); + return NULL; } // file changed, update request with conditional variable @@ -170,7 +171,7 @@ BatteryState *init_batteries(char **battery_names, int battery_count) { *battery->watching = ATOMIC_VAR_INIT(true); // init inotify-fd for notification on battery charging state changes - battery->inotify_fd = inotify_init1(IN_NONBLOCK); + battery->inotify_fd = inotify_init(); if (battery->inotify_fd == -1) { perror("Error on initialising inotify"); return battery; @@ -181,7 +182,6 @@ BatteryState *init_batteries(char **battery_names, int battery_count) { return battery; } - battery->thread_ids = calloc(battery->count, sizeof(*battery->thread_ids)); if (battery->thread_ids == NULL) { perror("Error while creating memory for inotify thread infos"); @@ -192,13 +192,14 @@ BatteryState *init_batteries(char **battery_names, int battery_count) { for (int i = 0; i < battery->count; i++) { sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/status", battery->names[i]); battery->watch_fds[i] = - inotify_add_watch(battery->inotify_fd, attr_path, IN_MODIFY); + inotify_add_watch(battery->inotify_fd, attr_path, IN_MODIFY | IN_ACCESS); if (battery->watch_fds[i] == -1) { fprintf(stderr, "Cannot watch '%s': %s\n", attr_path, strerror(errno)); continue; } - struct BatteryStateWrapper *b_state = calloc(1, sizeof(struct BatteryStateWrapper)); + struct BatteryStateWrapper *b_state = + calloc(1, sizeof(struct BatteryStateWrapper)); if (b_state == NULL) { perror("Error while creating memory for battery-state wrapper"); continue; @@ -219,10 +220,10 @@ BatteryState *init_batteries(char **battery_names, int battery_count) { void uninit_batteries(BatteryState *battery) { if (battery->inotify_fd != -1) { - //stopping threads + // stopping threads battery->watching = false; - if (battery->thread_ids!=NULL) { - for (int i = 0; icount; i++) { + if (battery->thread_ids != NULL) { + for (int i = 0; i < battery->count; i++) { pthread_cancel(battery->thread_ids[i]); pthread_join(battery->thread_ids[i], NULL); } @@ -242,9 +243,9 @@ void uninit_batteries(BatteryState *battery) { } } -int validate_batteries(char **battery_names, int battery_count) -{ - unsigned int path_len = strlen(POWER_SUPPLY_SUBSYSTEM) + POWER_SUPPLY_ATTR_LENGTH; +int validate_batteries(char **battery_names, int battery_count) { + unsigned int path_len = + strlen(POWER_SUPPLY_SUBSYSTEM) + POWER_SUPPLY_ATTR_LENGTH; unsigned int name_len = 5; int return_value = -1; @@ -265,8 +266,7 @@ int validate_batteries(char **battery_names, int battery_count) } void wait_for_update_battery_state(BatteryState *battery, bool required, - struct timespec timeout) -{ + struct timespec timeout) { char state[15]; char *now_attribute; char *full_attribute; @@ -281,12 +281,14 @@ void wait_for_update_battery_state(BatteryState *battery, bool required, battery->energy_full = 0; set_attributes(battery->names[0], &now_attribute, &full_attribute); - //wait for changes on the state files or for timeout + // wait for changes on the state files or for timeout clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += timeout.tv_sec; ts.tv_nsec += timeout.tv_nsec; pthread_mutex_lock(battery->state_change_mut); - pthread_cond_timedwait(battery->bat_state_change, battery->state_change_mut, &ts); + int success = pthread_cond_timedwait(battery->bat_state_change, + battery->state_change_mut, &ts); + printf("Timed out waiting: %d\n", (success == 0)); pthread_mutex_unlock(battery->state_change_mut); /* iterate through all batteries */ @@ -306,7 +308,8 @@ void wait_for_update_battery_state(BatteryState *battery, bool required, battery->discharging |= strcmp(state, POWER_SUPPLY_DISCHARGING) == 0; battery->full &= strcmp(state, POWER_SUPPLY_FULL) == 0; - sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/%s", battery->names[i], now_attribute); + sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/%s", battery->names[i], + now_attribute); file = fopen(attr_path, "r"); if (file == NULL || fscanf(file, "%u", &tmp_now) == 0) { if (required) @@ -318,7 +321,8 @@ void wait_for_update_battery_state(BatteryState *battery, bool required, fclose(file); if (full_attribute != NULL) { - sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/%s", battery->names[i], full_attribute); + sprintf(attr_path, POWER_SUPPLY_SUBSYSTEM "/%s/%s", battery->names[i], + full_attribute); file = fopen(attr_path, "r"); if (file == NULL || fscanf(file, "%u", &tmp_full) == 0) { if (required) From 5b60d793eba02b3b55e6c40746313adb6c346147 Mon Sep 17 00:00:00 2001 From: nikl174 Date: Wed, 26 Jun 2024 23:10:28 +0200 Subject: [PATCH 6/6] removed unneeded debug messages --- src/battery.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/battery.c b/src/battery.c index a4366ef..deed947 100644 --- a/src/battery.c +++ b/src/battery.c @@ -130,7 +130,6 @@ void *watch_for_file_changes(void *battery) { while (bat->battery->watching) { // blocks here, until the watched file changes or a signal is send to the // thread - printf("Waiting for filechange\n"); int len = read(bat->battery->inotify_fd, &buf, sizeof(buf)); // error while reading -> signal was send to stop or IO-Error @@ -286,9 +285,8 @@ void wait_for_update_battery_state(BatteryState *battery, bool required, ts.tv_sec += timeout.tv_sec; ts.tv_nsec += timeout.tv_nsec; pthread_mutex_lock(battery->state_change_mut); - int success = pthread_cond_timedwait(battery->bat_state_change, + pthread_cond_timedwait(battery->bat_state_change, battery->state_change_mut, &ts); - printf("Timed out waiting: %d\n", (success == 0)); pthread_mutex_unlock(battery->state_change_mut); /* iterate through all batteries */