commit - 23a90cf95d6b733db64c1c4adb136018997a8fd1
commit + c9b5e794e4a1455fe3ead85670b45c65e72fe873
blob - 29ccceaafc5b3c6e989b5075ad1ed8015cf05366
blob + d88a1e429c79a4fe86b55d0d4e52d4e20b54f6c6
--- include/statbar.h
+++ include/statbar.h
#include <stdio.h>
#include <poll.h>
+#include <unistd.h>
/* Glyphs */
#define MAIL "\ueb1c"
#define WIFI "\uf1eb"
#define ETHERNET "\uef09"
+extern void close_display(void);
+
/* FS */
extern bool weather_loc_valid;
extern bool mail_path_valid;
extern pid_t start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout);
/* Volume */
-extern char volume_string[11];
+#define VOLUME_STRING_SIZE 11
-extern bool init_volume(int *nfds);
-extern void fill_sndio_pfds(struct pollfd *pfd);
-extern void process_volume_events(struct pollfd *pfd, bool *hdl_open);
-extern void close_volume(void);
+extern pid_t start_volume_process(int *pipe_fd);
/* CPU Temp */
extern char cputemp_string[14];
blob - 79d1a8a4d4213e3eceb6f2590ccf1ff3f90901df
blob + 4f7843bb78a4141565fd3bba8b1d66807067d887
--- modules/volume.c
+++ modules/volume.c
+#include <signal.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <poll.h>
+#include <sys/poll.h>
+#include <unistd.h>
#include <sndio.h>
#include "statbar.h"
-char volume_string[11];
-
static struct sioctl_hdl *hdl;
+static volatile sig_atomic_t should_quit = 0;
+static unsigned int ctl_addr = -1;
-void
+static void
onval(void *arg, unsigned int addr, unsigned int val)
{
- char vglyph[5];
+ char *vglyph;
- (void)arg;
- (void)addr;
+ if (ctl_addr != addr) return;
if (val == 0)
- (void)strcpy(vglyph, VOLMUTE);
+ vglyph = VOLMUTE;
else if (val < 128)
- (void)strcpy(vglyph, VOLLOW);
+ vglyph = VOLLOW;
else
- (void)strcpy(vglyph, VOL);
+ vglyph = VOL;
- (void)snprintf(volume_string, 11, "%s %3d%%", vglyph, val * 100 / 255);
+ (void)dprintf(*(int *)arg, "%s %3d%%", vglyph, val * 100 / 255);
}
-void
+static void
ondesc(void *arg, struct sioctl_desc *desc, int val)
{
- static bool did_init = false;
- char vglyph[5];
+ char *vglyph;
- (void)arg;
-
if (val == 0)
- (void)strcpy(vglyph, VOLMUTE);
+ vglyph = VOLMUTE;
else if (val < 128)
- (void)strcpy(vglyph, VOLLOW);
+ vglyph = VOLLOW;
else
- (void)strcpy(vglyph, VOL);
+ vglyph = VOL;
- if (!did_init && desc != NULL && strcmp(desc->func, "level") == 0)
+ if (ctl_addr == -1 &&
+ desc != NULL &&
+ strcmp(desc->func, "level") == 0 &&
+ strcmp(desc->node0.name, "output") == 0)
{
- (void)snprintf(volume_string, 11, "%s %3d%%", vglyph, val * 100 / 255);
- did_init = true;
+ (void)dprintf(*(int *)arg, "%s %3d%%", vglyph, val * 100 / 255);
+ ctl_addr = desc->addr;
}
}
-bool
-init_volume(int *nfds)
+static int
+init_volume(int *nfds, void *fd)
{
hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0);
if (hdl == NULL)
{
(void)puts("Could not open sndio");
- (void)strcpy(volume_string, UNKNOWN);
- return false;
+ return -1;
}
- *nfds += sioctl_nfds(hdl);
- (void)sioctl_ondesc(hdl, ondesc, NULL);
- (void)sioctl_onval(hdl, onval, NULL);
+ *nfds = sioctl_nfds(hdl);
+ (void)sioctl_ondesc(hdl, ondesc, fd);
+ (void)sioctl_onval(hdl, onval, fd);
return true;
}
-void
-fill_sndio_pfds(struct pollfd *pfd)
+static void
+signal_handler(int sig)
{
- sioctl_pollfd(hdl, pfd, POLLIN);
+ if (sig == SIGTERM || sig == SIGINT) should_quit = 1;
}
-void
-process_volume_events(struct pollfd *pfd, bool *hdl_open)
+pid_t
+start_volume_process(int *pipe_fd)
{
+ pid_t pid;
+ int vol_pipe[2];
+ int nfds;
+ struct pollfd *pfd;
+
+ if (pipe(vol_pipe) == -1)
+ {
+ perror("pipe");
+
+ return -1;
+ }
+ *pipe_fd = vol_pipe[0];
+
+ pid = fork();
+ if (pid)
+ {
+ if (pid == -1) (void)close(vol_pipe[0]);
+ (void)close(vol_pipe[1]);
+
+ return pid;
+ }
+
+ if (pledge("stdio inet unix rpath", NULL) == -1)
+ {
+ perror("pledge");
+ (void)close(vol_pipe[0]);
+ (void)close(vol_pipe[1]);
+
+ _exit(1);
+ }
+ if (init_volume(&nfds, &vol_pipe[1]) == -1) _exit(1);
+ (void)close(vol_pipe[0]);
+ (void)puts("Volume process started");
+
+ (void)signal(SIGTERM, signal_handler);
+ (void)signal(SIGINT, signal_handler);
+
+ pfd = malloc(nfds * sizeof(struct pollfd));
+ if (pfd == NULL)
+ {
+ perror("malloc");
+
+ _exit(1);
+ }
+ (void)sioctl_pollfd(hdl, pfd, POLLIN);
+
+ if (pledge("stdio", NULL) == -1)
+ {
+ perror("pledge");
+ free(pfd);
+ (void)close(vol_pipe[1]);
+
+ _exit(1);
+ }
+ while(!should_quit)
+ {
+ if (poll(pfd, nfds, INFTIM) > 0)
+ {
if (sioctl_revents(hdl, pfd) & POLLHUP)
{
(void)puts("Lost connection to sndio\n");
- sioctl_close(hdl);
- *hdl_open = false;
+
+ break;
}
-}
+ }
-void
-close_volume(void)
-{
- sioctl_close(hdl);
+ if (getppid() == 1) break;
+ }
+ (void)puts("Closing volume process");
+ (void)sioctl_close(hdl);
+ free(pfd);
+ (void)close(vol_pipe[1]);
+
+ _exit(0);
}
blob - 780d00cd6185f0ea59de3b2b64c6eb90502fe37a
blob + bb91908b4fbb21965cc9bcb2462655c446c8c6e0
--- src/main.c
+++ src/main.c
#include <errno.h>
#include <stdbool.h>
-#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include "statbar.h"
#define MAX_STATBAR_LEN 128
+#define NFDS 5
enum clocks_e
{
char statbar_text[MAX_STATBAR_LEN];
bool dirty = true;
int batt_fd;
+ int vol_fd;
int weather_pipe[2];
pid_t batt_pid;
+ pid_t vol_pid;
unsigned char cmd;
- struct pollfd *cmd_pfd = NULL;
- struct pollfd *batt_pfd = NULL;
- struct pollfd *network_pfd = NULL;
- struct pollfd *weather_pfd = NULL;
- bool hdl_open = false;
bool network_open = false;
struct timespec now;
struct timespec clocks[CLOCKS_COUNT];
struct timespec cputemp_interval = { .tv_sec = 2 };
struct timespec fanspeed_interval = { .tv_sec = 3 };
struct timespec weather_interval = { .tv_sec = 1800 };
- struct pollfd *pfd;
+ struct pollfd pfd[NFDS];
+ 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 *weather_pfd = &pfd[4];
char battery_string[BATTERY_STRING_SIZE];
- int nfds = 2; /* Start with 2 to guarantee space for the network socket and cmd interface */
+ char volume_string[VOLUME_STRING_SIZE];
int i;
+ ssize_t n;
(void)setvbuf(stdout, NULL, _IOLBF, 0);
-
- display = XOpenDisplay(NULL);
- if (display == NULL)
- {
- (void)puts("Failed to get display");
-
- return 1;
- }
install_signal_handlers();
statbar_text[0] = '\0';
- root = DefaultRootWindow(display);
(void)puts("Welcome to statbar");
/* Init components */
timespecadd(&now, &cputemp_interval, &clocks[CPUTEMP_CLOCK]);
timespecadd(&now, &fanspeed_interval, &clocks[FANSPEED_CLOCK]);
timespecadd(&now, &weather_interval, &clocks[WEATHER_CLOCK]);
- if (pipe(weather_pipe) != 0)
- {
- perror("pipe");
- weather_loc_valid = false;
- }
get_clock();
batt_pid = start_privileged_battery_process(&batt_fd, &battery_interval);
- hdl_open = init_volume(&nfds);
+ vol_pid = start_volume_process(&vol_fd);
get_cputemp();
get_fanspeed();
get_initial_network_state();
- if (weather_loc_valid) nfds++;
- if (batt_pid > 0) nfds++;
- pfd = malloc(nfds * sizeof(struct pollfd));
- if (pfd == NULL)
+ if (pipe(weather_pipe) != 0)
{
- perror("malloc");
- goto cleanup;
+ perror("pipe");
+ weather_loc_valid = false;
}
- cmd_pfd = &pfd[nfds - 1];
+
cmd_pfd->fd = open_command_interface();
cmd_pfd->events = POLLIN;
- network_pfd = &pfd[nfds - 2];
- network_open = init_network_socket(&network_pfd->fd);
- network_pfd->events = POLLIN;
+ if (batt_pid > 0)
+ {
+ batt_pfd->fd = batt_fd;
+ batt_pfd->events = POLLIN;
+ }
+ if (vol_pid > 0)
+ {
+ vol_pfd->fd = vol_fd;
+ vol_pfd->events = POLLIN;
+ }
if (weather_loc_valid)
{
- weather_pfd = &pfd[nfds - 3];
weather_pfd->fd = weather_pipe[0];
weather_pfd->events = POLLIN;
get_weather(weather_pipe[1]);
}
- if (batt_pid > 0)
- {
- batt_pfd = &pfd[nfds - (weather_loc_valid ? 4 : 3)];
- batt_pfd->fd = batt_fd;
- batt_pfd->events = POLLIN;
- }
if (mail_path_valid) mail_path_valid = get_mail();
- fill_sndio_pfds(pfd);
- if (pledge("stdio rpath cpath inet proc exec route audio", NULL) == -1)
+ display = XOpenDisplay(NULL);
+ if (display == NULL)
{
+ (void)puts("Failed to get display");
+
+ return -1;
+ }
+ root = DefaultRootWindow(display);
+
+ if (pledge("stdio rpath cpath inet proc exec route", NULL) == -1)
+ {
perror("pledge");
goto cleanup;
timespecsub(next_event, &now, &next_interval);
}
- if (ppoll(pfd, nfds, &next_interval, NULL) > 0)
+ if (ppoll(pfd, NFDS, &next_interval, NULL) > 0)
{
- if (hdl_open)
- process_volume_events(pfd, &hdl_open);
if (cmd_pfd->revents & POLLIN)
{
(void)read(cmd_pfd->fd, &cmd, 1);
}
}
if (batt_pfd->revents & POLLIN)
- (void)read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE);
+ {
+ n = read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE - 1);
+ if (n > 0) battery_string[n] = '\0';
+ }
+ if (vol_pfd->revents & POLLIN)
+ {
+ n = read(vol_pfd->fd, volume_string, VOLUME_STRING_SIZE - 1);
+ if (n > 0) volume_string[n] = '\0';
+ }
if (network_pfd->revents & POLLIN)
read_network_socket(network_pfd->fd);
if (weather_pfd && (weather_pfd->revents & POLLIN))
if (dirty)
{
- (void)snprintf(statbar_text, MAX_STATBAR_LEN, "%s%s| %s | %s | %s | %s | %s | %s",
+ (void)snprintf(statbar_text, MAX_STATBAR_LEN - 1, "%s%s| %s | %s | %s | %s | %s | %s",
mail_string,
network_string,
weather_string,
volume_string,
battery_string,
clock_string);
- XStoreName(display, root, statbar_text);
- XFlush(display);
+ (void)XStoreName(display, root, statbar_text);
+ (void)XFlush(display);
dirty = false;
}
}
cleanup:
(void)puts("Closing statbar");
if (batt_pid > 0) (void)kill(batt_pid, SIGTERM);
- if (hdl_open) close_volume();
+ if (batt_pid > 0) (void)kill(vol_pid, SIGTERM);
if (network_open) (void)close(network_pfd->fd);
if (weather_loc_valid) close_weather();
if (mail_path_valid) close_mail();
(void)close(weather_pipe[1]);
}
close_command_interface();
- free(pfd);
return 0;
}