gawk

[old] Sed-like interface to the Gopher protocol
Log | Files | Refs | LICENSE

commit ffba757836dd113b7c4f858dd1bc7140eb017fc8
parent a1ea8f71d6c75d7a03e21ba6e0ab8da15846bd88
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Fri,  1 Jan 2021 20:10:35 -0800

Add better signal handling

Create a function to remove temporary files without unwinding the
stack and simply call exit(1) in sighandler. This fixes hanging due
to DNS lookups or recv.

Also bump copywrite year.

Diffstat:
Mconfig.def.h | 3---
Mmain.c | 55+++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -3,9 +3,6 @@ /* default gopher hole (path, host, port): */ static const char *default_address[] = { "/", "localhost", "70" }; -/* signals to handle */ -static const int signals[] = { SIGABRT, SIGCHLD, SIGINT, SIGTERM }; - #define IFS ":\t " /* input field seporator */ #define ISS ";\n" /* input statement seporator */ diff --git a/main.c b/main.c @@ -1,5 +1,5 @@ /* This file is part of gawk to browse gopher servers. - * Copyright (C) 2020 Jacob R. Edwards + * Copyright (C) 2020, 2021 Jacob R. Edwards * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #include <sys/stat.h> #include <sys/wait.h> #include <ctype.h> +#include <dirent.h> #include <err.h> #include <errno.h> #include <libgen.h> @@ -81,6 +82,16 @@ wfclose(FILE *fp) } int +wremove(const char *path) +{ + if (remove(path)) { + warn("unable to remove '%s'", path); + return -1; + } + return 0; +} + +int warg(int min, int max, int argc, const char **ap) { if (max > 0 && argc > max) { @@ -686,8 +697,8 @@ gawk(const char **addr) } } - if (mycache && unlink(cache) == -1) - warn("unable to unlink '%s'", cache); + if (mycache) + wremove(cache); if (feof(stdin)) done = depth; @@ -701,22 +712,34 @@ gawk(const char **addr) } void +cleanup(void) +{ + DIR *dir; + char path[MY_PATH_MAX]; + struct dirent *ent; + + dir = opendir(tmpdir); + if (dir == NULL) + return; /* ENOTDIR */ + while ((ent = readdir(dir)) != NULL) { + if (ent->d_type == DT_REG) { + snprintf(path, sizeof(path), "%s/%s", tmpdir, ent->d_name); + wremove(path); + } + } + wremove(tmpdir); +} + +void sighandler(int sig) { - switch (sig) { - case SIGCHLD: - while (waitpid(WAIT_ANY, NULL, WNOHANG) > 0); - break; - default: - wfclose(stdin); - fatal = 1; - } + cleanup(); + exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { - int i; int status; if (argc > 1 && *argv[1] == '-') { @@ -729,14 +752,14 @@ main(int argc, char *argv[]) err(1, "pledge"); #endif /* __OpenBSD__ */ - for (i = 0; i < LEN(signals); ++i) - signal(signals[i], sighandler); + signal(SIGCHLD, SIG_IGN); + signal(SIGINT, sighandler); if (mkdtemp(tmpdir) == NULL) err(1, "mkdtemp '%s'", tmpdir); status = sgoto(argc - 1, (const char **)argv + 1, 0, default_address); - if (rmdir(tmpdir) == -1) - err(1, "rmdir '%s'", tmpdir); + if (wremove(tmpdir) == -1) + return 1; return status; }