X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=x5%2Fkhatus.c;h=3897b870bf65b1a6fa2f4cfa480503c2938b30f5;hb=fabb877142fbe4686ef7fcaf7fa0f4f92c1fe254;hp=a41351a9b72842d7c9376216cf3c989441b962c3;hpb=77c76070aa1cdd9f38b6b1c338854c83abae21ff;p=khatus.git diff --git a/x5/khatus.c b/x5/khatus.c index a41351a..3897b87 100644 --- a/x5/khatus.c +++ b/x5/khatus.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include @@ -17,6 +19,7 @@ char *argv0; +/* TODO: Convert file list to file array. */ typedef struct File File; struct File { char *name; @@ -35,12 +38,14 @@ struct Config { File * files; int file_count; int total_width; + int output_to_x_root_window; } defaults = { .interval = 1, .separator = "|", .files = NULL, .file_count = 0, .total_width = 0, + .output_to_x_root_window = 0, }; void @@ -169,6 +174,11 @@ parse_opts_opt(Config *cfg, int argc, char *argv[], int i) switch (argv[i][1]) { case 'i': parse_opts_opt_i(cfg, argc, argv, ++i); break; /* TODO: Generic set_int */ case 's': parse_opts_opt_s(cfg, argc, argv, ++i); break; /* TODO: Generic set_str */ + case 'x': { + cfg->output_to_x_root_window = 1; + opts_parse_any(cfg, argc, argv, ++i); + break; + } default : usage("Option \"%s\" is invalid\n", argv[i]); } } @@ -235,27 +245,21 @@ opts_parse(Config *cfg, int argc, char *argv[], int i) void read_one(File *f, char *buf) { - ssize_t n; + ssize_t current; + ssize_t total; char *b; + char c; + current = 0; + total = 0; + c = '\0'; b = buf + f->pos; memset(b, ' ', f->width); - while ((n = read(f->fd, b, f->width)) > 0) { - b += n; - debug("read %zd from %s\n", n, f->name); - } - - if (n > -1) { - if (*(b - 1) == '\n') - *(b - 1) = ' '; - } else { - error( - "Failed to read: \"%s\". Error: %s\n", - f->name, - strerror(errno) - ); - } - + while ((current = read(f->fd, &c, 1)) && c != '\n' && c != '\0' && total++ < f->width) + *b++ = c; + if (current == -1) + error("Failed to read: \"%s\". Error: %s\n", f->name, strerror(errno)); + /* TODO Record timestamp read */ close(f->fd); f->fd = -1; } @@ -266,11 +270,16 @@ read_all(Config *cfg, char *buf) fd_set fds; int maxfd; int ready; + struct stat st; FD_ZERO(&fds); - - /* TODO: stat then check TTL */ + /* TODO: Check TTL */ for (File *f = cfg->files; f; f = f->next) { + /* TODO: Create the FIFO if it doesn't already exist. */ + if (lstat(f->name, &st) < 0) + fatal("Cannot stat \"%s\". Error: %s\n", f->name, strerror(errno)); + if (!(st.st_mode & S_IFIFO)) + fatal("\"%s\" is not a FIFO\n", f->name); debug("opening: %s\n", f->name); if (f->fd < 0) f->fd = open(f->name, O_RDONLY | O_NONBLOCK); @@ -304,6 +313,7 @@ main(int argc, char *argv[]) int prefix = 0; char *buf; Config *cfg = &defaults; + Display *display; argv0 = argv[0]; @@ -336,10 +346,23 @@ main(int argc, char *argv[]) } } - printf("%s\n", buf); + if (cfg->output_to_x_root_window && !(display = XOpenDisplay(NULL))) + fatal("XOpenDisplay failed with: %p\n", display); /* TODO: nanosleep and nano time diff */ for (;;) { + /* TODO: Check TTL and maybe blank-out */ + /* TODO: How to trigger TTL check? On select? Alarm signal? */ + /* TODO: Set timeout on read_all based on diff of last time of + * read_all and desired time of next TTL check. + * */ read_all(cfg, buf); - printf("%s\n", buf); + if (cfg->output_to_x_root_window) { + if (XStoreName(display, DefaultRootWindow(display), buf) < 0) + fatal("XStoreName failed.\n"); + XFlush(display); + } else { + puts(buf); + fflush(stdout); + } } }