From: Kevin Day Date: Fri, 15 Oct 2021 01:58:38 +0000 (-0500) Subject: Update: Execute changes and controller program changes. X-Git-Tag: 0.5.6~14 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=a9aa9602fe15a161559c4ce3bae3399f0c37e83d;p=fll Update: Execute changes and controller program changes. Tweak some of the execute status codes. I confused the errno parameters for what I was using F_execute_off for. Change F_execute_off to F_execute_bad to more accurately reflect what the error code represents. Add additional execute status codes. Provide a F_format and F_format_not status codes. Pass through non-negative, non-zero, exec return codes. For negative return codes that is not -1, set the execute error code to F_execute_failure. Improve error printing in controller program on child process failure. Start to cleanup print functions. There already is data being passed via the f_process_t, use those to better reduce the number of parameters passed to relevant functions. There is much more work in this regards to do, but that is to be done at another time. The controller program threads should exit with child code only if the child code is non-zero. When the child code is zero, then the normal (and preferred) thread exit is allowed to perform. --- diff --git a/level_0/f_execute/c/execute-common.h b/level_0/f_execute/c/execute-common.h index 3dc01f3..8f42c4f 100644 --- a/level_0/f_execute/c/execute-common.h +++ b/level_0/f_execute/c/execute-common.h @@ -34,6 +34,7 @@ extern "C" { enum { F_execute_none = 0, F_execute_access, + F_execute_bad, F_execute_buffer, F_execute_busy, F_execute_capability, @@ -43,6 +44,8 @@ extern "C" { F_execute_failure, F_execute_file_found_not, F_execute_file_type_directory, + F_execute_fork_not, + F_execute_format_not, F_execute_group, F_execute_input_output, F_execute_limit, @@ -50,7 +53,6 @@ extern "C" { F_execute_memory_not, F_execute_name_not, F_execute_nice, - F_execute_off, F_execute_parameter, F_execute_pipe, F_execute_processor, diff --git a/level_0/f_execute/c/execute.c b/level_0/f_execute/c/execute.c index 050e940..1b03ad3 100644 --- a/level_0/f_execute/c/execute.c +++ b/level_0/f_execute/c/execute.c @@ -40,7 +40,7 @@ extern "C" { } if (F_status_set_fine(status) == F_execute_not) { - return F_execute_off; + return F_execute_bad; } if (F_status_set_fine(status) == F_failure) { @@ -55,6 +55,14 @@ extern "C" { return F_execute_file_type_directory; } + if (F_status_set_fine(status) == F_fork_not) { + return F_execute_fork_not; + } + + if (F_status_set_fine(status) == F_format_not) { + return F_execute_format_not; + } + if (F_status_set_fine(status) == F_group) { return F_execute_group; } @@ -134,6 +142,10 @@ extern "C" { return F_access; } + if (status == F_execute_bad) { + return F_execute_not; + } + if (status == F_execute_buffer) { return F_buffer; } @@ -170,6 +182,14 @@ extern "C" { return F_file_type_directory; } + if (status == F_execute_fork_not) { + return F_fork_not; + } + + if (status == F_execute_format_not) { + return F_format_not; + } + if (status == F_execute_group) { return F_group; } @@ -198,10 +218,6 @@ extern "C" { return F_nice; } - if (status == F_execute_off) { - return F_execute_not; - } - if (status == F_execute_parameter) { return F_parameter; } diff --git a/level_0/f_status/c/status.h b/level_0/f_status/c/status.h index ad51a53..757cb4f 100644 --- a/level_0/f_status/c/status.h +++ b/level_0/f_status/c/status.h @@ -207,6 +207,8 @@ extern "C" { F_failure_not, F_fork, F_fork_not, + F_format, + F_format_not, F_found, F_found_not, F_full, diff --git a/level_1/fl_status/c/status.c b/level_1/fl_status/c/status.c index eb53745..d0ecee3 100644 --- a/level_1/fl_status/c/status.c +++ b/level_1/fl_status/c/status.c @@ -405,6 +405,12 @@ extern "C" { case F_fork_not: *string = FL_status_string_fork_not; break; + case F_format: + *string = FL_status_string_format; + break; + case F_format_not: + *string = FL_status_string_format_not; + break; case F_found: *string = FL_status_string_found; break; diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h index 293d9b5..a58762d 100644 --- a/level_1/fl_status/c/status.h +++ b/level_1/fl_status/c/status.h @@ -227,6 +227,8 @@ extern "C" { #define FL_status_string_failure_not "F_failure_not" #define FL_status_string_fork "F_fork" #define FL_status_string_fork_not "F_fork_not" + #define FL_status_string_format "F_format" + #define FL_status_string_format_not "F_format_not" #define FL_status_string_found "F_found" #define FL_status_string_found_not "F_found_not" #define FL_status_string_full "F_full" @@ -408,6 +410,8 @@ extern "C" { #define FL_status_string_failure_not_length 13 #define FL_status_string_fork_length 6 #define FL_status_string_fork_not_length 10 + #define FL_status_string_format_length 8 + #define FL_status_string_format_not_length 12 #define FL_status_string_found_length 7 #define FL_status_string_found_not_length 11 #define FL_status_string_full_length 6 diff --git a/level_2/fll_execute/c/execute.c b/level_2/fll_execute/c/execute.c index c4ea744..5d074f7 100644 --- a/level_2/fll_execute/c/execute.c +++ b/level_2/fll_execute/c/execute.c @@ -286,7 +286,7 @@ extern "C" { else if (errno == ENAMETOOLONG) code = F_execute_name_not; else if (errno == ENFILE) code = F_execute_resource_not; else if (errno == ENOENT) code = F_execute_file_found_not; - else if (errno == ENOEXEC) code = F_execute_off; + else if (errno == ENOEXEC) code = F_execute_bad; else if (errno == ENOMEM) code = F_execute_memory_not; else if (errno == ENOTDIR) code = F_execute_directory_not; else if (errno == EPERM) code = F_execute_prohibited; diff --git a/level_2/fll_execute/c/private-execute.c b/level_2/fll_execute/c/private-execute.c index 0d7562c..27d0204 100644 --- a/level_2/fll_execute/c/private-execute.c +++ b/level_2/fll_execute/c/private-execute.c @@ -364,12 +364,9 @@ extern "C" { if (parameter && parameter->signals) { #ifdef _di_pthread_support_ - f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); - #else // _di_pthread_support_ - if (parameter->option & fl_execute_parameter_option_threadsafe) { f_thread_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); f_thread_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); @@ -378,7 +375,6 @@ extern "C" { f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); } - #endif // _di_pthread_support_ } @@ -401,7 +397,7 @@ extern "C" { int code = direct ? execv(program, fixed_arguments) : execvp(program, fixed_arguments); - if (code < 0) { + if (code == -1) { if (errno == EACCES) code = F_execute_access; else if (errno == E2BIG) code = F_execute_too_large; else if (errno == EAGAIN) code = F_execute_resource_not; @@ -416,15 +412,15 @@ extern "C" { else if (errno == ENAMETOOLONG) code = F_execute_name_not; else if (errno == ENFILE) code = F_execute_resource_not; else if (errno == ENOENT) code = F_execute_file_found_not; - else if (errno == ENOEXEC) code = F_execute_off; + else if (errno == ENOEXEC) code = F_execute_bad; else if (errno == ENOMEM) code = F_execute_memory_not; else if (errno == ENOTDIR) code = F_execute_directory_not; else if (errno == EPERM) code = F_execute_prohibited; else if (errno == ETXTBSY) code = F_execute_busy; else code = F_execute_failure; } - else { - code = 0; + else if (code < 0) { + code = F_execute_failure; } if (result) { @@ -559,12 +555,9 @@ extern "C" { if (parameter && parameter->signals) { #ifdef _di_pthread_support_ - f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); - #else // _di_pthread_support_ - if (parameter->option & fl_execute_parameter_option_threadsafe) { f_thread_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); f_thread_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); @@ -573,7 +566,6 @@ extern "C" { f_signal_mask(SIG_BLOCK, ¶meter->signals->block, 0); f_signal_mask(SIG_UNBLOCK, ¶meter->signals->block_not, 0); } - #endif // _di_pthread_support_ } @@ -612,20 +604,15 @@ extern "C" { else if (errno == ENAMETOOLONG) code = F_execute_name_not; else if (errno == ENFILE) code = F_execute_resource_not; else if (errno == ENOENT) code = F_execute_file_found_not; - else if (errno == ENOEXEC) code = F_execute_off; + else if (errno == ENOEXEC) code = F_execute_bad; else if (errno == ENOMEM) code = F_execute_memory_not; else if (errno == ENOTDIR) code = F_execute_directory_not; else if (errno == EPERM) code = F_execute_prohibited; else if (errno == ETXTBSY) code = F_execute_busy; else code = F_execute_failure; } - else { - code = 0; - } - - if (result) { - int *r = (int *) result; - *r = code; + else if (code < 0) { + code = F_execute_failure; } if (result) { diff --git a/level_2/fll_status/c/status.c b/level_2/fll_status/c/status.c index cc2f46f..53284aa 100644 --- a/level_2/fll_status/c/status.c +++ b/level_2/fll_status/c/status.c @@ -805,6 +805,18 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_format, length, FL_status_string_format_length) == F_equal_to) { + *code = F_format; + + return F_none; + } + + if (fl_string_compare(string, FL_status_string_format_not, length, FL_status_string_format_not_length) == F_equal_to) { + *code = F_format_not; + + return F_none; + } + if (fl_string_compare(string, FL_status_string_found, length, FL_status_string_found_length) == F_equal_to) { *code = F_found; diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index fa16b8e..a8fcd59 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -1087,50 +1087,137 @@ extern "C" { #endif // _di_controller_rule_item_error_print_ #ifndef _di_controller_rule_item_error_print_execute_ - void controller_rule_item_error_print_execute(const fll_error_print_t print, const bool script_is, const f_string_t name, const int code, const f_status_t status, controller_thread_t * const thread) { + void controller_rule_item_error_print_execute(const bool script_is, const f_string_t name, const f_status_t status, controller_process_t * const process) { - if (print.verbosity != f_console_verbosity_quiet) { - controller_print_lock(print.to, thread); + if (((controller_main_t *) process->main_data)->error.verbosity != f_console_verbosity_quiet) { + fll_error_print_t * const print = &((controller_main_t *) process->main_data)->error; - fl_print_format("%c%[%SThe %s '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix, script_is ? controller_string_script_s : controller_string_program_s, print.context); - fl_print_format("%[%S%]", print.to.stream, print.notable, name, print.notable); + controller_print_lock(print->to, (controller_thread_t *) process->main_thread); + + fl_print_format("%c%[%SThe %s '%]", print->to.stream, f_string_eol_s[0], print->context, print->prefix, script_is ? controller_string_script_s : controller_string_program_s, print->context); + fl_print_format("%[%S%]", print->to.stream, print->notable, name, print->notable); if (status == F_control_group || status == F_limit || status == F_processor || status == F_schedule) { - fl_print_format("%[' failed due to a failure to setup the '%]", print.to.stream, print.context, print.context); - fl_print_color_before(print.notable, print.to.stream); + fl_print_format("%[' failed due to a failure to setup the '%]", print->to.stream, print->context, print->context); + fl_print_color_before(print->notable, print->to.stream); if (status == F_control_group) { - f_print_terminated(controller_string_control_group_s, print.to.stream); + f_print_terminated(controller_string_control_group_s, print->to.stream); } else if (status == F_limit) { - f_print_terminated(controller_string_limit_s, print.to.stream); + f_print_terminated(controller_string_limit_s, print->to.stream); } else if (status == F_processor) { - f_print_terminated(controller_string_processor_s, print.to.stream); + f_print_terminated(controller_string_processor_s, print->to.stream); } else if (status == F_schedule) { - f_print_terminated(controller_string_scheduler_s, print.to.stream); + f_print_terminated(controller_string_scheduler_s, print->to.stream); } - fl_print_color_after(print.notable, print.to.stream); - fl_print_format("%['.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); + fl_print_color_after(print->notable, print->to.stream); + fl_print_format("%['.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); } - else if (code) { - if (code == F_execute_file_found_not) { - fl_print_format("%[' could not be executed because it was not found.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); + else if (WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0) { + const uint8_t code = WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0; + + if (code == F_execute_access) { + fl_print_format("%[' access denied.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_bad) { + fl_print_format("%[' cannot execute, unsupported format.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_buffer) { + fl_print_format("%[' invalid memory access in arguments buffer.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_busy) { + fl_print_format("%[' required resources are unavailable, too busy.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_capability) { + fl_print_format("%[' failed to setup capabilities.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_control_group) { + fl_print_format("%[' failed to setup control group.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_child) { + fl_print_format("%[' failed to setup child process.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_directory_not) { + fl_print_format("%[' invalid path, part of the path is not a valid directory.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_failure) { + fl_print_format("%[' failed during execution.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_file_found_not) { + fl_print_format("%[' could not be executed, unable to find file.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_file_type_directory) { + fl_print_format("%[' ELF interpreter is a directory.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_fork_not) { + fl_print_format("%[' fork failure.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_format_not) { + fl_print_format("%[' could not be executed because the program has an invalid ELF header.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_group) { + fl_print_format("%[' failed to setup group.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_input_output) { + fl_print_format("%[' I/O failure.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_limit) { + fl_print_format("%[' failed to setup resource limits.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_loop) { + fl_print_format("%[' max recursion reached.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_memory_not) { + fl_print_format("%[' out of memory.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_name_not) { + fl_print_format("%[' file name or path is too long.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_nice) { + fl_print_format("%[' failed to setup niceness.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_parameter) { + fl_print_format("%[' invalid parameter.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_pipe) { + fl_print_format("%[' pipe failed.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_processor) { + fl_print_format("%[' failed to setup processor affinity.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_prohibited) { + fl_print_format("%[' access prohibited.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_resource_not) { + fl_print_format("%[' resource limit reached.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_schedule) { + fl_print_format("%[' failed to setup scheduler.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_too_large) { + fl_print_format("%[' too many arguments or arguments are too large.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_user) { + fl_print_format("%[' failed to setup user.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + } + else if (code == F_execute_valid_not) { + fl_print_format("%[' unknown ELF interpreter format.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); } else { - // @todo improve reporting of all known status codes. - fl_print_format("%[' failed with the exit code %]", print.to.stream, print.context, print.context); - fl_print_format("%[%i%]", print.to.stream, print.notable, code, print.notable); - fl_print_format("%[.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); + fl_print_format("%[' failed with the execute error code %]", print->to.stream, print->context, print->context); + fl_print_format("%[%i%]", print->to.stream, print->notable, code, print->notable); + fl_print_format("%[.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); } } else { - fl_print_format("%[' failed.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); + fl_print_format("%[' failed.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); } - controller_print_unlock_flush(print.to, thread); + controller_print_unlock_flush(print->to, (controller_thread_t *) process->main_thread); } } #endif // _di_controller_rule_item_error_print_execute_ @@ -1268,12 +1355,12 @@ extern "C" { if (process->rule.items.array[i].type == controller_rule_item_type_command) { for (;;) { - status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], 0, process->rule.items.array[i].actions.array[j].parameters, options, global, &execute_set, process); + status = controller_rule_execute_foreground(process->rule.items.array[i].type, 0, process->rule.items.array[i].actions.array[j].parameters, options, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - if (controller_rule_execute_rerun(global, controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { + if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { continue; } @@ -1298,12 +1385,12 @@ extern "C" { for (;;) { - status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, global, &execute_set, process); + status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - if (controller_rule_execute_rerun(global, controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { + if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { continue; } @@ -1327,12 +1414,12 @@ extern "C" { if (process->rule.items.array[i].pid_file.used) { for (;;) { - status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], 0, process->rule.items.array[i].actions.array[j].parameters, options, process->rule.items.array[i].with, global, &execute_set, process); + status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, 0, process->rule.items.array[i].actions.array[j].parameters, options, process->rule.items.array[i].with, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - if (controller_rule_execute_rerun(global, controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { + if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { continue; } @@ -1365,12 +1452,12 @@ extern "C" { for (;;) { - status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, process->rule.items.array[i].with, global, &execute_set, process); + status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, process->rule.items.array[i].with, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - if (controller_rule_execute_rerun(global, controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { + if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { continue; } @@ -1455,17 +1542,22 @@ extern "C" { #endif // _di_controller_rule_execute_ #ifndef _di_controller_rule_execute_foreground_ - f_status_t controller_rule_execute_foreground(const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const controller_global_t global, controller_execute_set_t * const execute_set, controller_process_t *process) { + f_status_t controller_rule_execute_foreground(const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, controller_execute_set_t * const execute_set, controller_process_t *process) { f_status_t status = F_none; f_status_t status_lock = F_none; + f_string_dynamics_t arguments_none = f_string_dynamics_t_initialize; + + controller_main_t * const main = (controller_main_t *) process->main_data; + controller_thread_t * const thread = (controller_thread_t *) process->main_thread; + f_execute_result_t result = f_execute_result_t_initialize; status = controller_pids_increase(&process->childs); if (F_status_is_error(status)) { - controller_error_print(global.main->error, F_status_set_fine(status), "controller_pids_increase", F_true, global.thread); + controller_error_print(main->error, F_status_set_fine(status), "controller_pids_increase", F_true, thread); return status; } @@ -1488,33 +1580,33 @@ extern "C" { } if (options & controller_process_option_simulate) { - if (global.main->error.verbosity != f_console_verbosity_quiet) { - controller_print_lock(global.main->output, global.thread); + if (main->error.verbosity != f_console_verbosity_quiet) { + controller_print_lock(main->output, thread); - fl_print_format("%cSimulating execution of '%[", global.main->output.stream, f_string_eol_s[0], global.main->context.set.title); + fl_print_format("%cSimulating execution of '%[", main->output.stream, f_string_eol_s[0], main->context.set.title); if (program) { - f_print_safely_terminated(program, global.main->output.stream); + f_print_safely_terminated(program, main->output.stream); } else { - f_print_dynamic_safely(arguments.array[0], global.main->output.stream); + f_print_dynamic_safely(arguments.array[0], main->output.stream); } - fl_print_format("%]' with the arguments: '%[", global.main->output.stream, global.main->context.set.title, global.main->context.set.important); + fl_print_format("%]' with the arguments: '%[", main->output.stream, main->context.set.title, main->context.set.important); for (f_array_length_t i = program ? 0 : 1; i < arguments.used; ++i) { if (program && i || !program && i > 1) { - f_print_terminated(f_string_space_s, global.main->output.stream); + f_print_terminated(f_string_space_s, main->output.stream); } - f_print_dynamic_safely(arguments.array[i], global.main->output.stream); + f_print_dynamic_safely(arguments.array[i], main->output.stream); } // for - fl_print_format("%]' from '", global.main->output.stream, global.main->context.set.important); - fl_print_format("%[%Q%]'.%c", global.main->output.stream, global.main->context.set.notable, process->rule.name, global.main->context.set.notable, f_string_eol_s[0]); + fl_print_format("%]' from '", main->output.stream, main->context.set.important); + fl_print_format("%[%Q%]'.%c", main->output.stream, main->context.set.notable, process->rule.name, main->context.set.notable, f_string_eol_s[0]); - controller_print_unlock_flush(global.main->output, global.thread); + controller_print_unlock_flush(main->output, thread); } // sleep for less than a second to better show simulation of synchronous vs asynchronous. @@ -1539,13 +1631,13 @@ extern "C" { f_thread_unlock(&process->lock); - status_lock = controller_lock_write_process(process, global.thread, &process->lock); + status_lock = controller_lock_write_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread); if (status_lock != F_signal) { - status = controller_lock_read_process(process, global.thread, &process->lock); + status = controller_lock_read_process(process, thread, &process->lock); if (status == F_none) { return status_lock; @@ -1560,10 +1652,10 @@ extern "C" { f_thread_unlock(&process->lock); - status_lock = controller_lock_read_process(process, global.thread, &process->lock); + status_lock = controller_lock_read_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread); } if (status_lock != F_signal) { @@ -1572,7 +1664,7 @@ extern "C" { waitpid(id_child, &result.status, 0); } - if (status_lock == F_signal || !controller_thread_is_enabled_process(process, global.thread)) { + if (status_lock == F_signal || !controller_thread_is_enabled_process(process, thread)) { if (status_lock == F_none) { return F_signal; } @@ -1584,13 +1676,13 @@ extern "C" { f_thread_unlock(&process->lock); } - status_lock = controller_lock_write_process(process, global.thread, &process->lock); + status_lock = controller_lock_write_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread); if (status_lock != F_signal) { - status = controller_lock_read_process(process, global.thread, &process->lock); + status = controller_lock_read_process(process, thread, &process->lock); if (status == F_none) { return status_lock; @@ -1607,10 +1699,10 @@ extern "C" { f_thread_unlock(&process->lock); - status_lock = controller_lock_read_process(process, global.thread, &process->lock); + status_lock = controller_lock_read_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread); return F_status_set_error(F_lock); } @@ -1623,9 +1715,9 @@ extern "C" { } } else { - global.main->child = result.status; + main->child = result.status; - if (!controller_thread_is_enabled_process(process, global.thread)) { + if (!controller_thread_is_enabled_process(process, thread)) { return F_signal; } } @@ -1649,10 +1741,10 @@ extern "C" { status = F_status_set_fine(status); if ((WIFEXITED(process->result) && WEXITSTATUS(process->result)) || status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) { - controller_rule_item_error_print_execute(global.main->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0, status, global.thread); + controller_rule_item_error_print_execute(type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process); } else { - controller_error_print(global.main->error, F_status_set_fine(status), "fll_execute_program", F_true, global.thread); + controller_error_print(main->error, F_status_set_fine(status), "fll_execute_program", F_true, thread); } status = F_status_set_error(status); @@ -1663,17 +1755,20 @@ extern "C" { #endif // _di_controller_rule_execute_foreground_ #ifndef _di_controller_rule_execute_pid_with_ - f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const uint8_t with, const controller_global_t global, controller_execute_set_t * const execute_set, controller_process_t *process) { + f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, const uint8_t with, controller_execute_set_t * const execute_set, controller_process_t *process) { f_status_t status = F_none; f_status_t status_lock = F_none; + controller_main_t * const main = (controller_main_t *) process->main_data; + controller_thread_t * const thread = (controller_thread_t *) process->main_thread; + f_execute_result_t result = f_execute_result_t_initialize; status = controller_pids_increase(&process->childs); if (F_status_is_error(status)) { - controller_error_print(global.main->error, F_status_set_fine(status), "controller_pids_increase", F_true, global.thread); + controller_error_print(main->error, F_status_set_fine(status), "controller_pids_increase", F_true, thread); return status; } @@ -1681,7 +1776,7 @@ extern "C" { status = f_string_dynamics_increase(controller_common_allocation_small, &process->path_pids); if (F_status_is_error(status)) { - controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread); + controller_error_print(main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, thread); return status; } @@ -1716,13 +1811,13 @@ extern "C" { status = f_file_exists(pid_file.string); if (F_status_is_error(status)) { - controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, global.thread); + controller_error_file_print(main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, thread); return status; } if (status == F_true) { - controller_error_file_print(global.main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, global.thread); + controller_error_file_print(main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, thread); return F_status_set_error(F_file_found); } @@ -1730,39 +1825,39 @@ extern "C" { status = controller_string_dynamic_append_terminated(pid_file, child_pid_file); if (F_status_is_error(status)) { - controller_error_print(global.main->error, F_status_set_fine(status), "controller_string_dynamic_append_terminated", F_true, global.thread); + controller_error_print(main->error, F_status_set_fine(status), "controller_string_dynamic_append_terminated", F_true, thread); return status; } if (options & controller_process_option_simulate) { - if (global.main->error.verbosity != f_console_verbosity_quiet) { - controller_print_lock(global.main->error.to, global.thread); + if (main->error.verbosity != f_console_verbosity_quiet) { + controller_print_lock(main->error.to, thread); - fl_print_format("%cSimulating execution of '%[", global.main->error.to.stream, f_string_eol_s[0], global.main->context.set.title); + fl_print_format("%cSimulating execution of '%[", main->error.to.stream, f_string_eol_s[0], main->context.set.title); if (program) { - f_print_safely_terminated(program, global.main->error.to.stream); + f_print_safely_terminated(program, main->error.to.stream); } else { - f_print_dynamic_safely(arguments.array[0], global.main->error.to.stream); + f_print_dynamic_safely(arguments.array[0], main->error.to.stream); } - fl_print_format("%]' with the arguments: '%[", global.main->error.to.stream, global.main->context.set.title, global.main->context.set.important); + fl_print_format("%]' with the arguments: '%[", main->error.to.stream, main->context.set.title, main->context.set.important); for (f_array_length_t i = program ? 0 : 1; i < arguments.used; ++i) { if (program && i || !program && i > 1) { - f_print_terminated(f_string_space_s, global.main->error.to.stream); + f_print_terminated(f_string_space_s, main->error.to.stream); } - f_print_dynamic_safely(arguments.array[i], global.main->error.to.stream); + f_print_dynamic_safely(arguments.array[i], main->error.to.stream); } // for - fl_print_format("%]' from '", global.main->error.to.stream, global.main->context.set.important); - fl_print_format("%[%Q%]'.%c", global.main->error.to.stream, global.main->context.set.notable, process->rule.name, global.main->context.set.notable, f_string_eol_s[0]); + fl_print_format("%]' from '", main->error.to.stream, main->context.set.important); + fl_print_format("%[%Q%]'.%c", main->error.to.stream, main->context.set.notable, process->rule.name, main->context.set.notable, f_string_eol_s[0]); - controller_print_unlock_flush(global.main->error.to, global.thread); + controller_print_unlock_flush(main->error.to, thread); } // sleep for less than a second to better show simulation of synchronous vs asynchronous. @@ -1787,13 +1882,13 @@ extern "C" { f_thread_unlock(&process->lock); - status_lock = controller_lock_write_process(process, global.thread, &process->lock); + status_lock = controller_lock_write_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread); if (status_lock != F_signal) { - status = controller_lock_read_process(process, global.thread, &process->lock); + status = controller_lock_read_process(process, thread, &process->lock); if (status == F_none) { return status_lock; @@ -1808,10 +1903,10 @@ extern "C" { f_thread_unlock(&process->lock); - status_lock = controller_lock_read_process(process, global.thread, &process->lock); + status_lock = controller_lock_read_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread); } if (status_lock != F_signal) { @@ -1820,7 +1915,7 @@ extern "C" { waitpid(id_child, &result.status, 0); } - if (!controller_thread_is_enabled_process(process, global.thread)) { + if (!controller_thread_is_enabled_process(process, thread)) { if (status_lock == F_none) { return F_signal; } @@ -1832,13 +1927,13 @@ extern "C" { f_thread_unlock(&process->lock); } - status_lock = controller_lock_write_process(process, global.thread, &process->lock); + status_lock = controller_lock_write_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread); if (status_lock != F_signal) { - status = controller_lock_read_process(process, global.thread, &process->lock); + status = controller_lock_read_process(process, thread, &process->lock); if (status == F_none) { return status_lock; @@ -1855,10 +1950,10 @@ extern "C" { f_thread_unlock(&process->lock); - status_lock = controller_lock_read_process(process, global.thread, &process->lock); + status_lock = controller_lock_read_process(process, thread, &process->lock); if (status_lock == F_signal || F_status_is_error(status_lock)) { - controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); + controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread); return F_status_set_error(F_lock); } @@ -1871,9 +1966,9 @@ extern "C" { } } else { - global.main->child = result.status; + main->child = result.status; - if (!controller_thread_is_enabled_process(process, global.thread)) { + if (!controller_thread_is_enabled_process(process, thread)) { return F_signal; } } @@ -1897,10 +1992,10 @@ extern "C" { status = F_status_set_fine(status); if ((WIFEXITED(process->result) && WEXITSTATUS(process->result)) || status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) { - controller_rule_item_error_print_execute(global.main->error, type == controller_rule_item_type_utility, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0, status, global.thread); + controller_rule_item_error_print_execute(type == controller_rule_item_type_utility, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process); } else { - controller_error_print(global.main->error, F_status_set_fine(status), "fll_execute_program", F_true, global.thread); + controller_error_print(main->error, F_status_set_fine(status), "fll_execute_program", F_true, thread); } return F_status_set_error(status); @@ -1911,41 +2006,43 @@ extern "C" { #endif // _di_controller_rule_execute_pid_with_ #ifndef _di_controller_rule_execute_rerun_ - int8_t controller_rule_execute_rerun(const controller_global_t global, const uint8_t action, controller_process_t *process, controller_rule_item_t *item) { + int8_t controller_rule_execute_rerun(const uint8_t action, controller_process_t *process, controller_rule_item_t *item) { const int result = WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0; if (item->reruns[action].is & (result ? controller_rule_rerun_is_failure : controller_rule_rerun_is_success)) { + controller_main_t * const main = (controller_main_t *) process->main_data; + controller_thread_t * const thread = (controller_thread_t *) process->main_thread; controller_rule_rerun_item_t *rerun_item = result ? &item->reruns[action].failure : &item->reruns[action].success; - if (!controller_thread_is_enabled_process(process, global.thread)) return -2; + if (!controller_thread_is_enabled_process(process, thread)) return -2; if (!rerun_item->max || rerun_item->count < rerun_item->max) { - if (global.main->error.verbosity == f_console_verbosity_debug) { - controller_print_lock(global.main->output, global.thread); - - fl_print_format("%cRe-running '", global.main->output.stream, f_string_eol_s[0]); - fl_print_format("%[%q%]", global.main->output.stream, global.main->context.set.title, process->rule.alias, global.main->context.set.title); - f_print_terminated("' '", global.main->output.stream); - fl_print_format("%[%q%]", global.main->output.stream, global.main->context.set.notable, controller_rule_action_type_execute_name(action), global.main->context.set.notable); - f_print_terminated("' with a ", global.main->output.stream); - fl_print_format("%[%s%]", global.main->output.stream, global.main->context.set.notable, controller_string_delay_s, global.main->context.set.notable); - f_print_terminated(" of ", global.main->output.stream); - fl_print_format("%[%ul%] MegaTime", global.main->output.stream, global.main->context.set.notable, rerun_item->delay, global.main->context.set.notable); + if (main->error.verbosity == f_console_verbosity_debug) { + controller_print_lock(main->output, thread); + + fl_print_format("%cRe-running '", main->output.stream, f_string_eol_s[0]); + fl_print_format("%[%q%]", main->output.stream, main->context.set.title, process->rule.alias, main->context.set.title); + f_print_terminated("' '", main->output.stream); + fl_print_format("%[%q%]", main->output.stream, main->context.set.notable, controller_rule_action_type_execute_name(action), main->context.set.notable); + f_print_terminated("' with a ", main->output.stream); + fl_print_format("%[%s%]", main->output.stream, main->context.set.notable, controller_string_delay_s, main->context.set.notable); + f_print_terminated(" of ", main->output.stream); + fl_print_format("%[%ul%] MegaTime", main->output.stream, main->context.set.notable, rerun_item->delay, main->context.set.notable); if (rerun_item->max) { - f_print_terminated(" for ", global.main->output.stream); - fl_print_format("%[%ul%]", global.main->output.stream, global.main->context.set.notable, rerun_item->count, global.main->context.set.notable); - f_print_terminated(" of ", global.main->output.stream); - fl_print_format("%[%s%] ", global.main->output.stream, global.main->context.set.notable, controller_string_max_s, global.main->context.set.notable); - fl_print_format("%[%ul%]", global.main->output.stream, global.main->context.set.notable, rerun_item->max, global.main->context.set.notable); - fl_print_format(".%c", global.main->output.stream, f_string_eol_s[0]); + f_print_terminated(" for ", main->output.stream); + fl_print_format("%[%ul%]", main->output.stream, main->context.set.notable, rerun_item->count, main->context.set.notable); + f_print_terminated(" of ", main->output.stream); + fl_print_format("%[%s%] ", main->output.stream, main->context.set.notable, controller_string_max_s, main->context.set.notable); + fl_print_format("%[%ul%]", main->output.stream, main->context.set.notable, rerun_item->max, main->context.set.notable); + fl_print_format(".%c", main->output.stream, f_string_eol_s[0]); } else { - fl_print_format(" with no %[%s%].%c", global.main->output.stream, global.main->context.set.notable, controller_string_max_s, global.main->context.set.notable, f_string_eol_s[0]); + fl_print_format(" with no %[%s%].%c", main->output.stream, main->context.set.notable, controller_string_max_s, main->context.set.notable, f_string_eol_s[0]); } - controller_print_unlock_flush(global.main->output, global.thread); + controller_print_unlock_flush(main->output, thread); } if (rerun_item->delay) { @@ -1955,7 +2052,7 @@ extern "C" { return -1; } - if (!controller_thread_is_enabled_process(process, global.thread)) return -2; + if (!controller_thread_is_enabled_process(process, thread)) return -2; } if (item->reruns[action].is & (result ? controller_rule_rerun_is_failure_reset : controller_rule_rerun_is_success_reset)) { diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h index 45594e3..2d3f311 100644 --- a/level_3/controller/c/private-rule.h +++ b/level_3/controller/c/private-rule.h @@ -296,8 +296,6 @@ extern "C" { /** * Print an error or warning message related to the failed execution of some program or script. * - * @param print - * The error or warning output structure. * @param script_is * If TRUE, then this represents a script. * If FALSE, then this represents a program. @@ -307,11 +305,11 @@ extern "C" { * The code returned by the executed program or script. * @param status * The status code representing the failure (without the error bit set). - * @param thread - * The thread data. + * @param process + * The process to use. */ #ifndef _di_controller_rule_item_error_print_execute_ - extern void controller_rule_item_error_print_execute(const fll_error_print_t print, const bool script_is, const f_string_t name, const int code, const f_status_t status, controller_thread_t * const thread) f_attribute_visibility_internal; + extern void controller_rule_item_error_print_execute(const bool script_is, const f_string_t name, const f_status_t status, controller_process_t * const process) f_attribute_visibility_internal; #endif // _di_controller_rule_item_error_print_execute_ /** @@ -402,16 +400,7 @@ extern "C" { * This requires that a read lock be set on process->lock before being called. * * @param type - * The item type ID. - * @param action - * The action to perform based on the action type codes. - * - * Only subset of the action type codes are supported: - * - controller_rule_action_type_kill - * - controller_rule_action_type_reload - * - controller_rule_action_type_restart - * - controller_rule_action_type_start - * - controller_rule_action_type_stop + * The item type code. * @param program * The program to use (such as "bash"). * @param arguments @@ -419,8 +408,6 @@ extern "C" { * @param options * Process options to consider when executing. * If bit controller_process_option_simulate, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). - * @param global - * The global data. * @param execute_set * The execute parameter and as settings. * @param process @@ -438,7 +425,7 @@ extern "C" { * @see fll_execute_program() */ #ifndef _di_controller_rule_execute_foreground_ - extern f_status_t controller_rule_execute_foreground(const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const controller_global_t global, controller_execute_set_t * const execute_set, controller_process_t *process) f_attribute_visibility_internal; + extern f_status_t controller_rule_execute_foreground(const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, controller_execute_set_t * const execute_set, controller_process_t *process) f_attribute_visibility_internal; #endif // _di_controller_rule_execute_foreground_ /** @@ -453,15 +440,6 @@ extern "C" { * The path to the PID file. * @param type * The item type code. - * @param action - * The action to perform based on the action type codes. - * - * Only subset of the action type codes are supported: - * - controller_rule_action_type_kill - * - controller_rule_action_type_reload - * - controller_rule_action_type_restart - * - controller_rule_action_type_start - * - controller_rule_action_type_stop * @param program * The program to use (such as "bash"). * @param arguments @@ -471,8 +449,6 @@ extern "C" { * If bit controller_process_option_simulate, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). * @param with * The "with" option flags. - * @param global - * The global data. * @param execute_set * The execute parameter and as settings. * @param process @@ -491,14 +467,12 @@ extern "C" { * @see fll_execute_program() */ #ifndef _di_controller_rule_execute_pid_with_ - extern f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const uint8_t with, const controller_global_t global, controller_execute_set_t * const execute_set, controller_process_t *process) f_attribute_visibility_internal; + extern f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, const uint8_t with, controller_execute_set_t * const execute_set, controller_process_t *process) f_attribute_visibility_internal; #endif // _di_controller_rule_execute_pid_with_ /** * Determine whether or not an execute rule should be re-run, applying a delay as requested. * - * @param global - * The global data. * @param action * The action type. * @param process @@ -516,7 +490,7 @@ extern "C" { * -2 to designate exit due to signal/disabled thread. */ #ifndef _di_controller_rule_execute_rerun_ - extern int8_t controller_rule_execute_rerun(const controller_global_t global, const uint8_t action, controller_process_t *process, controller_rule_item_t *item) f_attribute_visibility_internal; + extern int8_t controller_rule_execute_rerun(const uint8_t action, controller_process_t *process, controller_rule_item_t *item) f_attribute_visibility_internal; #endif // _di_controller_rule_execute_rerun_ /** diff --git a/level_3/controller/c/private-thread.c b/level_3/controller/c/private-thread.c index 24e08ed..05df9d1 100644 --- a/level_3/controller/c/private-thread.c +++ b/level_3/controller/c/private-thread.c @@ -363,7 +363,7 @@ extern "C" { controller_main_delete(main); // According to the manpages, pthread_exit() calls exit(0), which is not good because a non-zero exit code may be returned. - exit(main->child); + if (main->child) exit(main->child); } } #endif // _di_controller_thread_process_ @@ -803,10 +803,8 @@ extern "C" { controller_setting_delete_simple(entry->global->setting); controller_main_delete(entry->global->main); - const int code = main->child; - // According to the manpages, pthread_exit() calls exit(0), which is not good because a non-zero exit code may be returned. - exit(main->child); + if (main->child) exit(main->child); return 0; }