Commit Diff


commit - 62f057dfcf4a2127b30a288a78ecb29b1dc37348
commit + 7e9b1d575ff8c792714fe787010a2296996eee72
blob - d88a1e429c79a4fe86b55d0d4e52d4e20b54f6c6
blob + b6f1aeaeda3d21bdc8104572062cac0b7a3e339e
--- include/statbar.h
+++ include/statbar.h
@@ -40,12 +40,12 @@ extern void get_clock(void);
 extern void normalize_clock_interval(const struct timespec *now, struct timespec *next);
 
 /* Battery */
-#define BATTERY_STRING_SIZE 11
+#define BATTERY_STRING_SIZE 12
 
 extern pid_t start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout);
 
 /* Volume */
-#define VOLUME_STRING_SIZE 11
+#define VOLUME_STRING_SIZE 12
 
 extern pid_t start_volume_process(int *pipe_fd);
 
@@ -75,11 +75,9 @@ extern char **get_mail_path_ptr(void);
 extern void close_mail(void);
 
 /* Network */
-extern char network_string[7];
+#define NETWORK_STRING_SIZE 8
 
-extern bool init_network_socket(int *fd);
-extern void read_network_socket(int fd);
-extern void get_initial_network_state(void);
+extern pid_t start_network_process(int *pipe_fd);
 extern void set_ethernet_device(char *dev);
 extern void set_wifi_device(char *dev);
 
blob - 47f48c0341b8a3537dcb70b7d7ecdb6f19aa1e78
blob + e81a31be52e29a82f5fe351842f44f68c8b825e0
--- modules/network.c
+++ modules/network.c
@@ -1,7 +1,9 @@
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include <fcntl.h>
 #include <unistd.h>
 #include <net/if.h>
 #include <net/route.h>
@@ -10,59 +12,29 @@
 
 #include "statbar.h"
 
-char network_string[7];
-
 static int ethernet_device;
 static int wifi_device;
+static volatile sig_atomic_t should_quit = 0;
 
-bool
-init_network_socket(int *fd)
+static int
+init_network_socket(void)
 {
-	*fd = socket(AF_ROUTE, SOCK_RAW, 0);
-	if (*fd < 0)
+	int fd;
+
+	fd = socket(AF_ROUTE, SOCK_RAW, 0);
+	if (fd < 0)
 	{
 		perror("socket");
 
-		return false;
+		return -1;
 	}
 
-	return true;
+	return fd;
 }
 
-void
-read_network_socket(int fd)
+static void
+get_current_network_state(int pipe_fd)
 {
-	char buf[1024];
-	struct rt_msghdr *rtm;
-	struct if_msghdr *ifm;
-	ssize_t n;
-
-	n = read(fd, buf, sizeof(buf));
-	if (n < 0)
-	{
-		perror("read");
-
-		return;
-	}
-
-	rtm = (struct rt_msghdr *)buf;
-	if (rtm->rtm_type != RTM_IFINFO) return;
-
-	ifm = (struct if_msghdr *)buf;
-	if (ifm->ifm_index != wifi_device && ifm->ifm_index != ethernet_device) return;
-	if (!LINK_STATE_IS_UP(ifm->ifm_data.ifi_link_state))
-	{
-		network_string[0] = '\0';
-
-		return;
-	}
-	if (ifm->ifm_index == ethernet_device) (void)snprintf(network_string, 7, "%s  ", ETHERNET);
-	else if (ifm->ifm_index == wifi_device) (void)snprintf(network_string, 7, "%s  ", WIFI);
-}
-
-void
-get_initial_network_state(void)
-{
 	int mib[6];
 	char *buf;
 	char *next;
@@ -70,6 +42,7 @@ get_initial_network_state(void)
 	size_t len;
 	struct rt_msghdr *rtm;
 	struct if_msghdr *ifm;
+	char network_string[NETWORK_STRING_SIZE];
 
 	mib[0] = CTL_NET;
 	mib[1] = AF_ROUTE;
@@ -113,13 +86,109 @@ get_initial_network_state(void)
 
 			continue;
 		}
-		if (ifm->ifm_index == wifi_device) (void)snprintf(network_string, 7, "%s  ", WIFI);
-		if (ifm->ifm_index == ethernet_device) (void)snprintf(network_string, 7, "%s  ", ETHERNET);
+		if (ifm->ifm_index == wifi_device) (void)snprintf(network_string, NETWORK_STRING_SIZE, "%s  ", WIFI);
+		if (ifm->ifm_index == ethernet_device) (void)snprintf(network_string, NETWORK_STRING_SIZE, "%s  ", ETHERNET);
 	}
 
+	(void)write(pipe_fd, network_string, NETWORK_STRING_SIZE);
 	free(buf);
 }
 
+static void
+signal_handler(int sig)
+{
+	if (sig == SIGTERM || sig == SIGINT) should_quit = 1;
+}
+
+pid_t
+start_network_process(int *pipe_fd)
+{
+	pid_t pid;
+	int network_pipe[2];
+	int sock_fd;
+	struct pollfd pfd;
+	char buf[1024];
+	int flags;
+	ssize_t n;
+
+	if (pipe(network_pipe) == -1)
+	{
+		perror("pipe");
+
+		return -1;
+	}
+	*pipe_fd = network_pipe[0];
+
+	pid = fork();
+	if (pid)
+	{
+		if (pid == -1) (void)close(network_pipe[0]);
+		(void)close(network_pipe[1]);
+
+		return pid;
+	}
+
+	sock_fd = init_network_socket();
+	if (sock_fd == -1) _exit(-1);
+	flags = fcntl(sock_fd, F_GETFL, 0);
+	(void)fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
+	pfd.fd = sock_fd;
+	pfd.events = POLLIN;
+	(void)close(pipe_fd[0]);
+	setproctitle("network");
+	(void)puts("Network process started");
+
+	(void)signal(SIGTERM, signal_handler);
+	(void)signal(SIGINT, signal_handler);
+
+	if (pledge("stdio inet", NULL) == -1)
+	{
+		perror("pledge");
+		(void)close(network_pipe[0]);
+		(void)close(network_pipe[1]);
+
+		_exit(1);
+	}
+
+	get_current_network_state(network_pipe[1]);
+	while(!should_quit)
+	{
+		if (poll(&pfd, 1, INFTIM) > 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;
+				}
+			}
+			get_current_network_state(network_pipe[1]);
+		}
+
+		if (getppid() == 1) break;
+	}
+
+	(void)puts("Closing network process");
+	(void)close(network_pipe[1]);
+	(void)close(sock_fd);
+
+	_exit(0);
+}
+
 void set_ethernet_device(char *dev)
 {
 	ethernet_device = if_nametoindex(dev);
blob - a6bd194520be7e434b6dca53811a82eeb66dec09
blob + a98021bcb54aa680ac2e4b89486250ddd8da7bf6
--- src/main.c
+++ src/main.c
@@ -78,9 +78,11 @@ main(void)
 	bool dirty = true;
 	int batt_fd;
 	int vol_fd;
+	int network_fd;
 	int weather_pipe[2];
 	pid_t batt_pid;
 	pid_t vol_pid;
+	pid_t network_pid;
 	unsigned char cmd;
 	bool network_open = false;
 	struct timespec now;
@@ -100,6 +102,7 @@ main(void)
 	struct pollfd *weather_pfd = &pfd[4];
 	char battery_string[BATTERY_STRING_SIZE];
 	char volume_string[VOLUME_STRING_SIZE];
+	char network_string[NETWORK_STRING_SIZE];
 	int i;
 	ssize_t n;
 
@@ -121,9 +124,9 @@ main(void)
 	get_clock();
 	batt_pid = start_privileged_battery_process(&batt_fd, &battery_interval);
 	vol_pid = start_volume_process(&vol_fd);
+	network_pid = start_network_process(&network_fd);
 	get_cputemp();
 	get_fanspeed();
-	get_initial_network_state();
 
 	if (pipe(weather_pipe) != 0)
 	{
@@ -143,6 +146,11 @@ main(void)
 		vol_pfd->fd = vol_fd;
 		vol_pfd->events = POLLIN;
 	}
+	if (network_pid > 0)
+	{
+		network_pfd->fd = network_fd;
+		network_pfd->events = POLLIN;
+	}
 	if (weather_loc_valid)
 	{
 		weather_pfd->fd = weather_pipe[0];
@@ -160,7 +168,7 @@ main(void)
 	}
 	root = DefaultRootWindow(display);
 
-	if (pledge("stdio rpath cpath inet proc exec route", NULL) == -1)
+	if (pledge("stdio rpath cpath proc exec", NULL) == -1)
 	{
 		perror("pledge");
 
@@ -228,16 +236,19 @@ main(void)
 			}
 			if (batt_pfd->revents & POLLIN)
 			{
-				n = read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE - 1);
+				n = read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE);
 				if (n > 0) battery_string[n] = '\0';
 			}
 			if (vol_pfd->revents & POLLIN)
 			{
-				n = read(vol_pfd->fd, volume_string, VOLUME_STRING_SIZE - 1);
+				n = read(vol_pfd->fd, volume_string, VOLUME_STRING_SIZE);
 				if (n > 0) volume_string[n] = '\0';
 			}
 			if (network_pfd->revents & POLLIN)
-				read_network_socket(network_pfd->fd);
+			{
+				n = read(network_pfd->fd, network_string, NETWORK_STRING_SIZE);
+				if (n > 0) network_string[n] = '\0';
+			}
 			if (weather_pfd && (weather_pfd->revents & POLLIN))
 				read_weather(weather_pfd->fd);
 
@@ -317,7 +328,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 (network_open) (void)close(network_pfd->fd);
+	if (network_pid > 0) (void)kill(network_pid, SIGTERM);
 	if (weather_loc_valid) close_weather();
 	if (mail_path_valid) close_mail(); 
 	(void)XCloseDisplay(display);