commit 4532059f780bfa658d0757e3921441d09b833b0e from: Caleb Stein date: Fri May 22 22:09:55 2026 UTC move to fifo command interface instad of signal handlers in most cases commit - 7c13785946178f23dc739bb6a10800ee7dba968f commit + 4532059f780bfa658d0757e3921441d09b833b0e blob - 76f7b9f674d767119fa8b8c7f798804fb1618862 blob + 2efe892c418eaadf452b8ae10c5e71e59cdd871a --- include/statbar.h +++ include/statbar.h @@ -19,7 +19,7 @@ #define WIFI "\uf1eb" #define ETHERNET "\uef09" -/* Config */ +/* FS */ extern bool weather_loc_valid; extern bool mail_path_valid; @@ -27,6 +27,8 @@ extern void read_config(struct timespec *clock_interva struct timespec *battery_interval, struct timespec *cputemp_interval, struct timespec *fanspeed_interval); +extern int open_command_interface(void); +extern void close_command_interface(void); /* Clock */ extern char clock_string[26]; blob - ac72b49cfe8e5e6cf713b4071ecc9589d4860ccc blob + 49d8a4846e5fa567b4e7a4568411d1182c218d7f --- src/Makefile +++ src/Makefile @@ -1,5 +1,5 @@ PROG= statbar -SRCS= main.c config.c +SRCS= main.c fs.c MAN= CFLAGS += -I../include -I/usr/X11R6/include -I/usr/local/include blob - 7102df21e5b7ef636895621cc42a167f3da6ad54 (mode 644) blob + /dev/null --- src/config.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -#include "statbar.h" - -void -read_config( - struct timespec *clock_interval, - struct timespec *battery_interval, - struct timespec *cputemp_interval, - struct timespec *fanspeed_interval -){ - char *config_full_path; - char *path_sep; - time_t clock_ms; - time_t battery_ms; - time_t cputemp_ms; - char **weather_location; - uid_t uid; - struct passwd *pw; - int mkdir_ret; - FILE *file; - char *line = NULL; - char *delim; - char *nline; - int val; - int i = 0; - size_t n = 0; - - puts("Reading config..."); - - uid = getuid(); - pw = getpwuid(uid); - - if (pw == NULL) - { - perror("getpwuid"); - - return; - } - - if (asprintf(&config_full_path, "%s/.config/statbar/statbar.conf", pw->pw_dir) == -1) - { - perror("asprintf"); - - return; - } - path_sep = config_full_path + 1; - path_sep = strchr(path_sep, '/'); - while (path_sep) - { - *path_sep = '\0'; - mkdir_ret = mkdir(config_full_path, 0700); - if (mkdir_ret != 0 && errno != EEXIST) - { - perror("mkdir"); - free(config_full_path); - - return; - } - *path_sep = '/'; - path_sep++; - path_sep = strchr(path_sep, '/'); - } - file = fopen(config_full_path, "r"); - if (file == NULL) - { - free(config_full_path); - - return; - } - free(config_full_path); - - while (getline(&line, &n, file) > 0) - { - i++; - delim = strchr(line, ':'); - if (delim == NULL || *(delim + 1) == '\n' || *(delim + 1) == '\0') - goto read_err; - - nline = strchr(delim, '\n'); - if (nline != NULL) *nline = '\0'; - - if (strncmp(line, "weather location", strlen("weather location")) == 0) - { - weather_location = get_weather_location_ptr(); - if (weather_loc_valid && *weather_location != NULL) close_weather(); - delim++; - while (*delim == ' ') delim++; - *weather_location = strdup(delim); - if (*weather_location == NULL) - perror("strdup"); - else - weather_loc_valid = true; - - continue; - } - if (strncmp(line, "inbox directory", strlen("inbox directory")) == 0) - { - if (mail_path_valid && *get_mail_path_ptr() != NULL) close_mail(); - delim++; - while (*delim == ' ') delim++; - if (asprintf(get_mail_path_ptr(), "%s/new", delim) == -1) - perror("asprintf"); - else - mail_path_valid = true; - - continue; - } - if (strncmp(line, "ethernet device", strlen("ethernet device")) == 0) - { - delim++; - while (*delim == ' ') delim++; - set_ethernet_device(delim); - continue; - } - if (strncmp(line, "wifi device", strlen("wifi device")) == 0) - { - delim++; - while (*delim == ' ') delim++; - set_wifi_device(delim); - continue; - } - - /* 10 minute max is arbitrary */ - delim++; - val = (int)strtonum(delim, 1, 600000, NULL); - if (val == 0) - goto read_err; - - if (strncmp(line, "clock interval", strlen("clock interval")) == 0) - { - clock_interval->tv_sec = val / 1000; - clock_interval->tv_nsec = (val % 1000) * 1000000; - } - else if (strncmp(line, "battery interval", strlen("battery interval")) == 0) - { - battery_interval->tv_sec = val / 1000; - battery_interval->tv_nsec = (val % 1000) * 1000000; - } - else if (strncmp(line, "cputemp interval", strlen("cputemp interval")) == 0) - { - cputemp_interval->tv_sec = val / 1000; - cputemp_interval->tv_nsec = (val % 1000) * 1000000; - } - else if (strncmp(line, "fanspeed interval", strlen("fanspeed interval")) == 0) - { - fanspeed_interval->tv_sec = val / 1000; - fanspeed_interval->tv_nsec = (val % 1000) * 1000000; - } - else - { - goto read_err; - } - - n = 0; - continue; - - read_err: - (void)printf("Config syntax error line %d: %s\n", i, line); - free(line); - (void)fclose(file); - - return; - } - free(line); - if (ferror(file)) - perror("getline"); - (void)fclose(file); -} blob - /dev/null blob + bfec6b9c22673be04a39246a02ff09db55dc7595 (mode 644) --- /dev/null +++ src/fs.c @@ -0,0 +1,252 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "statbar.h" + +static int fifo_rdfd; +static int fifo_wrfd; +static char *fifopath; + +static int +mkdir_recursive(char *path) +{ + char *path_sep; + int mkdir_ret; + + path_sep = path + 1; + path_sep = strchr(path_sep, '/'); + while (path_sep) + { + *path_sep = '\0'; + mkdir_ret = mkdir(path, 0700); + if (mkdir_ret != 0 && errno != EEXIST) + return -1; + + *path_sep = '/'; + path_sep++; + path_sep = strchr(path_sep, '/'); + } + + return 0; +} + +void +read_config( + struct timespec *clock_interval, + struct timespec *battery_interval, + struct timespec *cputemp_interval, + struct timespec *fanspeed_interval +){ + char *config_full_path; + time_t clock_ms; + time_t battery_ms; + time_t cputemp_ms; + char **weather_location; + uid_t uid; + struct passwd *pw; + FILE *file; + char *line = NULL; + char *delim; + char *nline; + int val; + int i = 0; + size_t n = 0; + + uid = getuid(); + pw = getpwuid(uid); + + if (pw == NULL) + { + perror("getpwuid"); + + return; + } + + if (asprintf(&config_full_path, "%s/.config/statbar/statbar.conf", pw->pw_dir) == -1) + { + perror("asprintf"); + + return; + } + if (mkdir_recursive(config_full_path) != 0) + { + perror("mkdir_recursive"); + free(config_full_path); + + return; + } + + file = fopen(config_full_path, "r"); + if (file == NULL) + { + free(config_full_path); + + return; + } + free(config_full_path); + + while (getline(&line, &n, file) > 0) + { + i++; + delim = strchr(line, ':'); + if (delim == NULL || *(delim + 1) == '\n' || *(delim + 1) == '\0') + goto read_err; + + nline = strchr(delim, '\n'); + if (nline != NULL) *nline = '\0'; + + if (strncmp(line, "weather location", strlen("weather location")) == 0) + { + weather_location = get_weather_location_ptr(); + if (weather_loc_valid && *weather_location != NULL) close_weather(); + delim++; + while (*delim == ' ') delim++; + *weather_location = strdup(delim); + if (*weather_location == NULL) + perror("strdup"); + else + weather_loc_valid = true; + + continue; + } + if (strncmp(line, "inbox directory", strlen("inbox directory")) == 0) + { + if (mail_path_valid && *get_mail_path_ptr() != NULL) close_mail(); + delim++; + while (*delim == ' ') delim++; + if (asprintf(get_mail_path_ptr(), "%s/new", delim) == -1) + perror("asprintf"); + else + mail_path_valid = true; + + continue; + } + if (strncmp(line, "ethernet device", strlen("ethernet device")) == 0) + { + delim++; + while (*delim == ' ') delim++; + set_ethernet_device(delim); + continue; + } + if (strncmp(line, "wifi device", strlen("wifi device")) == 0) + { + delim++; + while (*delim == ' ') delim++; + set_wifi_device(delim); + continue; + } + + /* 10 minute max is arbitrary */ + delim++; + val = (int)strtonum(delim, 1, 600000, NULL); + if (val == 0) + goto read_err; + + if (strncmp(line, "clock interval", strlen("clock interval")) == 0) + { + clock_interval->tv_sec = val / 1000; + clock_interval->tv_nsec = (val % 1000) * 1000000; + } + else if (strncmp(line, "battery interval", strlen("battery interval")) == 0) + { + battery_interval->tv_sec = val / 1000; + battery_interval->tv_nsec = (val % 1000) * 1000000; + } + else if (strncmp(line, "cputemp interval", strlen("cputemp interval")) == 0) + { + cputemp_interval->tv_sec = val / 1000; + cputemp_interval->tv_nsec = (val % 1000) * 1000000; + } + else if (strncmp(line, "fanspeed interval", strlen("fanspeed interval")) == 0) + { + fanspeed_interval->tv_sec = val / 1000; + fanspeed_interval->tv_nsec = (val % 1000) * 1000000; + } + else + { + goto read_err; + } + + n = 0; + continue; + + read_err: + (void)printf("Config syntax error line %d: %s\n", i, line); + free(line); + (void)fclose(file); + + return; + } + free(line); + if (ferror(file)) + perror("getline"); + (void)fclose(file); +} + +int +open_command_interface(void) +{ + uid_t uid; + struct passwd *pw; + + (void)puts("Creating FIFO..."); + + uid = getuid(); + pw = getpwuid(uid); + + if (pw == NULL) + { + perror("getpwuid"); + + return -1; + } + + if (asprintf(&fifopath, "%s/.local/state/statbarcmd", pw->pw_dir) == -1) + { + perror("asprintf"); + + return -1; + } + if (mkfifo(fifopath, 0600) != 0 && errno != EEXIST) + { + perror("mkfifo"); + free(fifopath); + + return -1; + } + fifo_rdfd = open(fifopath, O_RDONLY | O_NONBLOCK); + if (fifo_rdfd == -1) + { + perror("open"); + free(fifopath); + + return -1; + } + fifo_wrfd = open(fifopath, O_WRONLY); + if (fifo_wrfd == -1) + { + perror("open"); + (void)close(fifo_rdfd); + free(fifopath); + + return -1; + } + + return fifo_rdfd; +} + +void +close_command_interface(void) +{ + (void)close(fifo_rdfd); + (void)close(fifo_wrfd); + (void)remove(fifopath); + free(fifopath); +} + blob - effb64cfd1b1b70bf3881b58bff4ed921eb4e316 blob + 0b5d6618af30297297b0ea8774a6eb67d6f2a2f5 --- src/main.c +++ src/main.c @@ -30,10 +30,10 @@ enum clocks_e }; static volatile sig_atomic_t should_quit = 0; -static volatile sig_atomic_t reload_config = 0; -static volatile sig_atomic_t reload_mail = 0; -static volatile sig_atomic_t reload_battery = 0; -static volatile sig_atomic_t reload_weather = 0; +static int reload_config = 0; +static int reload_weather = 0; +static int reload_mail = 0; +static int reload_battery = 0; bool weather_loc_valid = false; bool mail_path_valid = false; @@ -50,21 +50,9 @@ sig_handler(int sig) case SIGINT: should_quit = 1; break; - case SIGHUP: - reload_config = 1; - break; case SIGCHLD: while (waitpid(-1, NULL, WNOHANG) > 0); break; - case SIGWINCH: - reload_weather = 1; - break; - case SIGUSR1: - reload_mail = 1; - break; - case SIGUSR2: - reload_battery = 1; - break; } errno = saved_errno; } @@ -80,11 +68,7 @@ install_signal_handlers(void) if (sigaction(SIGTERM, &sa, NULL) == -1) perror("sigaction"); if (sigaction(SIGINT, &sa, NULL) == -1) perror("sigaction"); - if (sigaction(SIGHUP, &sa, NULL) == -1) perror("sigaction"); if (sigaction(SIGCHLD, &sa, NULL) == -1) perror("sigaction"); - if (sigaction(SIGWINCH, &sa, NULL) == -1) perror("sigaction"); - if (sigaction(SIGUSR1, &sa, NULL) == -1) perror("sigaction"); - if (sigaction(SIGUSR2, &sa, NULL) == -1) perror("sigaction"); } int @@ -94,6 +78,8 @@ main(int argc, char *argv[]) Window root; char statbar_text[MAX_STATBAR_LEN]; bool dirty = true; + unsigned char cmd; + struct pollfd *cmd_pfd = NULL; struct pollfd *network_pfd = NULL; struct pollfd *weather_pfd = NULL; bool apm_open = false; @@ -109,7 +95,7 @@ main(int argc, char *argv[]) struct timespec fanspeed_interval = { .tv_sec = 3 }; struct timespec weather_interval = { .tv_sec = 1800 }; struct pollfd *pfd; - int nfds = 1; /* Start with 1 to guarantee space for the network socket */ + int nfds = 2; /* Start with 2 to guarantee space for the network socket and cmd interface */ int i; (void)setvbuf(stdout, NULL, _IOLBF, 0); @@ -127,6 +113,7 @@ main(int argc, char *argv[]) (void)puts("Welcome to statbar"); /* Init components */ + (void)puts("Reading config..."); read_config(&clock_interval, &battery_interval, &cputemp_interval, &fanspeed_interval); (void)clock_gettime(CLOCK_BOOTTIME, &now); normalize_clock_interval(&now, &clocks[CLOCK_CLOCK]); @@ -154,12 +141,15 @@ main(int argc, char *argv[]) perror("malloc"); goto cleanup; } - network_pfd = &pfd[nfds - 1]; + cmd_pfd = &pfd[nfds - 1]; + cmd_pfd->fd = open_command_interface(); + cmd_pfd->events = POLLIN; + network_pfd = &pfd[nfds - 2]; network_open = init_network_socket(&network_pfd->fd); network_pfd->events = POLLIN; if (weather_loc_valid) { - weather_pfd = &pfd[nfds - 2]; + weather_pfd = &pfd[nfds - 3]; weather_pfd->fd = weather_pipe[0]; get_weather(weather_pipe[1]); } @@ -205,6 +195,30 @@ main(int argc, char *argv[]) { if (hdl_open) process_volume_events(pfd, &hdl_open); + if (cmd_pfd->revents & POLLIN) + { + (void)read(cmd_pfd->fd, &cmd, 1); + (void)printf("Got command 0x%02x: ", cmd); + switch (cmd) + { + case 0x01: + (void)puts("reloading config"); + reload_config = 1; + break; + case 0x02: + (void)puts("reloading weather"); + reload_weather = 1; + break; + case 0x03: + (void)puts("reloading mail"); + reload_mail = 1; + break; + case 0x04: + (void)puts("reloading battery"); + reload_battery = 1; + break; + } + } if (network_pfd->revents & POLLIN) read_network_socket(network_pfd->fd); if (weather_pfd && (weather_pfd->revents & POLLIN)) @@ -299,6 +313,7 @@ cleanup: (void)close(weather_pipe[0]); (void)close(weather_pipe[1]); } + close_command_interface(); free(pfd); return 0;