Commit Diff


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 <stdlib.h>
 #include <time.h>
 
+#include <signal.h>
+
 #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(&current_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 <signal.h>
 #include <unistd.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 
 #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);