commit 6a40413bfd582f7ef59dbe0a6926d7f4b5d8bf8c from: Caleb Stein date: Wed May 27 21:41:28 2026 UTC begin adding pledge support commit - 8321fa19c97a5f78ceca7ea866ca8dc18696d6ba commit + 6a40413bfd582f7ef59dbe0a6926d7f4b5d8bf8c blob - 2efe892c418eaadf452b8ae10c5e71e59cdd871a blob + 29ccceaafc5b3c6e989b5075ad1ed8015cf05366 --- include/statbar.h +++ include/statbar.h @@ -37,11 +37,9 @@ extern void get_clock(void); extern void normalize_clock_interval(const struct timespec *now, struct timespec *next); /* Battery */ -extern char battery_string[11]; +#define BATTERY_STRING_SIZE 11 -extern bool init_battery(void); -extern void get_battery(void); -extern void close_battery(void); +extern pid_t start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout); /* Volume */ extern char volume_string[11]; blob - b67ebc6adadd240baca6ee127b49b5549a39fba0 blob + 2d222454e2b6914d85b9ab08f55cfc0504a9c30c --- modules/battery.c +++ modules/battery.c @@ -3,42 +3,40 @@ #include #include +#include #include #include #include +#include #include "statbar.h" -char battery_string[11]; - static int fd; +static volatile sig_atomic_t should_quit = 0; -bool +int init_battery(void) { fd = open("/dev/apm", O_RDONLY); if (fd < 0) { - perror("battery: open"); - (void)strcpy(battery_string, UNKNOWN); + perror("open"); - return false; + return -1; } - get_battery(); - return true; + return 0; } -void -get_battery() +static void +get_battery(int pipe_fd) { struct apm_power_info pinfo; char pstate[5]; if (ioctl(fd, APM_IOC_GETPOWER, &pinfo) < 0) { - perror("battery: ioctl"); - (void)strcpy(battery_string, UNKNOWN); + perror("ioctl"); return; } @@ -54,12 +52,49 @@ get_battery() else (void)strcpy(pstate, BATT); - (void)snprintf(battery_string, 11, "%s %3d%%", pstate, pinfo.battery_life); + (void)dprintf(pipe_fd, "%s %3d%%", pstate, pinfo.battery_life); } -void -close_battery(void) +static void +signal_handler(int sig) { - (void)close(fd); + if (sig == SIGTERM || sig == SIGINT) should_quit = 1; } +pid_t +start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout) +{ + pid_t pid; + int batt_pipe[2]; + + if (pipe(batt_pipe) == -1) + { + perror("pipe"); + + return -1; + } + *pipe_fd = batt_pipe[0]; + + pid = fork(); + if (pid) return pid; + + if (init_battery() == -1) _exit(-1); + + (void)signal(SIGTERM, signal_handler); + (void)signal(SIGINT, signal_handler); + (void)signal(SIGUSR1, signal_handler); + + while(!should_quit) + { + get_battery(batt_pipe[1]); + (void)nanosleep(timeout, NULL); + + if (getppid() == 1) break; + } + (void)puts("Closing battery pipe"); + (void)close(batt_pipe[1]); + (void)close(batt_pipe[0]); + + _exit(0); +} + blob - 0b5d6618af30297297b0ea8774a6eb67d6f2a2f5 blob + 90a5b407848bd07d74b11f3250c4f6e348a62783 --- src/main.c +++ src/main.c @@ -22,7 +22,6 @@ enum clocks_e { CLOCK_CLOCK, - BATTERY_CLOCK, CPUTEMP_CLOCK, FANSPEED_CLOCK, WEATHER_CLOCK, @@ -74,15 +73,17 @@ install_signal_handlers(void) int main(int argc, char *argv[]) { - Display *display = XOpenDisplay(NULL); + Display *display; Window root; char statbar_text[MAX_STATBAR_LEN]; bool dirty = true; + int batt_fd; + pid_t batt_pid; unsigned char cmd; struct pollfd *cmd_pfd = NULL; + struct pollfd *batt_pfd = NULL; struct pollfd *network_pfd = NULL; struct pollfd *weather_pfd = NULL; - bool apm_open = false; bool hdl_open = false; bool network_open = false; struct timespec now; @@ -95,11 +96,13 @@ main(int argc, char *argv[]) struct timespec fanspeed_interval = { .tv_sec = 3 }; struct timespec weather_interval = { .tv_sec = 1800 }; struct pollfd *pfd; + char battery_string[BATTERY_STRING_SIZE]; int nfds = 2; /* Start with 2 to guarantee space for the network socket and cmd interface */ int i; (void)setvbuf(stdout, NULL, _IOLBF, 0); + display = XOpenDisplay(NULL); if (display == NULL) { (void)puts("Failed to get display"); @@ -117,7 +120,6 @@ main(int argc, char *argv[]) read_config(&clock_interval, &battery_interval, &cputemp_interval, &fanspeed_interval); (void)clock_gettime(CLOCK_BOOTTIME, &now); normalize_clock_interval(&now, &clocks[CLOCK_CLOCK]); - timespecadd(&now, &battery_interval, &clocks[BATTERY_CLOCK]); timespecadd(&now, &cputemp_interval, &clocks[CPUTEMP_CLOCK]); timespecadd(&now, &fanspeed_interval, &clocks[FANSPEED_CLOCK]); timespecadd(&now, &weather_interval, &clocks[WEATHER_CLOCK]); @@ -128,12 +130,13 @@ main(int argc, char *argv[]) } get_clock(); - apm_open = init_battery(); + batt_pid = start_privileged_battery_process(&batt_fd, &battery_interval); hdl_open = init_volume(&nfds); get_cputemp(); get_fanspeed(); get_initial_network_state(); if (weather_loc_valid) nfds++; + if (batt_pid > 0) nfds++; pfd = malloc(nfds * sizeof(struct pollfd)); if (pfd == NULL) @@ -151,12 +154,24 @@ main(int argc, char *argv[]) { weather_pfd = &pfd[nfds - 3]; weather_pfd->fd = weather_pipe[0]; + weather_pfd->events = POLLIN; get_weather(weather_pipe[1]); } + if (batt_pid > 0) + { + batt_pfd = &pfd[nfds - (weather_loc_valid ? 4 : 3)]; + batt_pfd->fd = batt_fd; + batt_pfd->events = POLLIN; + } if (mail_path_valid) mail_path_valid = get_mail(); fill_sndio_pfds(pfd); - weather_pfd->events = POLLIN; + if (pledge("stdio rpath cpath inet proc exec route audio", NULL) == -1) + { + perror("pledge"); + + goto cleanup; + } while (!should_quit) { if (reload_config) @@ -219,6 +234,8 @@ main(int argc, char *argv[]) break; } } + if (batt_pfd->revents & POLLIN) + (void)read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE); if (network_pfd->revents & POLLIN) read_network_socket(network_pfd->fd); if (weather_pfd && (weather_pfd->revents & POLLIN)) @@ -246,13 +263,10 @@ main(int argc, char *argv[]) } /* Battery */ - if (reload_battery || (apm_open && timespeccmp(&now, &clocks[BATTERY_CLOCK], >=))) + if (reload_battery) { reload_battery = 0; - get_battery(); - dirty = true; - while (timespeccmp(&now, &clocks[BATTERY_CLOCK], >=)) - timespecadd(&clocks[BATTERY_CLOCK], &battery_interval, &clocks[BATTERY_CLOCK]); + (void)kill(batt_pid, SIGUSR1); } /* CPU Temp */ @@ -301,7 +315,7 @@ main(int argc, char *argv[]) cleanup: (void)puts("Closing statbar"); - if (apm_open) close_battery(); + if (batt_pid > 0) (void)kill(batt_pid, SIGTERM); if (hdl_open) close_volume(); if (network_open) (void)close(network_pfd->fd); if (weather_loc_valid) close_weather();