From 9151c36b8606bfc6f307f695a9fbb067294705d9 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 30 Jul 2025 21:51:02 -0500 Subject: [PATCH] Progress: Initial setup for granting init program the ability to handle shutdown/reboot. The standard shutdown/reboot/ctrl-alt-delete process actually operates via interrupts. Make the init program interruptible by default and add notes in the help. Add additional callbacks. The help callback is added to print additional information specific to the init program. The process thread signal is going to be a new callback that the init program can use to define custom behavior. This custom behavior will utilize the special shutdown/reboot/ctrl-alt-delete signals. The init program will be handling more signals than the controller program. (I may want to consider looking into supporting more signals for the controller program as well.) --- data/build/settings.init | 4 +- data/build/stand_alone/config.h | 2 +- data/build/stand_alone/settings.init | 2 +- sources/c/program/controller/controller/main.c | 4 + sources/c/program/controller/init/init.h | 2 + sources/c/program/controller/init/main.c | 7 +- sources/c/program/controller/init/print.c | 33 ++++++ sources/c/program/controller/init/print.h | 43 ++++++++ sources/c/program/controller/init/signal.c | 111 +++++++++++++++++++++ sources/c/program/controller/init/signal.h | 67 +++++++++++++ sources/c/program/controller/main/common/type.h | 9 +- sources/c/program/controller/main/controller.h | 1 - sources/c/program/controller/main/print/message.c | 70 ++++++++++--- sources/c/program/controller/main/print/message.h | 93 ++++++++++++++++- .../controller/main/print/output/entry/setting.c | 36 +++---- .../controller/main/print/output/rule/validate.c | 2 +- sources/c/program/controller/main/process.c | 7 +- sources/c/program/controller/main/process.h | 3 +- sources/c/program/controller/main/thread/signal.c | 8 +- 19 files changed, 457 insertions(+), 47 deletions(-) create mode 100644 sources/c/program/controller/init/print.c create mode 100644 sources/c/program/controller/init/print.h create mode 100644 sources/c/program/controller/init/signal.c create mode 100644 sources/c/program/controller/init/signal.h diff --git a/data/build/settings.init b/data/build/settings.init index 43b2bc2..5deb3c7 100644 --- a/data/build/settings.init +++ b/data/build/settings.init @@ -52,9 +52,9 @@ build_libraries_static-individual_thread -l:libf_thread.a build_libraries_static-level -l:libfll_2.a -l:libfll_1.a -l:libfll_0.a -l:libcap.a build_libraries_static-monolithic -l:libfll.a -l:libcap.a -build_sources_program config.c main.c init.c string.c +build_sources_program config.c main.c init.c print.c signal.c string.c -build_sources_headers init.h string.h +build_sources_headers init.h print.h signal.h string.h build_sources_documentation man diff --git a/data/build/stand_alone/config.h b/data/build/stand_alone/config.h index 64ca67f..d7287a0 100644 --- a/data/build/stand_alone/config.h +++ b/data/build/stand_alone/config.h @@ -2253,7 +2253,7 @@ //#define _di_fll_program_standard_set_down_ //#define _di_fll_program_standard_set_up_ //#define _di_fll_program_standard_signal_handle_ -//#define _di_fll_program_standard_signal_received_ +#define _di_fll_program_standard_signal_received_ //#define _di_fll_program_standard_signal_received_wait_ #define _di_private_inline_f_print_to_error_ #define _di_private_inline_private_f_print_to_error_ diff --git a/data/build/stand_alone/settings.init b/data/build/stand_alone/settings.init index 7357eee..7639b49 100644 --- a/data/build/stand_alone/settings.init +++ b/data/build/stand_alone/settings.init @@ -108,7 +108,7 @@ build_sources_program program/controller/main/signal.c program/controller/main/s build_sources_program program/controller/main/thread.c program/controller/main/thread/cleanup.c program/controller/main/thread/control.c program/controller/main/thread/entry.c program/controller/main/thread/instance.c program/controller/main/thread/is.c program/controller/main/thread/rule.c program/controller/main/thread/signal.c build_sources_program program/controller/main/validate.c -build_sources_program program/controller/init/config.c program/controller/init/main.c program/controller/init/init.c program/controller/init/string.c +build_sources_program program/controller/init/config.c program/controller/init/main.c program/controller/init/init.c program/controller/init/print.c program/controller/init/signal.c program/controller/init/string.c build_sources_documentation man diff --git a/sources/c/program/controller/controller/main.c b/sources/c/program/controller/controller/main.c index aa68c3d..987872d 100644 --- a/sources/c/program/controller/controller/main.c +++ b/sources/c/program/controller/controller/main.c @@ -17,6 +17,10 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { f_console_parameter_t parameters[] = controller_console_parameter_t_initialize; + data.callback.print_message_help = 0; + data.callback.process_entry_setup = 0; + data.callback.process_thread_signal = &controller_thread_signal; + data.program.parameters.array = parameters; data.program.parameters.used = controller_parameter_total_d; data.program.environment = envp; diff --git a/sources/c/program/controller/init/init.h b/sources/c/program/controller/init/init.h index 52bf80d..08aad9b 100644 --- a/sources/c/program/controller/init/init.h +++ b/sources/c/program/controller/init/init.h @@ -12,6 +12,8 @@ // Controller includes. #include +#include +#include #include #ifdef __cplusplus diff --git a/sources/c/program/controller/init/main.c b/sources/c/program/controller/init/main.c index c9d77a3..02650d5 100644 --- a/sources/c/program/controller/init/main.c +++ b/sources/c/program/controller/init/main.c @@ -25,13 +25,16 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { data.program.pipe = fll_program_data_pipe_input_e; } + data.callback.print_message_help = &controller_init_print_message_help; data.callback.process_entry_setup = &controller_init_process_entry_setup; + data.callback.process_thread_signal = &controller_init_signal_thread; + data.process.entry.pid = controller_entry_pid_disable_e; data.process.entry.show = controller_entry_show_init_e; data.process.mode = controller_process_mode_service_e; - data.setting.flag &= ~controller_main_flag_interruptible_d; + data.setting.flag |= controller_main_flag_interruptible_d; - fll_program_standard_set_up(&data.program); + controller_init_signal_set_up(&data); f_file_umask_get(&data.program.umask); diff --git a/sources/c/program/controller/init/print.c b/sources/c/program/controller/init/print.c new file mode 100644 index 0000000..fead7cc --- /dev/null +++ b/sources/c/program/controller/init/print.c @@ -0,0 +1,33 @@ +#include "init.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_controller_init__print_message_help_ + f_status_t controller_init_print_message_help(fl_print_t * const print) { + + if (!print) return F_status_set_error(F_output_not); + + f_file_stream_lock(print->to); + + controller_print_message_help_standard(print); + + controller_print_message_help_note_simulate(print); + f_print_dynamic_raw(f_string_eol_s, print->to); + + controller_print_message_help_note_interrupt(print); + fl_print_format(" Using the %[%r%r%] parameter may prevent the init program from receiving reboot and shutdown commands via signals.%r%r", print->to, print->set->notable, f_console_symbol_long_normal_s, controller_long_uninterruptible_s, print->set->notable, f_string_eol_s, f_string_eol_s); + + controller_print_message_help_note_pid(print); + + f_file_stream_flush(print->to); + f_file_stream_unlock(print->to); + + return F_okay; + } +#endif // _di_controller_init__print_message_help_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/program/controller/init/print.h b/sources/c/program/controller/init/print.h new file mode 100644 index 0000000..06f3408 --- /dev/null +++ b/sources/c/program/controller/init/print.h @@ -0,0 +1,43 @@ +/** + * FLL - Level 3 + * + * Project: Controller + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides print functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _controller_init_print_h +#define _controller_init_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print help specific to the Init program. + * + * @param print + * The output structure to print to. + * + * This requires print.custom to be controller_t. + * + * This does not alter print.custom.setting.state.status. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_controller_init__print_message_help_ + extern f_status_t controller_init_print_message_help(fl_print_t * const print); +#endif // _di_controller_init__print_message_help_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _controller_init_print_h diff --git a/sources/c/program/controller/init/signal.c b/sources/c/program/controller/init/signal.c new file mode 100644 index 0000000..0ff5693 --- /dev/null +++ b/sources/c/program/controller/init/signal.c @@ -0,0 +1,111 @@ +#include "init.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_controller_init_signal_set_up_ + f_status_t controller_init_signal_set_up(controller_t * const main) { + + if (!main) return F_status_set_error(F_parameter); + + f_signal_set_empty(&main->program.signal.set); + f_signal_set_add(F_signal_abort, &main->program.signal.set); + f_signal_set_add(F_signal_broken_pipe, &main->program.signal.set); + f_signal_set_add(F_signal_child, &main->program.signal.set); + f_signal_set_add(F_signal_continue, &main->program.signal.set); + f_signal_set_add(F_signal_hangup, &main->program.signal.set); + f_signal_set_add(F_signal_interrupt, &main->program.signal.set); + f_signal_set_add(F_signal_keyboard_stop, &main->program.signal.set); + f_signal_set_add(F_signal_power_failure, &main->program.signal.set); + f_signal_set_add(F_signal_quit, &main->program.signal.set); + f_signal_set_add(F_signal_stop, &main->program.signal.set); + f_signal_set_add(F_signal_termination, &main->program.signal.set); + f_signal_set_add(F_signal_user_1, &main->program.signal.set); + f_signal_set_add(F_signal_user_2, &main->program.signal.set); + + f_status_t status = f_signal_mask(SIG_BLOCK, &main->program.signal.set, 0); + if (F_status_is_error(status)) return status; + + status = f_signal_open(&main->program.signal); + + // If there is an error opening a signal descriptor, then do not handle signals. + if (F_status_is_error(status)) { + f_signal_mask(SIG_UNBLOCK, &main->program.signal.set, 0); + f_signal_close(&main->program.signal); + + return status; + } + + // Unblock all other signals. + memset(&main->program.signal.set, 0, sizeof(sigset_t)); + + f_signal_set_fill(&main->program.signal.set); + f_signal_set_delete(F_signal_abort, &main->program.signal.set); + f_signal_set_delete(F_signal_broken_pipe, &main->program.signal.set); + f_signal_set_delete(F_signal_child, &main->program.signal.set); + f_signal_set_delete(F_signal_continue, &main->program.signal.set); + f_signal_set_delete(F_signal_hangup, &main->program.signal.set); + f_signal_set_delete(F_signal_interrupt, &main->program.signal.set); + f_signal_set_delete(F_signal_keyboard_stop, &main->program.signal.set); + f_signal_set_delete(F_signal_power_failure, &main->program.signal.set); + f_signal_set_delete(F_signal_quit, &main->program.signal.set); + f_signal_set_delete(F_signal_stop, &main->program.signal.set); + f_signal_set_delete(F_signal_termination, &main->program.signal.set); + f_signal_set_delete(F_signal_user_1, &main->program.signal.set); + f_signal_set_delete(F_signal_user_2, &main->program.signal.set); + + status = f_signal_mask(SIG_UNBLOCK, &main->program.signal.set, 0); + if (F_status_is_error(status)) return status; + + return F_okay; + } +#endif // _di_controller_init_signal_set_up_ + +#ifndef _di_controller_init_signal_thread_ + void controller_init_signal_thread(controller_t * const main, const uint8_t is_normal) { + + if (!main) return; + if (!controller_thread_is_enabled(&main->thread, is_normal)) return; + if (!(main->setting.flag & controller_main_flag_interruptible_d)) return; + + siginfo_t information; + f_time_spec_t time = f_time_spec_t_initialize; + + while (controller_thread_is_enabled(&main->thread, is_normal)) { + + memset((void *) &information, 0, sizeof(siginfo_t)); + + controller_time_now(controller_thread_timeout_exit_ready_seconds_d, controller_thread_timeout_exit_ready_nanoseconds_d, &time); + + // Allow thread to be interrupted and auto-cancelled while sleeping. + f_thread_cancel_state_set(PTHREAD_CANCEL_ASYNCHRONOUS, 0); + + if (f_signal_wait_until(&main->program.signal.set, &time, &information) == F_time_out) continue; + + // Prevent thread from being interrupted and auto-cancelled. + f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); + + // Reap zombie processes. + if (information.si_signo == F_signal_child) { + // @todo verify that this process id is a valid child process. + // @todo send F_signal_terminate first? + // @todo a waitpid() needs to be performed to check to see how to handle the child signal. + //f_signal_send(F_signal_kill, information.si_pid); + // @todo move this to a function and identify any pid files and clear it from the process array (see calls like: status = controller_file_pid_read(instance->path_pids.array[j], &pid);); + } + + if (information.si_signo == F_signal_interrupt || information.si_signo == F_signal_abort || information.si_signo == F_signal_quit || information.si_signo == F_signal_termination) { + main->thread.signal = information.si_signo; + + controller_thread_instance_cancel(main, is_normal, controller_thread_cancel_signal_e); + + break; + } + } // while + } +#endif // _di_controller_init_signal_thread_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/program/controller/init/signal.h b/sources/c/program/controller/init/signal.h new file mode 100644 index 0000000..02b7e86 --- /dev/null +++ b/sources/c/program/controller/init/signal.h @@ -0,0 +1,67 @@ +/** + * FLL - Level 3 + * + * Project: Controller + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides signal functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _controller_init_signal_h +#define _controller_init_signal_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform standard setup with custom signals. + * + * This is a modified version of fll_program_standard_set_up(). + * + * @param main + * The main program data. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_signal_mask(). + * Errors (with error bit) from: f_signal_open(). + * + * @see f_signal_mask() + * @see f_signal_open() + * @see f_signal_set_add() + * @see f_signal_set_delete() + * @see f_signal_set_empty() + * @see f_signal_set_fill() + */ +#ifndef _di_controller_init_signal_set_up_ + extern f_status_t controller_init_signal_set_up(controller_t * const main); +#endif // _di_controller_init_signal_set_up_ + +/** + * Thread for handling signals/interrupts for the init program. + * + * @param main + * The main program data. + * + * Must not be NULL. + * @param is_normal + * If TRUE, then process as if this operates during a normal operation (Entry and Control). + * If FALSE, then process as if this operates during an Exit operation. + */ +#ifndef _di_controller_init_signal_thread_ + extern void controller_init_signal_thread(controller_t * const main, const uint8_t is_normal); +#endif // _di_controller_init_signal_thread_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _controller_init_signal_h diff --git a/sources/c/program/controller/main/common/type.h b/sources/c/program/controller/main/common/type.h index 44fe04f..1799e17 100644 --- a/sources/c/program/controller/main/common/type.h +++ b/sources/c/program/controller/main/common/type.h @@ -51,16 +51,23 @@ extern "C" { * The Controller callbacks. * * Properties: - * - process_entry_setup: Perform any optional initialization on the entry. + * - print_message_help: Callback for printing the help message. + * - process_entry_setup: Perform any optional initialization on the entry. + * - process_thread_signal: Handle signals for threaded operation. */ #ifndef _di_controller_t_ typedef struct { + f_status_t (*print_message_help)(fl_print_t * const print); + f_status_t (*process_entry_setup)(controller_t * const main, controller_entry_t * const entry); + void (*process_thread_signal)(controller_t * const main, const uint8_t is_normal); } controller_callback_t; #define controller_callback_t_initialize \ { \ 0, \ + 0, \ + 0, \ } #endif // _di_controller_t_ diff --git a/sources/c/program/controller/main/controller.h b/sources/c/program/controller/main/controller.h index d020314..272e9c8 100644 --- a/sources/c/program/controller/main/controller.h +++ b/sources/c/program/controller/main/controller.h @@ -143,7 +143,6 @@ #include #include #include -#include #include #include #include diff --git a/sources/c/program/controller/main/print/message.c b/sources/c/program/controller/main/print/message.c index 4b58787..8de44ad 100644 --- a/sources/c/program/controller/main/print/message.c +++ b/sources/c/program/controller/main/print/message.c @@ -5,12 +5,68 @@ extern "C" { #endif #ifndef _di_controller_print_message_help_ - f_status_t controller_print_message_help(fl_print_t * const print, const uint8_t uninterrupt) { + f_status_t controller_print_message_help(fl_print_t * const print) { if (!print) return F_status_set_error(F_output_not); f_file_stream_lock(print->to); + controller_print_message_help_standard(print); + + controller_print_message_help_note_simulate(print); + f_print_dynamic_raw(f_string_eol_s, print->to); + + controller_print_message_help_note_interrupt(print); + f_print_dynamic_raw(f_string_eol_s, print->to); + + controller_print_message_help_note_pid(print); + + f_file_stream_flush(print->to); + f_file_stream_unlock(print->to); + + return F_okay; + } +#endif // _di_controller_print_message_help_ + +#ifndef _di_controller_print_message_help_note_interrupt_ + f_status_t controller_print_message_help_note_interrupt(fl_print_t * const print) { + + if (!print) return F_status_set_error(F_output_not); + + fl_print_format(" The default interrupt behavior is to operate as if the %[%r%r%] parameter is passed.%r", print->to, print->set->notable, f_console_symbol_long_normal_s, controller_long_interruptible_s, print->set->notable, f_string_eol_s); + + return F_okay; + } +#endif // _di_controller_print_message_help_note_interrupt_ + +#ifndef _di_controller_print_message_help_note_pid_ + f_status_t controller_print_message_help_note_pid(fl_print_t * const print) { + + if (!print) return F_status_set_error(F_output_not); + + fl_print_format(" Specify an empty string for the %[%r%r%] parameter to disable pid file creation for this program.%r", print->to, print->set->notable, f_console_symbol_long_normal_s, controller_long_pid_s, print->set->notable, f_string_eol_s); + + return F_okay; + } +#endif // _di_controller_print_message_help_note_pid_ + +#ifndef _di_controller_print_message_help_note_simulate_ + f_status_t controller_print_message_help_note_simulate(fl_print_t * const print) { + + if (!print) return F_status_set_error(F_output_not); + + fl_print_format("%r When both the %[%r%r%] parameter and the", print->to, f_string_eol_s, print->set->notable, f_console_symbol_long_normal_s, controller_long_simulate_s, print->set->notable); + fl_print_format(" %[%r%r%] parameter are specified, then additional information on each would be executed Rule is printed but no simulation is performed.%r", print->to, print->set->notable, f_console_symbol_long_normal_s, controller_long_validate_s, print->set->notable, f_string_eol_s); + + return F_okay; + } +#endif // _di_controller_print_message_help_note_simulate_ + +#ifndef _di_controller_print_message_help_standard_ + f_status_t controller_print_message_help_standard(fl_print_t * const print) { + + if (!print) return F_status_set_error(F_output_not); + fll_program_print_help_header(print, controller_program_name_long_s, controller_program_version_s); fll_program_print_help_option_standard(print); @@ -31,19 +87,9 @@ extern "C" { fll_program_print_help_usage(print, controller_program_name_s, f_string_empty_s); - fl_print_format("%r When both the %[%r%r%] parameter and the", print->to, f_string_eol_s, print->set->notable, f_console_symbol_long_normal_s, controller_long_simulate_s, print->set->notable); - fl_print_format(" %[%r%r%] parameter are specified, then additional information on each would be executed Rule is printed but no simulation is performed.%r%r", print->to, print->set->notable, f_console_symbol_long_normal_s, controller_long_validate_s, print->set->notable, f_string_eol_s, f_string_eol_s); - - fl_print_format(" The default interrupt behavior is to operate as if the %[%r%r%] parameter is passed.%r%r", print->to, print->set->notable, f_console_symbol_long_normal_s, uninterrupt ? controller_long_uninterruptible_s : controller_long_interruptible_s, print->set->notable, f_string_eol_s, f_string_eol_s); - - fl_print_format(" Specify an empty string for the %[%r%r%] parameter to disable pid file creation for this program.%r", print->to, print->set->notable, f_console_symbol_long_normal_s, controller_long_pid_s, print->set->notable, f_string_eol_s); - - f_file_stream_flush(print->to); - f_file_stream_unlock(print->to); - return F_okay; } -#endif // _di_controller_print_message_help_ +#endif // _di_controller_print_message_help_standard_ #ifdef __cplusplus } // extern "C" diff --git a/sources/c/program/controller/main/print/message.h b/sources/c/program/controller/main/print/message.h index a6ac3ea..75c2961 100644 --- a/sources/c/program/controller/main/print/message.h +++ b/sources/c/program/controller/main/print/message.h @@ -25,9 +25,6 @@ extern "C" { * This requires print.custom to be controller_t. * * This does not alter print.custom.setting.state.status. - * @param uninterrupt - * Set to F_true to print that the default behavior is uninterruptible. - * Otherwise, print that the default behavior is interruptible. * * @return * F_okay on success. @@ -36,9 +33,97 @@ extern "C" { * F_output_not (with error bit) if setting is NULL. */ #ifndef _di_controller_print_message_help_ - extern f_status_t controller_print_message_help(fl_print_t * const print, const uint8_t uninterrupt); + extern f_status_t controller_print_message_help(fl_print_t * const print); #endif // _di_controller_print_message_help_ +/** + * Print interrupt note help. + * + * This expects the output to be already locked. + * + * @param print + * The output structure to print to. + * + * This requires print.custom to be controller_t. + * + * This does not alter print.custom.setting.state.status. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_controller_print_message_help_note_interrupt_ + extern f_status_t controller_print_message_help_note_interrupt(fl_print_t * const print); +#endif // _di_controller_print_message_help_note_interrupt_ + +/** + * Print PID note help. + * + * This expects the output to be already locked. + * + * @param print + * The output structure to print to. + * + * This requires print.custom to be controller_t. + * + * This does not alter print.custom.setting.state.status. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_controller_print_message_help_note_pid_ + extern f_status_t controller_print_message_help_note_pid(fl_print_t * const print); +#endif // _di_controller_print_message_help_note_pid_ + +/** + * Print simulate note help. + * + * This expects the output to be already locked. + * + * @param print + * The output structure to print to. + * + * This requires print.custom to be controller_t. + * + * This does not alter print.custom.setting.state.status. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_controller_print_message_help_note_simulate_ + extern f_status_t controller_print_message_help_note_simulate(fl_print_t * const print); +#endif // _di_controller_print_message_help_note_simulate_ + +/** + * Print standard help parameters and usage without the additional notes. + * + * This expects the output to be already locked. + * + * @param print + * The output structure to print to. + * + * This requires print.custom to be controller_t. + * + * This does not alter print.custom.setting.state.status. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_controller_print_message_help_standard_ + extern f_status_t controller_print_message_help_standard(fl_print_t * const print); +#endif // _di_controller_print_message_help_standard_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/program/controller/main/print/output/entry/setting.c b/sources/c/program/controller/main/print/output/entry/setting.c index 59e6153..3b43b0c 100644 --- a/sources/c/program/controller/main/print/output/entry/setting.c +++ b/sources/c/program/controller/main/print/output/entry/setting.c @@ -78,7 +78,7 @@ extern "C" { fl_print_format(" %r", print->to, *string); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Session. @@ -98,7 +98,7 @@ extern "C" { fl_print_format(" %r", print->to, *string, f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Show. @@ -118,7 +118,7 @@ extern "C" { fl_print_format(" %r", print->to, *string, f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Pid. @@ -141,7 +141,7 @@ extern "C" { fl_print_format(" %r", print->to, *string); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Pid File. @@ -151,7 +151,7 @@ extern "C" { fl_print_format(" %r", print->to, main->process.path_pid); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Control. @@ -161,7 +161,7 @@ extern "C" { fl_print_format(" %Q", print->to, main->process.path_control); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Control Has. @@ -171,7 +171,7 @@ extern "C" { fl_print_format(" %r", print->to, controller_readonly_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Control User. @@ -181,7 +181,7 @@ extern "C" { fl_print_format(" %u", print->to, (unsigned int) main->process.control.user); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Control Group. @@ -191,7 +191,7 @@ extern "C" { fl_print_format(" %u", print->to, (unsigned int) main->process.control.group); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Control Mode. @@ -203,7 +203,7 @@ extern "C" { } } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Timeout: Exit. @@ -213,7 +213,7 @@ extern "C" { fl_print_format(" %ul", print->to, entry->timeout_exit, f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Timeout: Kill. @@ -223,7 +223,7 @@ extern "C" { fl_print_format(" %ul", print->to, entry->timeout_kill, f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Timeout: Start. @@ -233,7 +233,7 @@ extern "C" { fl_print_format(" %ul", print->to, entry->timeout_start, f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Timeout: Stop. @@ -243,7 +243,7 @@ extern "C" { fl_print_format(" %ul", print->to, entry->timeout_stop, f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Define. @@ -382,7 +382,7 @@ extern "C" { } } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Parameters. @@ -393,7 +393,7 @@ extern "C" { fl_print_format(" %Q", print->to, action->parameters.array[0], f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); } else if (raw) { for (k = 0; k < action->parameters.used; ++k) { @@ -409,7 +409,7 @@ extern "C" { fl_print_format(" %Q", print->to, action->parameters.array[0], f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); // Parameter, File. @@ -419,7 +419,7 @@ extern "C" { fl_print_format(" %Q", print->to, action->parameters.array[1], f_string_eol_s); } - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); } fl_print_format(" }%r", print->to, f_string_eol_s); diff --git a/sources/c/program/controller/main/print/output/rule/validate.c b/sources/c/program/controller/main/print/output/rule/validate.c index 76dd0eb..72bbd81 100644 --- a/sources/c/program/controller/main/print/output/rule/validate.c +++ b/sources/c/program/controller/main/print/output/rule/validate.c @@ -150,7 +150,7 @@ extern "C" { } } // for - fl_print_format("%r", print->to, f_string_eol_s); + f_print_dynamic_raw(f_string_eol_s, print->to); } else { fl_print_format(" %[%r%] %Q%r", print->to, print->set->important, controller_engine_s, print->set->important, rule->engine, f_string_eol_s); diff --git a/sources/c/program/controller/main/process.c b/sources/c/program/controller/main/process.c index c9dc186..7ce4b08 100644 --- a/sources/c/program/controller/main/process.c +++ b/sources/c/program/controller/main/process.c @@ -13,7 +13,12 @@ extern "C" { if (main->setting.flag & controller_main_flag_version_copyright_help_d) { if (main->setting.flag & controller_main_flag_help_d) { - controller_print_message_help(&main->program.message, F_false); + if (main->callback.print_message_help) { + main->callback.print_message_help(&main->program.message); + } + else { + controller_print_message_help(&main->program.message); + } } else if (main->setting.flag & controller_main_flag_version_d) { fll_program_print_version(&main->program.message, controller_program_version_s); diff --git a/sources/c/program/controller/main/process.h b/sources/c/program/controller/main/process.h index 9d974f2..5ef9a44 100644 --- a/sources/c/program/controller/main/process.h +++ b/sources/c/program/controller/main/process.h @@ -19,7 +19,8 @@ extern "C" { /** * Execute main program process, starting all threads, waiting on threads, and handling requests. * - * If main.signal is non-zero, then this blocks and handles the following signals: + * If main.signal is non-zero, then this blocks and handles the signals defined in the main.program.signal.set. + * The standard signals are (see the init program for its modifications on main.program.signal.set): * - F_signal_abort * - F_signal_broken_pipe * - F_signal_hangup diff --git a/sources/c/program/controller/main/thread/signal.c b/sources/c/program/controller/main/thread/signal.c index 842e1f2..7a59741 100644 --- a/sources/c/program/controller/main/thread/signal.c +++ b/sources/c/program/controller/main/thread/signal.c @@ -84,7 +84,9 @@ extern "C" { f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - controller_thread_signal((controller_t *) argument, F_true); + if (argument && ((controller_t *) argument)->callback.process_thread_signal) { + ((controller_t *) argument)->callback.process_thread_signal((controller_t *) argument, F_true); + } return 0; } @@ -95,7 +97,9 @@ extern "C" { f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - controller_thread_signal((controller_t *) argument, F_false); + if (argument && ((controller_t *) argument)->callback.process_thread_signal) { + ((controller_t *) argument)->callback.process_thread_signal((controller_t *) argument, F_false); + } return 0; } -- 1.8.3.1