#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const char errmsg[] = ERRMSG;
static const int errlen = sizeof(ERRMSG) - 1;
-char *argv0;
+char *argv0 = NULL;
+int running = 1;
/* TODO: Convert slot list to slot array. */
typedef struct Slot Slot;
void
slots_log(Slot *head)
{
- for (Slot *s = head; s; s = s->next) {
+ Slot *s = head;
+
+ for (; s; s = s->next) {
slot_log(s);
}
}
);
}
+void
+slot_close(Slot *s)
+{
+ close(s->in_fd);
+ s->in_fd = -1;
+ s->out_pos_cur = s->out_pos_lo;
+}
+
+void
+slots_close(Slot *s)
+{
+ for (; s; s = s->next)
+ if (s->in_fd > -1)
+ slot_close(s);
+}
+
+
void
slot_expire(Slot *s, struct timespec t, char *buf)
{
switch (errno) {
case EINTR:
khlib_error(
- "pselect temp failure: %d, errno: %d, msg: %s\n",
+ "pselect interrupted: %d, errno: %d, msg: %s\n",
ready,
errno,
strerror(errno)
case END_OF_MESSAGE:
case END_OF_FILE:
case FAILURE:
- close(s->in_fd);
- s->in_fd = -1;
+ slot_close(s);
s->in_last_read = t;
- s->out_pos_cur = s->out_pos_lo;
ready--;
break;
case RETRY:
tc; /* time interval correction (ti - td) when td < ti */
ti = khlib_timespec_of_float(cfg->interval);
- for (;;) {
+ while (running) {
clock_gettime(CLOCK_MONOTONIC, &t0); // FIXME: check errors
slots_read(cfg, &ti, buf);
if (cfg->to_x_root) {
}
}
+void
+terminate(int s)
+{
+ khlib_debug("terminating due to signal %d\n", s);
+ running = 0;
+}
+
int
main(int argc, char *argv[])
{
+ argv0 = argv[0];
+
Config cfg = {
.interval = 1.0,
.separator = "|",
};
char *buf;
Display *d = NULL;
+ struct sigaction sa;
- /* TODO: Handle signals */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = terminate;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT , &sa, NULL);
- argv0 = argv[0];
opts_parse(&cfg, argc, argv);
slots_assert_fifos_exist(cfg.slots);
config_stretch_for_separators(&cfg);
if (cfg.to_x_root && !(d = XOpenDisplay(NULL)))
khlib_fatal("XOpenDisplay failed with: %p\n", d);
loop(&cfg, buf, d);
+ slots_close(cfg.slots);
return EXIT_SUCCESS;
}