From d590bf66ade4a88b6c02d467165ad89f00f3254f Mon Sep 17 00:00:00 2001 From: Nikita Ivanov Date: Fri, 17 Jun 2022 01:43:37 +0500 Subject: [PATCH] Better macros for error handling --- src/config.c | 4 ++-- src/ctpv.c | 16 +++++++--------- src/error.h | 28 +++++++++++++++++++++------- src/lexer.c | 2 +- src/preview.c | 15 +++++++-------- src/server.c | 16 ++++++++-------- src/shell.c | 2 +- src/ulist.c | 4 ++-- src/utils.c | 10 +++++----- src/vector.c | 6 +++--- 10 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/config.c b/src/config.c index d29ae10..5e5602b 100644 --- a/src/config.c +++ b/src/config.c @@ -281,8 +281,8 @@ int config_load(VectorPreview *prevs, char *filename) { int ret = OK; - FILE *f = fopen(filename, "r"); - ERRCHK_GOTO(!f, ret, exit, FUNCFAILED("fopen"), ERRNOS); + FILE *f; + ERRCHK_GOTO_ERN(!(f = fopen(filename, "r")), ret, exit); lexer = lexer_init(f); previews = prevs; diff --git a/src/ctpv.c b/src/ctpv.c index 755ff9e..1a88271 100644 --- a/src/ctpv.c +++ b/src/ctpv.c @@ -46,11 +46,9 @@ static void cleanup(void) static int init_magic(void) { - ERRCHK_RET(!(magic = magic_open(MAGIC_MIME_TYPE)), FUNCFAILED("magic_open"), - magic_error(magic)); + ERRCHK_RET_MSG(!(magic = magic_open(MAGIC_MIME_TYPE)), magic_error(magic)); - ERRCHK_RET(magic_load(magic, NULL) != 0, FUNCFAILED("magic_load"), - magic_error(magic)); + ERRCHK_RET_MSG(magic_load(magic, NULL) != 0, magic_error(magic)); return OK; } @@ -59,7 +57,7 @@ static int create_dir(char *buf, size_t len) { char dir[len]; strncpy(dir, buf, LEN(dir) - 1); - ERRCHK_RET(mkpath(dir, 0700) == -1, FUNCFAILED("mkpath"), ERRNOS); + ERRCHK_RET_ERN(mkpath(dir, 0700) == -1); return OK; } @@ -98,7 +96,7 @@ static const char *get_mimetype(const char *path) { const char *r = magic_file(magic, path); if (!r) { - PRINTINTERR(FUNCFAILED("magic_file"), magic_error(magic)); + FUNCFAILED("magic_file", magic_error(magic)); return NULL; } @@ -113,7 +111,7 @@ static int check_file(const char *f) } if (access(f, R_OK) != 0) { - print_errorf("failed to access '%s': %s", f, ERRNOS); + print_errorf("failed to access '%s': %s", f, strerror(errno)); return ERR; } @@ -123,8 +121,8 @@ static int check_file(const char *f) static int is_newer(int *resp, char *f1, char *f2) { struct stat stat1, stat2; - ERRCHK_RET(stat(f1, &stat1) == -1, FUNCFAILED("stat"), ERRNOS); - ERRCHK_RET(stat(f2, &stat2) == -1, FUNCFAILED("stat"), ERRNOS); + ERRCHK_RET_ERN(stat(f1, &stat1) == -1); + ERRCHK_RET_ERN(stat(f2, &stat2) == -1); int sec_d = stat1.st_mtim.tv_sec - stat2.st_mtim.tv_sec; if (sec_d < 0) diff --git a/src/error.h b/src/error.h index c9ae3b5..3bde94b 100644 --- a/src/error.h +++ b/src/error.h @@ -6,20 +6,21 @@ #include "utils.h" -#define ERRNOS strerror(errno) +#define INTERRMSG "internal error: " -#define FUNCFAILED(f) f "() failed: %s" +/* + * Add error source to error message + */ +#define ERRSRC(msg) (__FILE__ ":" STRINGIZE(__LINE__) ": " msg) /* * Print internal error */ #define PRINTINTERR(format, ...) \ - print_error##__VA_OPT__(f)(ERRS(format) __VA_OPT__(, ) __VA_ARGS__) + print_error##__VA_OPT__(f)(ERRSRC(format) __VA_OPT__(, ) __VA_ARGS__) -/* - * Add error source to error message - */ -#define ERRS(msg) (__FILE__ ":" STRINGIZE(__LINE__) ": " msg) +#define FUNCFAILED(f, ...) \ + PRINTINTERR(INTERRMSG f "() failed" __VA_OPT__(": %s", __VA_ARGS__)) /* * If cond is true, return ERR. Also call print_error or @@ -42,6 +43,19 @@ } \ } while (0) +#define ERRCHK_MSG_(x) INTERRMSG "'" x "'" + +#define ERRCHK_RET_MSG(cond, ...) \ + ERRCHK_RET(cond, ERRCHK_MSG_(#cond) __VA_OPT__(": %s", ) __VA_ARGS__) + +#define ERRCHK_GOTO_MSG(cond, ret, label, ...) \ + ERRCHK_GOTO(cond, ret, label, \ + ERRCHK_MSG_(#cond) __VA_OPT__(": %s", ) __VA_ARGS__) + +#define ERRCHK_RET_ERN(cond) ERRCHK_RET_MSG(cond, strerror(errno)) +#define ERRCHK_GOTO_ERN(cond, ret, label) \ + ERRCHK_GOTO_MSG(cond, ret, label, strerror(errno)) + /* * Shortcut for ERRCHK_RET(expr != OK) */ diff --git a/src/lexer.c b/src/lexer.c index b171340..e0885fa 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -148,7 +148,7 @@ Lexer *lexer_init(FILE *f) Lexer *ctx; if (!(ctx = malloc(sizeof(*ctx)))) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } diff --git a/src/preview.c b/src/preview.c index c28699e..937dc55 100644 --- a/src/preview.c +++ b/src/preview.c @@ -51,7 +51,7 @@ void previews_init(Preview *ps, size_t len) previews.list = malloc(len * PREVP_SIZE); if (!previews.list) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } @@ -119,7 +119,7 @@ static void check_init_previews(void) static int run(Preview *p, int *exitcode, int *signal) { int pipe_fds[2]; - ERRCHK_RET(pipe(pipe_fds) == -1, FUNCFAILED("pipe"), ERRNOS); + ERRCHK_RET_ERN(pipe(pipe_fds) == -1); int sp_arg[] = { pipe_fds[0], pipe_fds[1], STDERR_FILENO }; @@ -138,7 +138,7 @@ static int run(Preview *p, int *exitcode, int *signal) } if (len == -1) { - PRINTINTERR(FUNCFAILED("read"), ERRNOS); + FUNCFAILED("read", strerror(errno)); ret = ERR; } } @@ -148,11 +148,10 @@ static int run(Preview *p, int *exitcode, int *signal) return ret; } -#define SET_PENV(n, v) \ - do { \ - if (v) \ - ERRCHK_RET(setenv((n), (v), 1) != 0, FUNCFAILED("setenv"), \ - ERRNOS); \ +#define SET_PENV(n, v) \ + do { \ + if (v) \ + ERRCHK_RET_ERN(setenv((n), (v), 1) != 0); \ } while (0) int preview_run(const char *ext, const char *mimetype, PreviewArgs *pa) diff --git a/src/server.c b/src/server.c index e9b6fc7..e55eac5 100644 --- a/src/server.c +++ b/src/server.c @@ -23,7 +23,7 @@ static void kill_ueberzug(void) if (errno == ESRCH) print_error("ueberzug is not running"); else - PRINTINTERR(FUNCFAILED("kill"), ERRNOS); + FUNCFAILED("kill", strerror(errno)); } spawn_wait(ueberzug_pid, NULL, NULL); @@ -36,13 +36,13 @@ static void sig_handler_exit(int s) static int register_signal(int sig, __sighandler_t handler) { - ERRCHK_RET(signal(sig, handler), FUNCFAILED("signal"), ERRNOS); + ERRCHK_RET_ERN(signal(sig, handler)); return OK; } static int open_fifo(int *fd, char *f) { - ERRCHK_RET((*fd = open(f, O_RDONLY | O_NONBLOCK)) == -1, FUNCFAILED("open"), ERRNOS); + ERRCHK_RET_ERN((*fd = open(f, O_RDONLY | O_NONBLOCK)) == -1); return OK; } @@ -63,7 +63,7 @@ static int listen(char *fifo) ERRCHK_GOTO_OK(register_signal(SIGTERM, sig_handler_exit), ret, fifo); int pipe_fds[2]; - ERRCHK_GOTO(pipe(pipe_fds) == -1, ret, signal, FUNCFAILED("pipe"), ERRNOS); + ERRCHK_GOTO_ERN(pipe(pipe_fds) == -1, ret, signal); char *args[] = { "ueberzug", "layer", NULL }; int sp_arg[] = { pipe_fds[1], pipe_fds[0], STDIN_FILENO }; @@ -105,7 +105,7 @@ static int listen(char *fifo) } - ERRCHK_GOTO(poll_ret < 0, ret, close, FUNCFAILED("poll"), ERRNOS); + ERRCHK_GOTO_ERN(poll_ret < 0, ret, close); close: close(pipe_fds[1]); @@ -154,7 +154,7 @@ int server_listen(const char *id_s) if (errno == EEXIST) print_errorf("server with id %s is already running or fifo %s still exists", id_s, fifo); else - PRINTINTERR(FUNCFAILED("mkfifo"), ERRNOS); + FUNCFAILED("mkfifo", strerror(errno)); ret = ERR; goto exit; } @@ -163,7 +163,7 @@ int server_listen(const char *id_s) fifo: if (remove(fifo) == -1 && errno != ENOENT) - PRINTINTERR(FUNCFAILED("remove"), ERRNOS); + FUNCFAILED("remove", strerror(errno)); exit: return ret; @@ -187,7 +187,7 @@ int server_set_fifo_var(const char *id_s) { char fifo[FIFO_FILENAME_SIZE]; get_fifo_name(fifo, LEN(fifo), id_s); - ERRCHK_RET(setenv("fifo", fifo, 1) != 0, FUNCFAILED("setenv"), ERRNOS); + ERRCHK_RET_ERN(setenv("fifo", fifo, 1) != 0); return OK; } diff --git a/src/shell.c b/src/shell.c index 52359d2..b06a1a8 100644 --- a/src/shell.c +++ b/src/shell.c @@ -15,7 +15,7 @@ char *prepend_helpers(char *str, size_t len) size_t l, helpers_len = LEN(scr_helpers_sh) - 1; if (!(buf = malloc(sizeof(*buf) * (helpers_len + len)))) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } diff --git a/src/ulist.c b/src/ulist.c index 821c932..70a158a 100644 --- a/src/ulist.c +++ b/src/ulist.c @@ -41,7 +41,7 @@ static struct UListNode *ulist_node_new(UList *l, size_t cap) cap = DEFAULT_CAP; if (!(n = malloc(ULIST_NODE_SIZE(cap, l->size)))) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } @@ -57,7 +57,7 @@ UList *ulist_new(size_t size, size_t cap) UList *l; if (!(l = malloc(sizeof(*l)))) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } diff --git a/src/utils.c b/src/utils.c index 79c9fb8..21bf4c2 100644 --- a/src/utils.c +++ b/src/utils.c @@ -15,8 +15,8 @@ int spawn_redirect(const void *arg) { int *fds = (int *)arg; - ERRCHK_RET(close(fds[0]) == -1, FUNCFAILED("close"), ERRNOS); - ERRCHK_RET(dup2(fds[1], fds[2]) == -1, FUNCFAILED("dup2"), ERRNOS); + ERRCHK_RET_ERN(close(fds[0]) == -1); + ERRCHK_RET_ERN(dup2(fds[1], fds[2]) == -1); return OK; } @@ -24,7 +24,7 @@ int spawn_redirect(const void *arg) int spawn_wait(pid_t pid, int *exitcode, int *signal) { int stat; - ERRCHK_RET(waitpid(pid, &stat, 0) == -1, FUNCFAILED("waitpid"), ERRNOS); + ERRCHK_RET_ERN(waitpid(pid, &stat, 0) == -1); if (exitcode) *exitcode = -1; @@ -58,7 +58,7 @@ int spawn(char *args[], pid_t *cpid, int *exitcode, int *signal, int (*cfunc)(co *exitcode = -1; pid_t pid = fork(); - ERRCHK_RET(pid == -1, FUNCFAILED("fork"), ERRNOS); + ERRCHK_RET_ERN(pid == -1); /* Child process */ if (pid == 0) { @@ -69,7 +69,7 @@ int spawn(char *args[], pid_t *cpid, int *exitcode, int *signal, int (*cfunc)(co if (errno == ENOENT) exit(NOTEXIST_EC); - PRINTINTERR(FUNCFAILED("exec"), ERRNOS); + FUNCFAILED("exec", strerror(errno)); exit(EXIT_FAILURE); } diff --git a/src/vector.c b/src/vector.c index edb2773..c265806 100644 --- a/src/vector.c +++ b/src/vector.c @@ -15,12 +15,12 @@ Vector *vector_new(size_t size, size_t cap) cap = DEFAULT_CAP; if (!(v = malloc(sizeof(*v)))) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } if (!(v->buf = malloc(size * cap))) { - PRINTINTERR(FUNCFAILED("malloc"), ERRNOS); + FUNCFAILED("malloc", strerror(errno)); abort(); } @@ -50,7 +50,7 @@ static void resize_if_needed(Vector *vec, size_t new_len) if (!(p = realloc(vec->buf, vec->size * cap))) { vector_free(vec); - PRINTINTERR(FUNCFAILED("realloc"), ERRNOS); + FUNCFAILED("realloc", strerror(errno)); abort(); }