Commit Diff


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 <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <sys/_time.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#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 <time>: count down from <time> in the status bar"
+}
+
+if [ ! -p "$STATBARTIMER" ]; then
+	echo "Could not open statbar timer" > /dev/stderr
+	exit 1;
+fi
+
+if [ -z "$1" ]; then
+	show_help;
+	exit 0;
+fi
+
+echo "$1" > "$STATBARTIMER"
+