From: Kevin Day Date: Tue, 5 Jul 2022 15:34:35 +0000 (-0500) Subject: Update: The "engine" rule setting should support parameters. X-Git-Tag: 0.6.0~84 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=d53d0ffefa099891e9bb827e0a114e0d1aad89c4;p=fll Update: The "engine" rule setting should support parameters. --- diff --git a/level_3/controller/c/common/private-rule.c b/level_3/controller/c/common/private-rule.c index ecd60b1..b25b9d3 100644 --- a/level_3/controller/c/common/private-rule.c +++ b/level_3/controller/c/common/private-rule.c @@ -64,6 +64,7 @@ extern "C" { f_string_maps_resize(0, &rule->define); f_string_maps_resize(0, &rule->parameter); + f_string_dynamics_resize(0, &rule->engine_arguments); f_string_dynamics_resize(0, &rule->environment); macro_f_int32s_t_delete_simple(rule->affinity) diff --git a/level_3/controller/c/common/private-rule.h b/level_3/controller/c/common/private-rule.h index d454a92..fc95573 100644 --- a/level_3/controller/c/common/private-rule.h +++ b/level_3/controller/c/common/private-rule.h @@ -261,21 +261,22 @@ extern "C" { * A Rule. * * controller_rule_setting_type_*: - * - affinity: Setting type representing a affinity. - * - capability: Setting type representing a capability. - * - cgroup: Setting type representing a control group. - * - define: Setting type representing a define. - * - engine: Setting type representing a engine. - * - environment: Setting type representing a environment. - * - group: Setting type representing a group. - * - limit: Setting type representing a limit. - * - name: Setting type representing a name. - * - nice: Setting type representing a nice. - * - on: Setting type representing a on. - * - parameter: Setting type representing a parameter. - * - path: Setting type representing a path. - * - scheduler: Setting type representing a scheduler. - * - user: Setting type representing a user. + * - affinity: Setting type representing a affinity. + * - capability: Setting type representing a capability. + * - cgroup: Setting type representing a control group. + * - define: Setting type representing a define. + * - engine: Setting type representing a engine. + * - engine_arguments: Setting type representing a engine. + * - environment: Setting type representing a environment. + * - group: Setting type representing a group. + * - limit: Setting type representing a limit. + * - name: Setting type representing a name. + * - nice: Setting type representing a nice. + * - on: Setting type representing a on. + * - parameter: Setting type representing a parameter. + * - path: Setting type representing a path. + * - scheduler: Setting type representing a scheduler. + * - user: Setting type representing a user. * * controller_rule_has_*: * - cgroup: Has type representing a control group. @@ -284,30 +285,31 @@ extern "C" { * - scheduler: Has type representing a scheduler. * - user: Has type representing a user. * - * affinity: The cpu affinity to be used when executing the Rule. - * alias: The distinct ID (machine name) of the Rule, such as "service/ssh". - * capability: The capability setting if the Rule "has" a capability. - * cgroup: The control group setting if the Rule "has" a control group. - * define: Any defines (environment variables) made available to the Rule for IKI substitution or just as environment variables. - * engine: The program or path to the program of the scripting engine to use when processing scripts in this Rule. - * environment: All environment variables allowed to be exposed to the Rule when processing. - * group: The group ID if the Rule "has" a group. - * groups: A set of group IDs to run the process with (first specified group is the primary group). - * has: Bitwise set of "has" codes representing what the Rule has. - * items: All items associated with the Rule. - * limits: The cpu/resource limits to use when executing the Rule. - * name: A human name for the Rule (does not have to be distinct), such as "Bash Script". - * nice: The niceness value if the Rule "has" nice. - * on: A set of parameters for defining dependencies and how they are needed, wanted, or wished for. - * parameter: Any parameters made available to the Rule for IKI substitution. - * path: The path to the Rule file. - * scheduler: The scheduler setting if the Rule "has" a scheduler. - * status: A set of action-specific success/failure status of the Rule. Each index represents a controller_rule_action_type_* enum value. Index 0 represents a global status. - * timeout_kill: The timeout to wait relating to using a kill signal. - * timeout_start: The timeout to wait relating to starting a process. - * timeout_stop: The timeout to wait relating to stopping a process. - * timestamp: The timestamp when the Rule was loaded. - * user: The User ID if the Rule "has" a user. + * affinity: The cpu affinity to be used when executing the Rule. + * alias: The distinct ID (machine name) of the Rule, such as "service/ssh". + * capability: The capability setting if the Rule "has" a capability. + * cgroup: The control group setting if the Rule "has" a control group. + * define: Any defines (environment variables) made available to the Rule for IKI substitution or just as environment variables. + * engine: The program or path to the program of the scripting engine to use when processing scripts in this Rule. + * engine_arguments: Any arguments to pass to the engine program. + * environment: All environment variables allowed to be exposed to the Rule when processing. + * group: The group ID if the Rule "has" a group. + * groups: A set of group IDs to run the process with (first specified group is the primary group). + * has: Bitwise set of "has" codes representing what the Rule has. + * items: All items associated with the Rule. + * limits: The cpu/resource limits to use when executing the Rule. + * name: A human name for the Rule (does not have to be distinct), such as "Bash Script". + * nice: The niceness value if the Rule "has" nice. + * on: A set of parameters for defining dependencies and how they are needed, wanted, or wished for. + * parameter: Any parameters made available to the Rule for IKI substitution. + * path: The path to the Rule file. + * scheduler: The scheduler setting if the Rule "has" a scheduler. + * status: A set of action-specific success/failure status of the Rule. Each index represents a controller_rule_action_type_* enum value. Index 0 represents a global status. + * timeout_kill: The timeout to wait relating to using a kill signal. + * timeout_start: The timeout to wait relating to starting a process. + * timeout_stop: The timeout to wait relating to stopping a process. + * timestamp: The timestamp when the Rule was loaded. + * user: The User ID if the Rule "has" a user. */ #ifndef _di_controller_rule_t_ enum { @@ -364,6 +366,7 @@ extern "C" { f_string_maps_t define; f_string_maps_t parameter; + f_string_dynamics_t engine_arguments; f_string_dynamics_t environment; f_int32s_t affinity; @@ -410,6 +413,7 @@ extern "C" { f_string_maps_t_initialize, \ f_string_maps_t_initialize, \ f_string_dynamics_t_initialize, \ + f_string_dynamics_t_initialize, \ f_int32s_t_initialize, \ f_capability_t_initialize, \ f_control_group_t_initialize, \ diff --git a/level_3/controller/c/rule/private-rule.c b/level_3/controller/c/rule/private-rule.c index 1ca1958..65b7adf 100644 --- a/level_3/controller/c/rule/private-rule.c +++ b/level_3/controller/c/rule/private-rule.c @@ -765,6 +765,7 @@ extern "C" { destination->alias.used = 0; destination->engine.used = 0; + destination->engine_arguments.used = 0; destination->name.used = 0; destination->path.used = 0; @@ -778,13 +779,21 @@ extern "C" { destination->scheduler.policy = source.scheduler.policy; destination->scheduler.priority = source.scheduler.priority; - for (f_array_length_t i = 0; i < destination->ons.size; ++i) { + { + f_array_length_t i = 0; - destination->ons.array[i].action = 0; - destination->ons.array[i].need.used = 0; - destination->ons.array[i].want.used = 0; - destination->ons.array[i].wish.used = 0; - } // for + for (; i < destination->ons.size; ++i) { + + destination->ons.array[i].action = 0; + destination->ons.array[i].need.used = 0; + destination->ons.array[i].want.used = 0; + destination->ons.array[i].wish.used = 0; + } // for + + for (i = 0; i < destination->engine_arguments.size; ++i) { + destination->engine_arguments.array[i].used = 0; + } // for + } destination->ons.used = 0; destination->items.used = 0; @@ -809,6 +818,9 @@ extern "C" { status = f_string_maps_append_all(source.parameter, &destination->parameter); if (F_status_is_error(status)) return status; + status = f_string_dynamics_append_all(source.engine_arguments, &destination->engine_arguments); + if (F_status_is_error(status)) return status; + status = f_string_dynamics_append_all(source.environment, &destination->environment); if (F_status_is_error(status)) return status; @@ -1128,10 +1140,10 @@ extern "C" { do { if (process->rule.engine.used) { - status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.engine, arguments_none, options, &execute_set, process); + status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.engine, process->rule.engine_arguments, options, &execute_set, process); } else { - status = controller_rule_execute_foreground(process->rule.items.array[i].type, *global.main->default_engine, arguments_none, options, &execute_set, process); + status = controller_rule_execute_foreground(process->rule.items.array[i].type, *global.main->default_engine, process->rule.engine_arguments, options, &execute_set, process); } if (status == F_child || F_status_set_fine(status) == F_lock) break; @@ -1207,7 +1219,7 @@ extern "C" { } do { - status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.engine.used ? process->rule.engine : *global.main->default_engine, arguments_none, options, process->rule.items.array[i].with, &execute_set, process); + status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.engine.used ? process->rule.engine : *global.main->default_engine, process->rule.engine_arguments, options, process->rule.items.array[i].with, &execute_set, process); if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; @@ -1362,10 +1374,9 @@ extern "C" { } if (F_status_set_fine(status) != F_interrupt) { - const f_string_statics_t simulated_arguments = f_string_statics_t_initialize; fl_execute_parameter_t simulated_parameter = macro_fl_execute_parameter_t_initialize(execute_set->parameter.option, execute_set->parameter.wait, process->rule.has & controller_rule_has_environment_d ? execute_set->parameter.environment : 0, execute_set->parameter.signals, &f_string_empty_s); - status = fll_execute_program(*main->default_engine, simulated_arguments, &simulated_parameter, &execute_set->as, (void *) &result); + status = fll_execute_program(*main->default_engine, process->rule.engine_arguments, &simulated_parameter, &execute_set->as, (void *) &result); } } else { @@ -3480,10 +3491,6 @@ extern "C" { bool for_item = F_true; - for (f_array_length_t i = 0; i < controller_rule_action_type__enum_size_e; ++i) { - rule->status[i] = F_known_not; - } // for - rule->timeout_kill = entry->timeout_kill ? entry->timeout_kill : 0; rule->timeout_start = entry->timeout_start ? entry->timeout_start : 0; rule->timeout_stop = entry->timeout_stop ? entry->timeout_stop : 0; @@ -3497,6 +3504,7 @@ extern "C" { rule->alias.used = 0; rule->engine.used = 0; + rule->engine_arguments.used = 0; rule->name.used = 0; rule->path.used = 0; @@ -3511,10 +3519,6 @@ extern "C" { rule->capability = 0; } - for (f_array_length_t i = 0; i < rule->cgroup.groups.size; ++i) { - rule->cgroup.groups.array[i].used = 0; - } // for - rule->cgroup.as_new = F_false; rule->cgroup.path.used = 0; rule->cgroup.groups.used = 0; @@ -3527,12 +3531,6 @@ extern "C" { rule->scheduler.policy = 0; rule->scheduler.priority = 0; - for (f_array_length_t i = 0; i < rule->ons.size; ++i) { - rule->ons.array[i].need.used = 0; - rule->ons.array[i].want.used = 0; - rule->ons.array[i].wish.used = 0; - } // for - rule->ons.used = 0; rule->items.used = 0; @@ -3549,10 +3547,6 @@ extern "C" { cache->buffer_item.used = 0; cache->buffer_path.used = 0; - for (f_array_length_t i = 0; i < cache->content_items.used; ++i) { - cache->content_items.array[i].used = 0; - } // for - cache->content_items.used = 0; cache->object_items.used = 0; @@ -3560,6 +3554,32 @@ extern "C" { cache->action.name_file.used = 0; cache->action.name_item.used = 0; + { + f_array_length_t i = 0; + + for (i = 0; i < rule->cgroup.groups.size; ++i) { + rule->cgroup.groups.array[i].used = 0; + } // for + + for (; i < controller_rule_action_type__enum_size_e; ++i) { + rule->status[i] = F_known_not; + } // for + + for (i = 0; i < cache->content_items.used; ++i) { + cache->content_items.array[i].used = 0; + } // for + + for (i = 0; i < rule->engine_arguments.size; ++i) { + rule->engine_arguments.array[i].used = 0; + } // for + + for (i = 0; i < rule->ons.size; ++i) { + rule->ons.array[i].need.used = 0; + rule->ons.array[i].want.used = 0; + rule->ons.array[i].wish.used = 0; + } // for + } + status = f_string_dynamic_append_nulless(alias, &rule->alias); if (F_status_is_error(status)) { @@ -4422,8 +4442,8 @@ extern "C" { setting_value = &rule->engine; } - if (setting_value->used || cache->content_actions.array[i].used != 1) { - controller_rule_setting_read_print_error(global.main->error, "requires exactly one Content", i, line_item, global.thread, cache); + if (setting_value->used || !cache->content_actions.array[i].used) { + controller_rule_setting_read_print_error(global.main->error, "requires one or more Content", i, line_item, global.thread, cache); if (F_status_is_error_not(status_return)) { status_return = F_status_set_error(F_valid_not); @@ -4435,9 +4455,28 @@ extern "C" { if (type == controller_rule_setting_type_name_e || type == controller_rule_setting_type_engine_e) { status = fl_string_dynamic_partial_rip_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value); + if (type == controller_rule_setting_type_engine_e) { + rule->engine_arguments.used = 0; + + if (cache->content_actions.array[i].used > 1) { + status = f_string_dynamics_increase_by(cache->content_actions.array[i].used - 1, &rule->engine_arguments); + + for (j = 1; F_status_is_error_not(status) && j < cache->content_actions.array[i].used; ++j, ++rule->engine_arguments.used) { + + rule->engine_arguments.array[rule->engine_arguments.used].used = 0; + + status = f_string_dynamic_partial_append(cache->buffer_item, cache->content_actions.array[i].array[j], &rule->engine_arguments.array[rule->engine_arguments.used]); + } // for + } + } + if (F_status_is_error(status)) { setting_value->used = 0; + if (type == controller_rule_setting_type_engine_e) { + rule->engine_arguments.used = 0; + } + if (F_status_set_fine(status) == F_memory_not) { status_return = status; @@ -4448,7 +4487,7 @@ extern "C" { status_return = status; } - // get the current line number within the settings item. + // Get the current line number within the settings item. cache->action.line_item = line_item; f_fss_count_lines(state, cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); @@ -4464,7 +4503,7 @@ extern "C" { if (status == F_false || F_status_set_fine(status) == F_complete_not_utf) { if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - // get the current line number within the settings item. + // Get the current line number within the settings item. cache->action.line_item = line_item; f_fss_count_lines(state, cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); @@ -5614,7 +5653,21 @@ extern "C" { f_print_dynamic_raw(f_string_eol_s, main->output.to.stream); // Engine. - fl_print_format(" %[%r%] %Q%r", main->output.to.stream, main->context.set.important, controller_engine_s, main->context.set.important, rule.engine, f_string_eol_s); + if (rule.engine_arguments.used) { + fl_print_format(" %[%r%] %Q", main->output.to.stream, main->context.set.important, controller_engine_s, main->context.set.important, rule.engine); + + for (i = 0; i < rule.engine_arguments.used; ++i) { + + if (rule.engine_arguments.array[i].used) { + fl_print_format(" %Q", main->output.to.stream, rule.engine_arguments.array[i]); + } + } // for + + fl_print_format("%r", main->output.to.stream, f_string_eol_s); + } + else { + fl_print_format(" %[%r%] %Q%r", main->output.to.stream, main->context.set.important, controller_engine_s, main->context.set.important, rule.engine, f_string_eol_s); + } // User. fl_print_format(" %[%r%]", main->output.to.stream, main->context.set.important, controller_user_s, main->context.set.important); diff --git a/level_3/controller/documents/rule.txt b/level_3/controller/documents/rule.txt index 4c6040d..be2c1b2 100644 --- a/level_3/controller/documents/rule.txt +++ b/level_3/controller/documents/rule.txt @@ -49,6 +49,7 @@ Rule Documentation: - In the case of "engine"\: This engine is used for both "script" and "utility" Rule Types. The program that engine refers to must accept a standard input pipe to be supported. + Additional parameters may be passed to the engine. - In the case of "group" and "user"\: Only users and groups that the user the controller program is being run as is allowed to use may be used. diff --git a/level_3/controller/specifications/rule.txt b/level_3/controller/specifications/rule.txt index b4b52d7..e1490bb 100644 --- a/level_3/controller/specifications/rule.txt +++ b/level_3/controller/specifications/rule.txt @@ -36,7 +36,7 @@ Rule Specification: - "capability": One Content representing capabilities. - "cgroup": Two or more Content, the first Content being either "existing" or "new" and the remaining representing a valid cgroup (control group) name, must have at least 1 graph character (non white space printing character) (leading and trailing white space are trimmed off). - "define": Two Content, the first Content must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits). - - "engine": One Content representing a valid program name or path (such as "bash" or "/bin/bash"). + - "engine": One or more Content representing a valid program name or path (such as "bash" or "/bin/bash") and any optional arguments. - "environment": Zero or more Content, each must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits). - "group": One or more Content representing group names or group ids. - "limit": Three Content, with the first representing a valid resource type and the second and third being a valid resource limit number (positive whole number or 0).