commit - 8321fa19c97a5f78ceca7ea866ca8dc18696d6ba
commit + 6a40413bfd582f7ef59dbe0a6926d7f4b5d8bf8c
blob - 2efe892c418eaadf452b8ae10c5e71e59cdd871a
blob + 29ccceaafc5b3c6e989b5075ad1ed8015cf05366
--- include/statbar.h
+++ include/statbar.h
extern void normalize_clock_interval(const struct timespec *now, struct timespec *next);
/* Battery */
-extern char battery_string[11];
+#define BATTERY_STRING_SIZE 11
-extern bool init_battery(void);
-extern void get_battery(void);
-extern void close_battery(void);
+extern pid_t start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout);
/* Volume */
extern char volume_string[11];
blob - b67ebc6adadd240baca6ee127b49b5549a39fba0
blob + 2d222454e2b6914d85b9ab08f55cfc0504a9c30c
--- modules/battery.c
+++ modules/battery.c
#include <string.h>
#include <fcntl.h>
+#include <signal.h>
#include <unistd.h>
#include <machine/apmvar.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
#include "statbar.h"
-char battery_string[11];
-
static int fd;
+static volatile sig_atomic_t should_quit = 0;
-bool
+int
init_battery(void)
{
fd = open("/dev/apm", O_RDONLY);
if (fd < 0)
{
- perror("battery: open");
- (void)strcpy(battery_string, UNKNOWN);
+ perror("open");
- return false;
+ return -1;
}
- get_battery();
- return true;
+ return 0;
}
-void
-get_battery()
+static void
+get_battery(int pipe_fd)
{
struct apm_power_info pinfo;
char pstate[5];
if (ioctl(fd, APM_IOC_GETPOWER, &pinfo) < 0)
{
- perror("battery: ioctl");
- (void)strcpy(battery_string, UNKNOWN);
+ perror("ioctl");
return;
}
else
(void)strcpy(pstate, BATT);
- (void)snprintf(battery_string, 11, "%s %3d%%", pstate, pinfo.battery_life);
+ (void)dprintf(pipe_fd, "%s %3d%%", pstate, pinfo.battery_life);
}
-void
-close_battery(void)
+static void
+signal_handler(int sig)
{
- (void)close(fd);
+ if (sig == SIGTERM || sig == SIGINT) should_quit = 1;
}
+pid_t
+start_privileged_battery_process(int *pipe_fd, const struct timespec *timeout)
+{
+ pid_t pid;
+ int batt_pipe[2];
+
+ if (pipe(batt_pipe) == -1)
+ {
+ perror("pipe");
+
+ return -1;
+ }
+ *pipe_fd = batt_pipe[0];
+
+ pid = fork();
+ if (pid) return pid;
+
+ if (init_battery() == -1) _exit(-1);
+
+ (void)signal(SIGTERM, signal_handler);
+ (void)signal(SIGINT, signal_handler);
+ (void)signal(SIGUSR1, signal_handler);
+
+ while(!should_quit)
+ {
+ get_battery(batt_pipe[1]);
+ (void)nanosleep(timeout, NULL);
+
+ if (getppid() == 1) break;
+ }
+ (void)puts("Closing battery pipe");
+ (void)close(batt_pipe[1]);
+ (void)close(batt_pipe[0]);
+
+ _exit(0);
+}
+
blob - 0b5d6618af30297297b0ea8774a6eb67d6f2a2f5
blob + 90a5b407848bd07d74b11f3250c4f6e348a62783
--- src/main.c
+++ src/main.c
enum clocks_e
{
CLOCK_CLOCK,
- BATTERY_CLOCK,
CPUTEMP_CLOCK,
FANSPEED_CLOCK,
WEATHER_CLOCK,
int
main(int argc, char *argv[])
{
- Display *display = XOpenDisplay(NULL);
+ Display *display;
Window root;
char statbar_text[MAX_STATBAR_LEN];
bool dirty = true;
+ int batt_fd;
+ pid_t batt_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 apm_open = false;
bool hdl_open = false;
bool network_open = false;
struct timespec now;
struct timespec fanspeed_interval = { .tv_sec = 3 };
struct timespec weather_interval = { .tv_sec = 1800 };
struct pollfd *pfd;
+ char battery_string[BATTERY_STRING_SIZE];
int nfds = 2; /* Start with 2 to guarantee space for the network socket and cmd interface */
int i;
(void)setvbuf(stdout, NULL, _IOLBF, 0);
+ display = XOpenDisplay(NULL);
if (display == NULL)
{
(void)puts("Failed to get display");
read_config(&clock_interval, &battery_interval, &cputemp_interval, &fanspeed_interval);
(void)clock_gettime(CLOCK_BOOTTIME, &now);
normalize_clock_interval(&now, &clocks[CLOCK_CLOCK]);
- timespecadd(&now, &battery_interval, &clocks[BATTERY_CLOCK]);
timespecadd(&now, &cputemp_interval, &clocks[CPUTEMP_CLOCK]);
timespecadd(&now, &fanspeed_interval, &clocks[FANSPEED_CLOCK]);
timespecadd(&now, &weather_interval, &clocks[WEATHER_CLOCK]);
}
get_clock();
- apm_open = init_battery();
+ batt_pid = start_privileged_battery_process(&batt_fd, &battery_interval);
hdl_open = init_volume(&nfds);
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)
{
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);
- weather_pfd->events = POLLIN;
+ if (pledge("stdio rpath cpath inet proc exec route audio", NULL) == -1)
+ {
+ perror("pledge");
+
+ goto cleanup;
+ }
while (!should_quit)
{
if (reload_config)
break;
}
}
+ if (batt_pfd->revents & POLLIN)
+ (void)read(batt_pfd->fd, battery_string, BATTERY_STRING_SIZE);
if (network_pfd->revents & POLLIN)
read_network_socket(network_pfd->fd);
if (weather_pfd && (weather_pfd->revents & POLLIN))
}
/* Battery */
- if (reload_battery || (apm_open && timespeccmp(&now, &clocks[BATTERY_CLOCK], >=)))
+ if (reload_battery)
{
reload_battery = 0;
- get_battery();
- dirty = true;
- while (timespeccmp(&now, &clocks[BATTERY_CLOCK], >=))
- timespecadd(&clocks[BATTERY_CLOCK], &battery_interval, &clocks[BATTERY_CLOCK]);
+ (void)kill(batt_pid, SIGUSR1);
}
/* CPU Temp */
cleanup:
(void)puts("Closing statbar");
- if (apm_open) close_battery();
+ if (batt_pid > 0) (void)kill(batt_pid, SIGTERM);
if (hdl_open) close_volume();
if (network_open) (void)close(network_pfd->fd);
if (weather_loc_valid) close_weather();