commit 069363286eaa434ca1bcea830ed897bd5bca9aac from: Caleb Stein date: Fri Jul 31 22:28:41 2026 UTC add timer module commit - 3726d3ccf1e70c2d368684178c12bbd4636842df commit + 069363286eaa434ca1bcea830ed897bd5bca9aac blob - 15618524e6bf84d52c325faf94753adeec699edb blob + a9fd703197692fd2ddc1345fd0b6380fe0b34cd7 --- include/statbar.h +++ include/statbar.h @@ -22,6 +22,7 @@ extern void read_config(void); extern int open_command_interface(void); extern int open_output(void); +extern int open_timer(void); extern void close_fifos(void); /* Clock */ @@ -40,6 +41,11 @@ extern pid_t start_privileged_battery_process(int *pip extern pid_t start_volume_process(int *pipe_fd); +/* Timer */ +#define TIMER_STRING_SIZE 6 + +extern pid_t start_timer_process(int *pipe_fd, int timerval_fd); + /* Mail */ extern char mail_string[7]; blob - 4122a3ed28669554cdf43f33d621d9c7358a2f56 blob + 92602b1f173905c829783717a73861694d3e643f --- modules/Makefile +++ modules/Makefile @@ -1,5 +1,5 @@ LIB= statbar_modules -SRCS= clock.c battery.c volume.c mail.c network.c +SRCS= clock.c battery.c volume.c timer.c mail.c network.c MAN= CFLAGS += -I../include -I/usr/local/include blob - /dev/null blob + ed6199d3b8e92e88017d59b52f59ec2e3e5725b9 (mode 644) --- /dev/null +++ modules/timer.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "statbar.h" + +static volatile sig_atomic_t should_quit = 0; + +static void +signal_handler(int sig) +{ + if (sig == SIGTERM || sig == SIGINT) should_quit = 1; +} + +pid_t +start_timer_process(int *pipe_fd, int timerval_fd) +{ + pid_t pid; + int timer_pipe[2]; + struct pollfd pfd; + int flags; + ssize_t n; + char buf[1024]; + char *delim; + struct timespec init; + struct timespec start; + struct timespec cur; + struct timespec elapsed; + struct timespec display; + long min; + long sec; + + if (pipe(timer_pipe) == -1) + { + perror("pipe"); + + return -1; + } + *pipe_fd = timer_pipe[0]; + + pid = fork(); + if (pid) + { + if (pid == -1) (void)close(timer_pipe[0]); + (void)close(timer_pipe[1]); + + return pid; + } + + flags = fcntl(timerval_fd, F_GETFL, 0); + (void)fcntl(timerval_fd, F_SETFL, flags | O_NONBLOCK); + pfd.fd = timerval_fd; + pfd.events = POLLIN; + (void)close(timer_pipe[0]); + setproctitle("timer"); + (void)puts("Timer process started"); + + (void)signal(SIGTERM, signal_handler); + (void)signal(SIGINT, signal_handler); + + if (pledge("stdio", NULL) == -1) + { + perror("pledge"); + (void)close(timer_pipe[0]); + (void)close(timer_pipe[1]); + + _exit(1); + } + + (void)dprintf(timer_pipe[1], "00:00"); + while(!should_quit) + { + if (poll(&pfd, 1, INFTIM) > 0) + { + n = read(pfd.fd, buf, sizeof(buf)); + + if (n < 0 && errno == EAGAIN) continue; + } + delim = strchr(buf, ':'); + if (delim) + { + *delim = '\0'; + delim++; + + min = strtol(buf, NULL, 10) * 60; + sec = strtol(delim, NULL, 10); + init.tv_sec = (time_t)(min + sec); + } + else + { + sec = strtol(buf, NULL, 10); + init.tv_sec = (time_t)sec; + } + init.tv_nsec = 0; + + while(1) + { + n = read(pfd.fd, buf, sizeof(buf)); + + if (n > 0) continue; + if (n == 0) + { + should_quit = 1; + + break; + } + if (n < 0) + { + if (errno == EAGAIN) break; + + perror("read"); + should_quit = 1; + + break; + } + } + + (void)clock_gettime(CLOCK_MONOTONIC, &start); + while(!should_quit) + { + (void)clock_gettime(CLOCK_MONOTONIC, &cur); + timespecsub(&cur, &start, &elapsed); + timespecsub(&init, &elapsed, &display); + if (display.tv_sec == 0) + { + (void)dprintf(timer_pipe[1], "00:00"); + + break; + } + else + { + (void)dprintf(timer_pipe[1], "%02jd:%02jd", (intmax_t)display.tv_sec / 60, (intmax_t)display.tv_sec % 60); + } + + if (poll(&pfd, 1, 1000) > 0) break; + } + + if (getppid() == 1) break; + } + (void)puts("Closing timer process"); + (void)close(timer_pipe[1]); + + _exit(0); +} + blob - 2859a99ccb6eb86e9d8dbc839025bbb806b0cde4 blob + a118dc16d10119e830a3bff3a1420697a4a8e5f3 --- src/fs.c +++ src/fs.c @@ -15,6 +15,9 @@ static char *cmdpath; static int out_rdfd; static int out_wrfd; static char *outpath; +static int timer_rdfd; +static int timer_wrfd; +static char *timerpath; static int mkdir_recursive(char *path) @@ -201,6 +204,12 @@ open_output(void) return open_fifo(&out_rdfd, &out_wrfd, &outpath, "/.local/state/statbarout", 1); } +int +open_timer(void) +{ + return open_fifo(&timer_rdfd, &timer_wrfd, &timerpath, "/.local/state/statbartimer", 0); +} + void close_fifos(void) { @@ -212,5 +221,9 @@ close_fifos(void) (void)close(out_wrfd); (void)remove(outpath); free(outpath); + (void)close(timer_rdfd); + (void)close(timer_wrfd); + (void)remove(timerpath); + free(timerpath); } blob - c5459bffd2095a91b09ebb586437be58b169a07e blob + c4e10c11c7a8f1e72c93899d6d35f3f2464ead8a --- src/main.c +++ src/main.c @@ -14,7 +14,7 @@ #include "statbar.h" -#define NFDS 4 +#define NFDS 5 enum clocks_e { @@ -65,9 +65,12 @@ main(void) int output_fd; int batt_fd; int vol_fd; + int timer_fd; + int timerval_fd; int network_fd; pid_t batt_pid; pid_t vol_pid; + pid_t timer_pid; pid_t network_pid; unsigned char cmd; bool network_open = false; @@ -81,9 +84,11 @@ main(void) struct pollfd *cmd_pfd = &pfd[0]; struct pollfd *batt_pfd = &pfd[1]; struct pollfd *vol_pfd = &pfd[2]; - struct pollfd *network_pfd = &pfd[3]; + struct pollfd *timer_pfd = &pfd[3]; + struct pollfd *network_pfd = &pfd[4]; char battery_string[BATTERY_STRING_SIZE]; char volume_string[VOLUME_STRING_SIZE]; + char timer_string[TIMER_STRING_SIZE]; char network_string[NETWORK_STRING_SIZE]; int i; ssize_t n; @@ -104,10 +109,18 @@ main(void) read_config(); (void)clock_gettime(CLOCK_BOOTTIME, &now); normalize_clock_interval(&now, &clocks[CLOCK_CLOCK]); + timerval_fd = open_timer(); + if (timer_fd == -1) + { + (void)puts("Failed to open timer FIFO"); + return -1; + } + get_clock(); batt_pid = start_privileged_battery_process(&batt_fd, &battery_interval); vol_pid = start_volume_process(&vol_fd); + timer_pid = start_timer_process(&timer_fd, timerval_fd); network_pid = start_network_process(&network_fd); cmd_pfd->fd = open_command_interface(); @@ -122,6 +135,11 @@ main(void) vol_pfd->fd = vol_fd; vol_pfd->events = POLLIN; } + if (timer_pid > 0) + { + timer_pfd->fd = timer_fd; + timer_pfd->events = POLLIN; + } if (network_pid > 0) { network_pfd->fd = network_fd; @@ -189,6 +207,11 @@ main(void) n = read(vol_pfd->fd, volume_string, VOLUME_STRING_SIZE); if (n > 0) volume_string[n] = '\0'; } + if (timer_pfd->revents & POLLIN) + { + n = read(timer_pfd->fd, timer_string, TIMER_STRING_SIZE); + if (n > 0) timer_string[n] = '\0'; + } if (network_pfd->revents & POLLIN) { n = read(network_pfd->fd, network_string, NETWORK_STRING_SIZE); @@ -225,10 +248,11 @@ main(void) if (dirty) { - (void)dprintf(output_fd, "%s | %s | %s | %s%s\n", + (void)dprintf(output_fd, "%s | %s | %s | %s | %s%s\n", clock_string, battery_string, volume_string, + timer_string, network_string, mail_string); dirty = false; @@ -239,6 +263,7 @@ cleanup: (void)puts("Closing statbar"); if (batt_pid > 0) (void)kill(batt_pid, SIGTERM); if (vol_pid > 0) (void)kill(vol_pid, SIGTERM); + if (timer_pid > 0) (void)kill(timer_pid, SIGTERM); if (network_pid > 0) (void)kill(network_pid, SIGTERM); close_mail(); close_fifos(); blob - /dev/null blob + a6699539d22aac30e34397bd019523431ff30094 (mode 755) --- /dev/null +++ stimer.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +STATBARTIMER=~/.local/state/statbartimer + +show_help() +{ + echo "stimer help" + echo "\nstimer is used to set the statbar timer widget" + echo "statbar must be running for this program to be useful" + echo "\nUsage:" + echo "\tstimer