From f3bca5f87f29e4428e51c04057d5609364e2c4ba Mon Sep 17 00:00:00 2001 From: mbays Date: Sat, 3 Apr 2021 00:00:01 +0000 Subject: [PATCH] clean up on termination --- main.c | 64 ++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/main.c b/main.c index dca35aa..a52c474 100644 --- a/main.c +++ b/main.c @@ -483,6 +483,23 @@ static void usage() } +/* state as global variable, so we can clean up on termination */ +State state = {}; + +static void cleanup(int sig) { + for (int i = 0; i < state.num_children; ++i) { + Child *const c = &state.children[i]; + if (c->exists) { + close(c->in); + close(c->out); + close(c->flag); + kill(-c->pid, SIGKILL); + waitpid(c->pid, NULL, 0); + } + } + exit(1); +} + int main(int argc, char **argv) { if (argc < 2) { @@ -490,16 +507,10 @@ int main(int argc, char **argv) exit(1); } - State *state = malloc(sizeof(State)); - if (state == NULL) { - fprintf(stderr, "Failed to allocate memory for state."); - exit(1); - } - - state->max_children = MAX_CHILDREN; - state->read_timeout = DEF_READ_TIMEOUT; - state->pause_timeout = DEF_PAUSE_TIMEOUT; - state->format = gemtext; + state.max_children = MAX_CHILDREN; + state.read_timeout = DEF_READ_TIMEOUT; + state.pause_timeout = DEF_PAUSE_TIMEOUT; + state.format = gemtext; int convert_newlines = -1; @@ -526,33 +537,33 @@ int main(int argc, char **argv) socketname = optarg; break; case 'f': - if (0 == strcmp(optarg, "gemtext")) state->format=gemtext; - else if (0 == strcmp(optarg, "pre")) state->format=pre; - else if (0 == strcmp(optarg, "unwrapped")) state->format=unwrapped; - else if (0 == strcmp(optarg, "raw")) state->format=raw; + if (0 == strcmp(optarg, "gemtext")) state.format=gemtext; + else if (0 == strcmp(optarg, "pre")) state.format=pre; + else if (0 == strcmp(optarg, "unwrapped")) state.format=unwrapped; + else if (0 == strcmp(optarg, "raw")) state.format=raw; else { printf("Unknown format.\n"); exit(1); } break; case 'm': - state->max_children = atoi(optarg); - if (state->max_children <= 0 || state->max_children > MAX_CHILDREN) { + state.max_children = atoi(optarg); + if (state.max_children <= 0 || state.max_children > MAX_CHILDREN) { printf("Bad value for max children.\n"); printf("You may need to increase MAX_CHILDREN in the source.\n"); exit(1); } break; case 't': - state->read_timeout = atoi(optarg); - if (state->read_timeout < 0) { + state.read_timeout = atoi(optarg); + if (state.read_timeout < 0) { printf("Bad value for read timeout.\n"); exit(1); } break; case 'T': - state->pause_timeout = atoi(optarg); - if (state->pause_timeout < 0) { + state.pause_timeout = atoi(optarg); + if (state.pause_timeout < 0) { printf("Bad value for pause timeout.\n"); exit(1); } @@ -571,11 +582,16 @@ int main(int argc, char **argv) exit(1); } - state->command = argv[optind]; - state->args = &argv[optind]; - state->convert_newlines = convert_newlines < 0 ? state->format != raw : convert_newlines; + state.command = argv[optind]; + state.args = &argv[optind]; + state.convert_newlines = convert_newlines < 0 ? state.format != raw : convert_newlines; srandom(time(NULL)); - runSCGI(socketname, respond, state); + struct sigaction act = {}; + act.sa_handler = cleanup; + sigaction(SIGTERM, &act, NULL); + sigaction(SIGINT, &act, NULL); + + runSCGI(socketname, respond, &state); } -- 2.11.4.GIT