From e4526da2445454202d3db38c2de804c212d13fe7 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 30 Nov 2020 23:05:10 -0600 Subject: [PATCH] Progress: controller program. --- level_3/controller/c/controller.c | 8 +++ level_3/controller/c/controller.h | 9 +++- level_3/controller/c/main.c | 2 + level_3/controller/c/private-controller.c | 87 ++++++++++++++++++++++++++++++ level_3/controller/c/private-controller.h | 39 ++++++++++++++ level_3/controller/data/build/dependencies | 1 + level_3/controller/data/build/settings | 2 +- 7 files changed, 145 insertions(+), 3 deletions(-) diff --git a/level_3/controller/c/controller.c b/level_3/controller/c/controller.c index a26ab05..ac4b91a 100644 --- a/level_3/controller/c/controller.c +++ b/level_3/controller/c/controller.c @@ -229,6 +229,11 @@ extern "C" { } } + // @todo create pid file but not until "ready", so be sure to add this after pre-processing the entry file. + if (setting.ready) { + controller_file_pid_create(*data, setting.path_pid); + } + if (F_status_is_error_not(status)) { if (data->parameters[controller_parameter_test].result == f_console_result_found || data->parameters[controller_parameter_validate].result == f_console_result_found) { // @todo validate happens first, report and handle validation problems or success. @@ -250,9 +255,12 @@ extern "C" { } } + controller_file_pid_delete(*data, setting.path_pid); + macro_controller_setting_t_delete_simple(setting); macro_controller_entry_cache_t_delete_simple(cache_entry); macro_controller_rule_cache_t_delete_simple(cache_rule); + controller_delete_data(data); return status; diff --git a/level_3/controller/c/controller.h b/level_3/controller/c/controller.h index 4036d7b..6d97acf 100644 --- a/level_3/controller/c/controller.h +++ b/level_3/controller/c/controller.h @@ -12,11 +12,14 @@ * This program can be controlled from user-space via the "control" program. * * @todo research containers and build in container support into this, providing "container" appropriate verbiage for individual rules. + * @todo research namespaces and user_namespaces, they may be important to support. */ #ifndef _controller_h // libc includes #include +#include +#include // fll-0 includes #include @@ -68,10 +71,10 @@ extern "C" { // must be at least 2. #define controller_default_allocation_step 4 - #define controller_path_pid "/var/run/controller.pid" + #define controller_path_pid "/var/run/controller/controller.pid" #define controller_path_settings "/etc/controller" - #define controller_path_pid_length 23 + #define controller_path_pid_length 34 #define controller_path_settings_length 15 #define controller_short_interruptable "i" @@ -131,6 +134,7 @@ extern "C" { f_string_lengths_t remaining; bool process_pipe; + pid_t pid; f_file_t output; fll_error_print_t error; @@ -144,6 +148,7 @@ extern "C" { controller_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ + 0, \ f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ fll_macro_error_print_t_initialize_warning(), \ diff --git a/level_3/controller/c/main.c b/level_3/controller/c/main.c index a7833b5..653a1e4 100644 --- a/level_3/controller/c/main.c +++ b/level_3/controller/c/main.c @@ -8,6 +8,8 @@ int main(const unsigned long argc, const f_string_t *argv) { data.process_pipe = F_true; } + data.pid = getpid(); + if (F_status_is_error(controller_main(arguments, &data))) { return 1; } diff --git a/level_3/controller/c/private-controller.c b/level_3/controller/c/private-controller.c index 2bfb625..72d526c 100644 --- a/level_3/controller/c/private-controller.c +++ b/level_3/controller/c/private-controller.c @@ -82,6 +82,93 @@ extern "C" { } #endif // _di_controller_file_load_ +#ifndef _di_controller_file_pid_create_ + f_return_status controller_file_pid_create(const controller_data_t data, const f_string_static_t path_pid) { + f_status_t status = F_none; + + // the file exists, do not attempt to overwrite. + if (f_file_exists(path_pid.string) == F_true) { + return F_status_set_error(F_file_found); + } + + { + f_string_dynamic_t path_directory = f_string_dynamic_t_initialize; + + status = f_file_name_directory(path_pid.string, path_pid.used, &path_directory); + + if (F_status_is_error_not(status)) { + status = f_directory_exists(path_directory.string); + } + + f_macro_string_dynamic_t_delete_simple(path_directory); + + if (F_status_is_error(status)) return status; + + // the directory does not exist so do not bother attempting to create a pid file. + if (status == F_false) { + return F_status_set_error(F_directory_not); + } + } + + f_file_t file = f_file_t_initialize; + + file.flag = f_file_flag_write_only; + + status = f_file_stream_open(path_pid.string, f_macro_file_open_mode_truncate, &file); + if (F_status_is_error(status)) return status; + + fprintf(file.stream, "%llu\n", data.pid); + + f_file_stream_close(F_true, &file); + + if (F_status_is_error(status)) return status; + + return F_none; + } +#endif // _di_controller_file_pid_create_ + +#ifndef _di_controller_file_pid_delete_ + void controller_file_pid_delete(const controller_data_t data, const f_string_static_t path_pid) { + + if (f_file_exists(path_pid.string) != F_true) { + return; + } + + f_status_t status = F_none; + f_file_t pid_file = f_file_t_initialize; + + status = f_file_stream_open(path_pid.string, f_macro_file_open_mode_read, &pid_file); + if (F_status_is_error(status)) return; + + f_string_dynamic_t pid_buffer = f_string_dynamic_t_initialize; + + status = f_file_stream_read(pid_file, 1, &pid_buffer); + + f_file_stream_close(F_true, &pid_file); + + if (F_status_is_error_not(status)) { + f_number_unsigned_t number = 0; + f_string_range_t range = f_macro_string_range_t_initialize(pid_buffer.used); + + for (; range.start < pid_buffer.used; ++range.start) { + if (!isspace(pid_buffer.string[range.start])) break; + } // for + + for (; range.stop > 0; --range.stop) { + if (!isspace(pid_buffer.string[range.stop])) break; + } // for + + status = fl_conversion_string_to_decimal_unsigned(pid_buffer.string, &number, range); + + if (F_status_is_error_not(status) && number == data.pid) { + f_file_remove(path_pid.string); + } + } + + f_macro_string_dynamic_t_delete_simple(pid_buffer); + } +#endif // _di_controller_file_pid_delete_ + #ifndef _di_controller_status_simplify_ f_return_status controller_status_simplify(const f_status_t status) { diff --git a/level_3/controller/c/private-controller.h b/level_3/controller/c/private-controller.h index ae5c962..7a57e18 100644 --- a/level_3/controller/c/private-controller.h +++ b/level_3/controller/c/private-controller.h @@ -505,6 +505,45 @@ extern "C" { #endif // _di_controller_file_load_ /** + * Create the pid file, if possible. + * + * @param data + * The program data. + * @param path_pid + * The file path to the pid file to create. + * + * @return + * F_none on success. + * F_access_denied if pid file is not created due to access denied errors. + * F_directory_not if pid file is not created due to a parent directory is unavailable or invalid. + * + * Errors (with error bit) from: f_directory_exists(). + * Errors (with error bit) from: f_file_name_directory(). + * Errors (with error bit) from: f_file_stream_open(). + * + * @see f_directory_exists() + * @see f_file_name_directory() + * @see f_file_stream_open() + */ +#ifndef _di_controller_file_pid_create_ + f_return_status controller_file_pid_create(const controller_data_t data, const f_string_static_t path_pid) f_gcc_attribute_visibility_internal; +#endif // _di_controller_file_pid_create_ + +/** + * Delete the pid file, if exists and is valid. + * + * This is meant to be called on exit and avoids checking status codes, returning void. + * + * @param data + * The program data. + * @param path_pid + * The file path to the pid file to create. + */ +#ifndef _di_controller_file_pid_delete_ + void controller_file_pid_delete(const controller_data_t data, const f_string_static_t path_pid) f_gcc_attribute_visibility_internal; +#endif // _di_controller_file_pid_delete_ + +/** * Given a wide range of status codes, simplify them down to a small subset. * * @param status diff --git a/level_3/controller/data/build/dependencies b/level_3/controller/data/build/dependencies index 3dba6bd..739d2da 100644 --- a/level_3/controller/data/build/dependencies +++ b/level_3/controller/data/build/dependencies @@ -8,6 +8,7 @@ f_utf f_color f_console f_conversion +f_directory f_file f_fss f_iki diff --git a/level_3/controller/data/build/settings b/level_3/controller/data/build/settings index 8eeb29b..6ebae0d 100644 --- a/level_3/controller/data/build/settings +++ b/level_3/controller/data/build/settings @@ -19,7 +19,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_conversion -lfl_fss -lfl_status -lfl_string -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_utf +build_libraries-individual -lfll_error -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_conversion -lfl_fss -lfl_iki -lfl_status -lfl_string -lf_console -lf_conversion -lf_directory -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_sources_library controller.c private-control.c private-controller.c private-entry.c private-rule.c -- 1.8.3.1