From: Davin McCall Date: Sat, 6 Jul 2019 00:05:09 +0000 (+0100) Subject: Implement "env-file" service setting for service-specific environment. X-Git-Tag: v0.6.0~9 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=79bfbd4f9eb62e3c589a9654ee26b4755181a7ae;p=oweals%2Fdinit.git Implement "env-file" service setting for service-specific environment. --- diff --git a/src/baseproc-service.cc b/src/baseproc-service.cc index 0bc9414..157b7ae 100644 --- a/src/baseproc-service.cc +++ b/src/baseproc-service.cc @@ -162,6 +162,7 @@ bool base_process_service::start_ps_process(const std::vector &cmd run_params.notify_fd = notify_pipe[1]; run_params.force_notify_fd = force_notification_fd; run_params.notify_var = notification_var.c_str(); + run_params.env_file = env_file.c_str(); run_child_proc(run_params); } else { diff --git a/src/dinit.cc b/src/dinit.cc index 5e87ccc..c997201 100644 --- a/src/dinit.cc +++ b/src/dinit.cc @@ -59,7 +59,6 @@ static void sigterm_cb(eventloop_t &eloop) noexcept; static void open_control_socket(bool report_ro_failure = true) noexcept; static void close_control_socket() noexcept; static void confirm_restart_boot() noexcept; -static void read_env_file(const char *); static void control_socket_cb(eventloop_t *loop, int fd); @@ -558,8 +557,8 @@ static void log_bad_env(int linenum) log(loglevel_t::ERROR, "invalid environment variable setting in environment file (line ", linenum, ")"); } -// Read and set environment variables from a file. -static void read_env_file(const char *env_file_path) +// Read and set environment variables from a file. May throw std::bad_alloc, std::system_error. +void read_env_file(const char *env_file_path) { // Note that we can't use the log in this function; it hasn't been initialised yet. diff --git a/src/includes/dinit.h b/src/includes/dinit.h index fc20ee3..180a5fd 100644 --- a/src/includes/dinit.h +++ b/src/includes/dinit.h @@ -15,6 +15,7 @@ using time_val = dasynq::time_val; void rootfs_is_rw() noexcept; void setup_external_log() noexcept; +void read_env_file(const char *); extern eventloop_t event_loop; diff --git a/src/includes/proc-service.h b/src/includes/proc-service.h index f3af541..b77113d 100644 --- a/src/includes/proc-service.h +++ b/src/includes/proc-service.h @@ -31,6 +31,7 @@ struct run_proc_params const char * const *args; // program arguments including executable (args[0]) const char *working_dir; // working directory const char *logfile; // log file or nullptr (stdout/stderr); must be valid if !on_console + const char *env_file; // file with environment settings (or nullptr) bool on_console; // whether to run on console int wpipefd; // pipe to which error status will be sent (if error occurs) int csfd; // control socket fd (or -1); may be moved @@ -44,9 +45,9 @@ struct run_proc_params run_proc_params(const char * const *args, const char *working_dir, const char *logfile, int wpipefd, uid_t uid, gid_t gid, const std::vector &rlimits) - : args(args), working_dir(working_dir), logfile(logfile), on_console(false), wpipefd(wpipefd), - csfd(-1), socket_fd(-1), notify_fd(-1), force_notify_fd(-1), notify_var(nullptr), uid(uid), - gid(gid), rlimits(rlimits) + : args(args), working_dir(working_dir), logfile(logfile), env_file(nullptr), on_console(false), + wpipefd(wpipefd), csfd(-1), socket_fd(-1), notify_fd(-1), force_notify_fd(-1), notify_var(nullptr), + uid(uid), gid(gid), rlimits(rlimits) { } }; @@ -128,6 +129,7 @@ class base_process_service : public service_record std::vector stop_arg_parts; string working_dir; // working directory (or empty) + string env_file; // file with environment settings for this service std::vector rlimits; // resource limits @@ -256,6 +258,11 @@ class base_process_service : public service_record stop_arg_parts = separate_args(stop_command, stop_command_offsets); } + void set_env_file(const std::string &env_file_p) + { + env_file = env_file_p; + } + void set_rlimits(std::vector &&rlimits_p) { rlimits = std::move(rlimits_p); diff --git a/src/load-service.cc b/src/load-service.cc index f4b4af2..3040cf3 100644 --- a/src/load-service.cc +++ b/src/load-service.cc @@ -436,6 +436,7 @@ service_record * dirload_service_set::load_service(const char * name) list> stop_command_offsets; string working_dir; string pid_file; + string env_file; bool do_sub_vars = false; @@ -493,6 +494,9 @@ service_record * dirload_service_set::load_service(const char * name) else if (setting == "working-dir") { working_dir = read_setting_value(i, end, nullptr); } + else if (setting == "env-file") { + env_file = read_setting_value(i, end, nullptr); + } else if (setting == "socket-listen") { socket_path = read_setting_value(i, end, nullptr); } @@ -757,6 +761,7 @@ service_record * dirload_service_set::load_service(const char * name) auto rvalps = new process_service(this, string(name), std::move(command), command_offsets, depends); rvalps->set_working_dir(working_dir); + rvalps->set_env_file(env_file); rvalps->set_rlimits(std::move(rlimits)); rvalps->set_restart_interval(restart_interval, max_restarts); rvalps->set_restart_delay(restart_delay); @@ -777,6 +782,7 @@ service_record * dirload_service_set::load_service(const char * name) auto rvalps = new bgproc_service(this, string(name), std::move(command), command_offsets, depends); rvalps->set_working_dir(working_dir); + rvalps->set_env_file(env_file); rvalps->set_rlimits(std::move(rlimits)); rvalps->set_pid_file(std::move(pid_file)); rvalps->set_restart_interval(restart_interval, max_restarts); @@ -794,6 +800,7 @@ service_record * dirload_service_set::load_service(const char * name) command_offsets, depends); rvalps->set_stop_command(stop_command, stop_command_offsets); rvalps->set_working_dir(working_dir); + rvalps->set_env_file(env_file); rvalps->set_rlimits(std::move(rlimits)); rvalps->set_stop_timeout(stop_timeout); rvalps->set_start_timeout(start_timeout); diff --git a/src/run-child-proc.cc b/src/run-child-proc.cc index 837a2c9..d3a8326 100644 --- a/src/run-child-proc.cc +++ b/src/run-child-proc.cc @@ -129,6 +129,19 @@ void base_process_service::run_child_proc(run_proc_params params) noexcept if (notify_fd == -1) goto failure_out; } + // Read environment from file + if (params.env_file != nullptr) { + try { + read_env_file(params.env_file); + } + catch (std::system_error &sys_err) { + errno = sys_err.code().value(); + } + catch (std::bad_alloc &alloc_err) { + errno = ENOMEM; goto failure_out; + } + } + // Set up notify-fd variable: if (notify_var != nullptr && *notify_var != 0) { // We need to do an allocation: the variable name length, '=', and space for the value, diff --git a/src/tests/test-includes/dinit.h b/src/tests/test-includes/dinit.h index e3cef62..5901346 100644 --- a/src/tests/test-includes/dinit.h +++ b/src/tests/test-includes/dinit.h @@ -215,6 +215,10 @@ inline void setup_external_log() noexcept { } +inline void read_env_file(const char *env_file_path) +{ +} + extern eventloop_t event_loop; #endif