From 9b43890591da92497a104490efd4e63157cb7c53 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 6 Apr 2020 15:44:15 +0200 Subject: cleanup: simplify runsvc environment config parsing Signed-off-by: David Oberhollenzer --- cmd/Makemodule.am | 2 +- cmd/runsvc.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/runsvc/env.c | 109 --------------------------------- cmd/runsvc/runsvc.c | 115 ----------------------------------- cmd/runsvc/runsvc.h | 23 ------- 5 files changed, 170 insertions(+), 248 deletions(-) create mode 100644 cmd/runsvc.c delete mode 100644 cmd/runsvc/env.c delete mode 100644 cmd/runsvc/runsvc.c delete mode 100644 cmd/runsvc/runsvc.h (limited to 'cmd') diff --git a/cmd/Makemodule.am b/cmd/Makemodule.am index 0af619f..4011b6c 100644 --- a/cmd/Makemodule.am +++ b/cmd/Makemodule.am @@ -3,7 +3,7 @@ shutdown_CPPFLAGS = $(AM_CPPFLAGS) shutdown_CFLAGS = $(AM_CFLAGS) shutdown_LDFLAGS = $(AM_LDFLAGS) -runsvc_SOURCES = cmd/runsvc/runsvc.c cmd/runsvc/env.c cmd/runsvc/runsvc.h +runsvc_SOURCES = cmd/runsvc.c runsvc_CPPFLAGS = $(AM_CPPFLAGS) runsvc_CFLAGS = $(AM_CFLAGS) runsvc_LDFLAGS = $(AM_LDFLAGS) diff --git a/cmd/runsvc.c b/cmd/runsvc.c new file mode 100644 index 0000000..db2de5b --- /dev/null +++ b/cmd/runsvc.c @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: ISC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "service.h" +#include "libcfg.h" +#include "config.h" + +#define ENVFILE ETCPATH "/initd.env" + +static int setup_env(void) +{ + int status = -1; + ssize_t ret; + FILE *fp; + + clearenv(); + + fp = fopen(ENVFILE, "r"); + if (fp == NULL) { + perror(ENVFILE); + return -1; + } + + do { + char *line = NULL; + size_t n = 0; + + errno = 0; + ret = getline(&line, &n, fp); + + if (ret < 0) { + if (errno == 0) { + status = 0; + } else { + perror(ENVFILE); + } + } else if (ret > 0 && putenv(line) != 0) { + perror("putenv"); + ret = -1; + } + + free(line); + } while (ret >= 0); + + fclose(fp); + return status; +} + +static int setup_tty(const char *tty, bool truncate) +{ + int fd; + + if (tty == NULL) + return 0; + + fd = open(tty, O_RDWR); + if (fd < 0) { + perror(tty); + return -1; + } + + if (truncate) + ftruncate(fd, 0); + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + setsid(); + + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + return 0; +} + +static __attribute__((noreturn)) void argv_exec(exec_t *e) +{ + char **argv = alloca(sizeof(char *) * (e->argc + 1)), *ptr; + int i; + + for (ptr = e->args, i = 0; i < e->argc; ++i, ptr += strlen(ptr) + 1) + argv[i] = ptr; + + argv[i] = NULL; + execvp(argv[0], argv); + perror(argv[0]); + exit(EXIT_FAILURE); +} + +static int run_sequentially(exec_t *list) +{ + pid_t ret, pid; + int status; + + for (; list != NULL; list = list->next) { + if (list->next == NULL) + argv_exec(list); + + pid = fork(); + + if (pid == 0) + argv_exec(list); + + if (pid == -1) { + perror("fork"); + return EXIT_FAILURE; + } + + do { + ret = waitpid(pid, &status, 0); + } while (ret != pid); + + if (!WIFEXITED(status)) + return EXIT_FAILURE; + + if (WEXITSTATUS(status) != EXIT_SUCCESS) + return WEXITSTATUS(status); + } + + return EXIT_SUCCESS; +} + +/*****************************************************************************/ + +int main(int argc, char **argv) +{ + service_t *svc = NULL; + int dirfd; + + if (argc != 3) { + fputs("usage: runsvc \n", stderr); + return EXIT_FAILURE; + } + + if (getppid() != 1) { + fputs("must be run by init!\n", stderr); + return EXIT_FAILURE; + } + + dirfd = open(argv[1], O_RDONLY | O_DIRECTORY); + if (dirfd < 0) { + perror(argv[1]); + return EXIT_FAILURE; + } + + svc = rdsvc(dirfd, argv[2], RDSVC_NO_FNAME | RDSVC_NO_DEPS); + close(dirfd); + if (svc == NULL) + return EXIT_FAILURE; + + if (setup_env()) + return EXIT_FAILURE; + + if (setup_tty(svc->ctty, (svc->flags & SVC_FLAG_TRUNCATE_OUT) != 0)) + return EXIT_FAILURE; + + return run_sequentially(svc->exec); +} diff --git a/cmd/runsvc/env.c b/cmd/runsvc/env.c deleted file mode 100644 index 4442e05..0000000 --- a/cmd/runsvc/env.c +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -#include "runsvc.h" - -struct entry { - struct entry *next; - char data[]; -}; - -extern char **environ; - -static void free_list(struct entry *list) -{ - struct entry *e; - - while (list != NULL) { - e = list; - list = list->next; - free(e); - } -} - -static struct entry *parse_list(rdline_t *rd) -{ - struct entry *e, *list = NULL; - char *ptr; - - while (rdline(rd) == 0) { - ptr = rd->line; - - while (*ptr != '\0' && *ptr != ' ' && *ptr != '=') - ++ptr; - - if (*ptr == ' ') - memmove(ptr, ptr + 1, strlen(ptr + 1) + 1); - - if (*(ptr++) != '=') { - fprintf(stderr, "%s: %zu: line is not of the shape " - "'key = value', skipping\n", - rd->filename, rd->lineno); - continue; - } - - if (*ptr == ' ') - memmove(ptr, ptr + 1, strlen(ptr + 1) + 1); - - if (unescape(ptr)) { - fprintf(stderr, "%s: %zu: malformed string constant, " - "skipping\n", - rd->filename, rd->lineno); - continue; - } - - e = calloc(1, sizeof(*e) + strlen(rd->line) + 1); - if (e == NULL) - goto fail_oom; - - strcpy(e->data, rd->line); - e->next = list; - list = e; - } - - return list; -fail_oom: - fputs("out of memory\n", stderr); - free_list(list); - return NULL; -} - -static struct entry *list_from_file(void) -{ - struct entry *list; - rdline_t rd; - - if (rdline_init(&rd, AT_FDCWD, ENVFILE, 0, NULL)) - return NULL; - - list = parse_list(&rd); - rdline_cleanup(&rd); - return list; -} - -int initenv(void) -{ - struct entry *list, *e; - int i, count; - char **envp; - - list = list_from_file(); - if (list == NULL) - return -1; - - for (count = 0, e = list; e != NULL; e = e->next) - ++count; - - envp = malloc((count + 1) * sizeof(char *)); - if (envp == NULL) { - fputs("out of memory\n", stderr); - free_list(list); - return -1; - } - - for (i = 0, e = list; e != NULL; e = e->next) - envp[i] = e->data; - - envp[i] = NULL; - - environ = envp; - return 0; -} diff --git a/cmd/runsvc/runsvc.c b/cmd/runsvc/runsvc.c deleted file mode 100644 index 75fdc46..0000000 --- a/cmd/runsvc/runsvc.c +++ /dev/null @@ -1,115 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -#include "runsvc.h" - -static int setup_tty(const char *tty, bool truncate) -{ - int fd; - - if (tty == NULL) - return 0; - - fd = open(tty, O_RDWR); - if (fd < 0) { - perror(tty); - return -1; - } - - if (truncate) - ftruncate(fd, 0); - - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - - setsid(); - - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - close(fd); - return 0; -} - -static __attribute__((noreturn)) void argv_exec(exec_t *e) -{ - char **argv = alloca(sizeof(char *) * (e->argc + 1)), *ptr; - int i; - - for (ptr = e->args, i = 0; i < e->argc; ++i, ptr += strlen(ptr) + 1) - argv[i] = ptr; - - argv[i] = NULL; - execvp(argv[0], argv); - perror(argv[0]); - exit(EXIT_FAILURE); -} - -static int run_sequentially(exec_t *list) -{ - pid_t ret, pid; - int status; - - for (; list != NULL; list = list->next) { - if (list->next == NULL) - argv_exec(list); - - pid = fork(); - - if (pid == 0) - argv_exec(list); - - if (pid == -1) { - perror("fork"); - return EXIT_FAILURE; - } - - do { - ret = waitpid(pid, &status, 0); - } while (ret != pid); - - if (!WIFEXITED(status)) - return EXIT_FAILURE; - - if (WEXITSTATUS(status) != EXIT_SUCCESS) - return WEXITSTATUS(status); - } - - return EXIT_SUCCESS; -} - -/*****************************************************************************/ - -int main(int argc, char **argv) -{ - service_t *svc = NULL; - int dirfd; - - if (argc != 3) { - fputs("usage: runsvc \n", stderr); - return EXIT_FAILURE; - } - - if (getppid() != 1) { - fputs("must be run by init!\n", stderr); - return EXIT_FAILURE; - } - - dirfd = open(argv[1], O_RDONLY | O_DIRECTORY); - if (dirfd < 0) { - perror(argv[1]); - return EXIT_FAILURE; - } - - svc = rdsvc(dirfd, argv[2], RDSVC_NO_FNAME | RDSVC_NO_DEPS); - close(dirfd); - if (svc == NULL) - return EXIT_FAILURE; - - if (initenv()) - return EXIT_FAILURE; - - if (setup_tty(svc->ctty, (svc->flags & SVC_FLAG_TRUNCATE_OUT) != 0)) - return EXIT_FAILURE; - - return run_sequentially(svc->exec); -} diff --git a/cmd/runsvc/runsvc.h b/cmd/runsvc/runsvc.h deleted file mode 100644 index 2a6ae49..0000000 --- a/cmd/runsvc/runsvc.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -#ifndef RUNSVC_H -#define RUNSVC_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "service.h" -#include "libcfg.h" -#include "config.h" - -#define ENVFILE ETCPATH "/initd.env" - -int initenv(void); - -#endif /* RUNSVC_H */ -- cgit v1.2.3