commit f80a5ceaf03e13c98e13cc9091cb44c854f8e7ef from: Caleb Stein date: Sat Aug 8 18:06:33 2026 UTC move clock to its own process commit - 183ace42beda3989346ed6cfbe03304d1ebd56e0 commit + f80a5ceaf03e13c98e13cc9091cb44c854f8e7ef blob - 3e826ae5a25a67821578d46aafe411c6226ddc37 blob + 10c5e40f61e9c931a9a6eafc895afc0263f056f4 --- include/statbar.h +++ include/statbar.h @@ -27,15 +27,14 @@ extern int open_timer(void); extern void close_fifos(void); /* Clock */ -extern char clock_string[26]; +#define CLOCK_STRING_SIZE 23 -extern void get_clock(void); -extern void normalize_clock_interval(const struct timespec *now, struct timespec *next); +extern pid_t start_clock_process(int *pipe_fd); /* Battery */ #define BATTERY_STRING_SIZE 12 -extern pid_t start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout); +extern pid_t start_privileged_battery_process(int *pipe_fd); /* Volume */ #define VOLUME_STRING_SIZE 12 blob - 6e8ecdae9b8fa5d4f81f37b56b99230fe910f3d1 blob + 489a70b8b32e25fe9908b0b052709cc59c8d923e --- modules/clock.c +++ modules/clock.c @@ -1,11 +1,14 @@ +#include #include +#include + #include "statbar.h" -char clock_string[26]; +static volatile sig_atomic_t should_quit = 0; -void -get_clock(void) +static void +get_clock(char *clock_string) { time_t current_time; struct tm loc_time; @@ -17,11 +20,11 @@ get_clock(void) return; } - (void)strftime(clock_string, sizeof(clock_string), "%F %l:%M %p", &loc_time); + (void)strftime(clock_string, CLOCK_STRING_SIZE, "%F %l:%M %p", &loc_time); } -void -normalize_clock_interval(const struct timespec *now, struct timespec *next) +static void +normalize_clock_interval(struct timespec *next) { time_t current_time; struct tm loc_time; @@ -29,13 +32,78 @@ normalize_clock_interval(const struct timespec *now, s current_time = time(NULL); if (localtime_r(¤t_time, &loc_time) == NULL) { - perror("localtime_r"); - next->tv_sec = now->tv_sec + 60; - next->tv_nsec = now->tv_nsec; + next->tv_sec = 60; + next->tv_nsec = 0; return; } - next->tv_sec = now->tv_sec + 60 - loc_time.tm_sec; - next->tv_nsec = now->tv_nsec; + next->tv_sec = 60 - loc_time.tm_sec; + next->tv_nsec = 0; } +static void +signal_handler(int sig) +{ + if (sig == SIGTERM || sig == SIGINT) should_quit = 1; +} + +pid_t +start_clock_process(int *pipe_fd) +{ + pid_t pid; + int clock_pipe[2]; + struct timespec interval; + char clock_string[CLOCK_STRING_SIZE + 1]; + + if (pipe(clock_pipe) == -1) + { + perror("pipe"); + + return -1; + } + *pipe_fd = clock_pipe[0]; + + pid = fork(); + if (pid) + { + if (pid == -1) (void)close(clock_pipe[0]); + (void)close(clock_pipe[1]); + + return pid; + } + + (void)close(clock_pipe[0]); + setproctitle("clock"); + (void)puts("Clock process started"); + + (void)signal(SIGTERM, signal_handler); + (void)signal(SIGINT, signal_handler); + + if (pledge("stdio", NULL) == -1) + { + perror("pledge"); + (void)close(clock_pipe[0]); + (void)close(clock_pipe[1]); + + _exit(1); + } + + normalize_clock_interval(&interval); + + while (!should_quit) + { + get_clock(clock_string); + (void)dprintf(clock_pipe[1], "%s", clock_string); + + (void)nanosleep(&interval, NULL); + interval.tv_sec = 60; + interval.tv_nsec = 0; + + if (getppid() == 1) break; + } + (void)puts("Closing clock process"); + (void)close(clock_pipe[1]); + + _exit(0); +} + blob - c4e10c11c7a8f1e72c93899d6d35f3f2464ead8a blob + 1c476b749e34fa40cc14b6ce98c928709ddd30dc --- src/main.c +++ src/main.c @@ -8,20 +8,13 @@ #include #include #include -#include #include #include #include "statbar.h" -#define NFDS 5 +#define NFDS 6 -enum clocks_e -{ - CLOCK_CLOCK, - CLOCKS_COUNT -}; - static volatile sig_atomic_t should_quit = 0; static int reload_mail = 0; static int reload_battery = 0; @@ -63,33 +56,31 @@ main(void) { bool dirty = true; int output_fd; + int clock_fd; int batt_fd; int vol_fd; int timer_fd; int timerval_fd; int network_fd; + pid_t clock_pid; pid_t batt_pid; pid_t vol_pid; pid_t timer_pid; pid_t network_pid; unsigned char cmd; bool network_open = false; - struct timespec now; - struct timespec clocks[CLOCKS_COUNT]; - struct timespec *next_event; - struct timespec next_interval; - struct timespec clock_interval = { .tv_sec = 60 }; - struct timespec battery_interval = { .tv_sec = 10 }; struct pollfd pfd[NFDS]; struct pollfd *cmd_pfd = &pfd[0]; - struct pollfd *batt_pfd = &pfd[1]; - struct pollfd *vol_pfd = &pfd[2]; - 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]; + struct pollfd *clock_pfd = &pfd[1]; + struct pollfd *batt_pfd = &pfd[2]; + struct pollfd *vol_pfd = &pfd[3]; + struct pollfd *timer_pfd = &pfd[4]; + struct pollfd *network_pfd = &pfd[5]; + char clock_string[CLOCK_STRING_SIZE + 1]; + char battery_string[BATTERY_STRING_SIZE + 1]; + char volume_string[VOLUME_STRING_SIZE + 1]; + char timer_string[TIMER_STRING_SIZE + 1]; + char network_string[NETWORK_STRING_SIZE + 1]; int i; ssize_t n; @@ -107,24 +98,27 @@ main(void) /* Init components */ (void)puts("Reading config..."); read_config(); - (void)clock_gettime(CLOCK_BOOTTIME, &now); - normalize_clock_interval(&now, &clocks[CLOCK_CLOCK]); timerval_fd = open_timer(); - if (timer_fd == -1) + if (timerval_fd == -1) { (void)puts("Failed to open timer FIFO"); return -1; } - get_clock(); - batt_pid = start_privileged_battery_process(&batt_fd, &battery_interval); + clock_pid = start_clock_process(&clock_fd); + batt_pid = start_privileged_battery_process(&batt_fd); 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(); cmd_pfd->events = POLLIN; + if (clock_pid > 0) + { + clock_pfd->fd = clock_fd; + clock_pfd->events = POLLIN; + } if (batt_pid > 0) { batt_pfd->fd = batt_fd; @@ -155,32 +149,8 @@ main(void) } while (!should_quit) { - (void)clock_gettime(CLOCK_BOOTTIME, &now); - next_event = NULL; - for (i = 0; i < CLOCKS_COUNT; i++) + if (poll(pfd, NFDS, INFTIM) > 0) { - if (next_event == NULL) - { - next_event = &clocks[i]; - } - else - { - if (timespeccmp(next_event, &clocks[i], >)) - next_event = &clocks[i]; - } - } - if (timespeccmp(&now, next_event, >=)) - { - next_interval.tv_sec = 0; - next_interval.tv_nsec = 0; - } - else - { - timespecsub(next_event, &now, &next_interval); - } - - if (ppoll(pfd, NFDS, &next_interval, NULL) > 0) - { if (cmd_pfd->revents & POLLIN) { (void)read(cmd_pfd->fd, &cmd, 1); @@ -197,6 +167,11 @@ main(void) break; } } + if (clock_pfd->revents & POLLIN) + { + n = read(clock_pfd->fd, clock_string, CLOCK_STRING_SIZE); + if (n > 0) clock_string[n] = '\0'; + } if (batt_pfd->revents & POLLIN) { n = read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE); @@ -220,7 +195,6 @@ main(void) dirty = true; } - (void)clock_gettime(CLOCK_BOOTTIME, &now); /* Mail */ if (reload_mail) @@ -230,16 +204,6 @@ main(void) dirty = true; } - /* Clock */ - if (timespeccmp(&now, &clocks[CLOCK_CLOCK], >=)) - { - get_clock(); - dirty = true; - while (timespeccmp(&now, &clocks[CLOCK_CLOCK], >=)) - timespecadd(&clocks[CLOCK_CLOCK], &clock_interval, &clocks[CLOCK_CLOCK]); - } - - /* Battery */ if (reload_battery) { reload_battery = 0; @@ -261,6 +225,7 @@ main(void) cleanup: (void)puts("Closing statbar"); + if (clock_pid > 0) (void)kill(clock_pid, SIGTERM); 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);