diff options
-rw-r--r-- | .config/wmii-hg/Makefile | 1 | ||||
-rw-r--r-- | .config/wmii-hg/rbar.h | 82 | ||||
-rw-r--r-- | .config/wmii-hg/rbar_clock.c | 15 |
3 files changed, 53 insertions, 45 deletions
diff --git a/.config/wmii-hg/Makefile b/.config/wmii-hg/Makefile index 85c1ab1..663653f 100644 --- a/.config/wmii-hg/Makefile +++ b/.config/wmii-hg/Makefile @@ -2,6 +2,7 @@ all: rbar_clock .PHONY: all CFLAGS += -std=c99 -Wall -Werror -Wextra +CFLAGS += -O2 -D_FORTIFY_SOURCE=2 rbar_clock: rbar.h diff --git a/.config/wmii-hg/rbar.h b/.config/wmii-hg/rbar.h index 843ac52..6500a76 100644 --- a/.config/wmii-hg/rbar.h +++ b/.config/wmii-hg/rbar.h @@ -5,12 +5,15 @@ #include <fcntl.h> /* O_* flags to open(3p) */ #include <glob.h> /* glob(3p), globfree(3p), GLOB_* */ #include <signal.h> /* sigaction(3p) */ +#include <stdbool.h> /* bool */ #include <stdio.h> /* dprintf(3p) */ #include <stdlib.h> /* exit(3p), malloc(3p) */ #include <string.h> /* strcmp(3p), strlen(3p), strcpy(3p) */ #include <sys/stat.h> /* open(3p) */ #include <unistd.h> /* unlink(3p) */ +char *rbar_globescape(const char *lit); + /* Main *************************************************************/ struct impl { @@ -37,10 +40,27 @@ void usage(int fd) { } void sigexit(int sig) { - error(0, 0, "Cought signal: %d", sig); + error(0, 0, "Caught signal: %d", sig); exit(0); } +char *xrd_glob; +size_t xrd_glob_len; + +void xrd_cleanup(void) { + free(xrd_glob); +} + +void xrd_setup(void) { + char *xrd = getenv("XDG_RUNTIME_DIR"); + if (xrd == NULL || xrd[0] == '\0') { + error(6, 0, "XDG_RUNTIME_DIR isn't set"); + } + xrd_glob = rbar_globescape(xrd); + xrd_glob_len = strlen(xrd_glob); + atexit(xrd_cleanup); +} + int main(int argc, char *argv[]) { if (argc != 2) { errusage("exactly 1 argument expected, got %d", argc-1); @@ -67,10 +87,7 @@ int main(int argc, char *argv[]) { case '4': fn = impl.scroll_up; break; case '5': fn = impl.scroll_down; break; } - char *xrd = getenv("XDG_RUNTIME_DIR"); - if (xrd == NULL || xrd[0] == '\0') { - error(6, 0, "XDG_RUNTIME_DIR isn't set"); - } + xrd_setup(); if (fn == NULL) { exit(0); } else { @@ -81,10 +98,7 @@ int main(int argc, char *argv[]) { if ('0' <= arg[0] && arg[0] <= '9' && '0' <= arg[1] && arg[1] <= '9' && arg[2] == '_') { - char *xrd = getenv("XDG_RUNTIME_DIR"); - if (xrd == NULL || xrd[0] == '\0') { - error(6, 0, "XDG_RUNTIME_DIR isn't set"); - } + xrd_setup(); if (impl.update == NULL) { exit(0); } else { @@ -130,26 +144,19 @@ char *rbar_globescape(const char *lit) { } /* returns 0 or GLOB_NOMATCH */ -int rbar_write(const char *filename, const char *msg) { - static const char *xrd = NULL; - static size_t xrdlen; - if (!xrd) { - xrd = rbar_globescape(getenv("XDG_RUNTIME_DIR")); - xrdlen = strlen(xrd); - } - - char *fullglob = alloca(xrdlen+(sizeof RBAR_DIRGLOB)); - strcpy(fullglob, xrd); - strcpy(&fullglob[xrdlen], RBAR_DIRGLOB); +bool rbar_write(const char *filename, const char *msg) { + char *fullglob = alloca(xrd_glob_len+(sizeof RBAR_DIRGLOB)); + strcpy(fullglob, xrd_glob); + strcpy(&fullglob[xrd_glob_len], RBAR_DIRGLOB); - glob_t globbuf = { 0 }; - switch (glob(fullglob, GLOB_ONLYDIR|GLOB_NOSORT, NULL, &globbuf)) { + glob_t __attribute__((__cleanup__(globfree))) globbuf = { 0 }; + switch (glob(fullglob, GLOB_ONLYDIR|GLOB_NOSORT|GLOB_ERR, NULL, &globbuf)) { case GLOB_NOSPACE: error(1, ENOMEM, "rbar_write"); assert(0); case GLOB_ABORTED: error(1, errno, "rbar_write: glob"); assert(0); case GLOB_NOMATCH: - return GLOB_NOMATCH; + return false; } const size_t filenamelen = strlen(filename); @@ -163,28 +170,25 @@ int rbar_write(const char *filename, const char *msg) { strcpy(&fullname[dirnamelen+1], filename); int fd = open(fullname, O_WRONLY|O_APPEND|O_CREAT, 0666); - if (fd < 0) + if (fd < 0) { + error(0, errno, "open: %s", fullname); continue; - write(fd, msg, msglen); + } + if (write(fd, msg, msglen) < (ssize_t)msglen) + error(0, errno, "write: %s", fullname); + close(fd); } - return 0; + return true; } void rbar_remove(const char *fileglob) { - static const char *xrd = NULL; - static size_t xrdlen; - if (!xrd) { - xrd = rbar_globescape(getenv("XDG_RUNTIME_DIR")); - xrdlen = strlen(xrd); - } - - char *fullglob = alloca(xrdlen+(sizeof RBAR_DIRGLOB)+strlen(fileglob)+1); - strcpy(fullglob, xrd); - strcpy(&fullglob[xrdlen], RBAR_DIRGLOB); - fullglob[xrdlen+(sizeof RBAR_DIRGLOB)-1] = '/'; - strcpy(&fullglob[xrdlen+(sizeof RBAR_DIRGLOB)], fileglob); + char *fullglob = alloca(xrd_glob_len+(sizeof RBAR_DIRGLOB)+strlen(fileglob)+1); + strcpy(fullglob, xrd_glob); + strcpy(&fullglob[xrd_glob_len], RBAR_DIRGLOB); + fullglob[xrd_glob_len+(sizeof RBAR_DIRGLOB)-1] = '/'; + strcpy(&fullglob[xrd_glob_len+(sizeof RBAR_DIRGLOB)], fileglob); - glob_t globbuf = { 0 }; + glob_t __attribute__((__cleanup__(globfree))) globbuf = { 0 }; if (glob(fullglob, GLOB_NOSORT, NULL, &globbuf) != 0) return; for (size_t i = 0; i < globbuf.gl_pathc; i++) { diff --git a/.config/wmii-hg/rbar_clock.c b/.config/wmii-hg/rbar_clock.c index ab636c2..79ddff3 100644 --- a/.config/wmii-hg/rbar_clock.c +++ b/.config/wmii-hg/rbar_clock.c @@ -7,8 +7,13 @@ const char *cleanup_id; +void strfree(char **strp) { + free(*strp); +} + void cleanup(void) { - rbar_remove(rbar_globescape(cleanup_id)); + char __attribute__((__cleanup__(strfree))) *glob_id = rbar_globescape(cleanup_id); + rbar_remove(glob_id); } int update(const char *id) { @@ -42,11 +47,9 @@ int update(const char *id) { "label %a %F %T %Z(%z)", /* apparently %:::z" is supported by date(1gnu) but not strftime(3gnu) */ localtime(&now.tv_sec)) <= 0) error(1, 0, "strftime wanted a really long string"); - int err = rbar_write(id, str); - if (err != 0) { - if (err == GLOB_NOMATCH) - return 0; - return 1; + if (!rbar_write(id, str)) { + error(0, errno, "all rbars have disappeared"); + return 0; } } } |