]> Kevux Git Server - controller/commitdiff
Update: Finish implementing control file and init file support.
authorKevin Day <Kevin@kevux.org>
Sat, 22 Nov 2025 03:49:24 +0000 (21:49 -0600)
committerKevin Day <Kevin@kevux.org>
Sat, 22 Nov 2025 05:21:30 +0000 (23:21 -0600)
Make sure the content and object items cache is not cleared when using a control file or init file.

The rule needs to skip past both the rule prefix and the rule alias when processing the control file or init file.

Remove no longer used `_support_controller_initfile_` from the defines documentation

Add new parameter `-f`/`--file` for specifying the controlfile or initfile.

12 files changed:
data/build/defines
sources/c/program/controller/controller/main.c
sources/c/program/controller/init/main.c
sources/c/program/controller/main/common.c
sources/c/program/controller/main/common/enumeration.h
sources/c/program/controller/main/common/string.c
sources/c/program/controller/main/common/string.h
sources/c/program/controller/main/common/type.c
sources/c/program/controller/main/common/type.h
sources/c/program/controller/main/file.c
sources/c/program/controller/main/print/message.c
sources/c/program/controller/main/rule/read.c

index 7fccb9f21afecb3a9b8ab2b71bbb2511a85b6e41..2cb15af3fa7dabad1c05ea46788440fb4cc54316 100644 (file)
@@ -6,7 +6,6 @@ _di_thread_support_ Disables thread support.
 _libcap_legacy_only_ Disable functionality provided by later versions of libcap (2.43 and later).
 
 _support_controller_controlfile_ Enable support for the controlfile by the controller program and library.
-_support_controller_initfile_    Enable support for the initfile by the init program (requires _support_controller_controlfile_).
 
 _override_controller_default_engine_     Provide a custom scripting engine name string to execute (such as php).
 _override_controller_path_pid_           Use this as the default custom directory path representing the location of the controller program pid.
index 3299c3f57c7e696ebdd6a76374d701e68cd6b651..5121a1372602d3a3dd82de7c658f589c2efaa725 100644 (file)
@@ -25,6 +25,10 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
   data.program.parameters.used = controller_parameter_total_d;
   data.program.environment = envp;
 
+  #ifdef _support_controller_controlfile_
+    data.program.parameters.array[controller_parameter_file_e].flag &= ~f_console_flag_disable_d;
+  #endif // _support_controller_controlfile_
+
   if (f_pipe_input_exists()) {
     data.program.pipe = fll_program_data_pipe_input_e;
   }
@@ -41,7 +45,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
     controller_setting_load(arguments, &data);
 
     #ifdef _support_controller_controlfile_
-      if (f_file_exists(controller_controlfile_s, F_false) == F_true) {
+      if (f_file_exists(data.setting.path_controlfile, F_false) == F_true) {
         data.setting.flag |= controller_main_flag_single_d;
       }
     #endif // _support_controller_controlfile_
index 343a2aa1eb8bbe05021eca7f713303c07932fd58..19f7ffb61f438694adbbce9e2f8a94dc96979b7d 100644 (file)
@@ -21,6 +21,10 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
   data.program.parameters.used = controller_parameter_total_d;
   data.program.environment = envp;
 
+  #ifdef _support_controller_controlfile_
+    data.program.parameters.array[controller_parameter_file_e].flag &= ~f_console_flag_disable_d;
+  #endif // _support_controller_controlfile_
+
   if (f_pipe_input_exists()) {
     data.program.pipe = fll_program_data_pipe_input_e;
   }
@@ -44,7 +48,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
     controller_setting_load(arguments, &data);
 
     #ifdef _support_controller_controlfile_
-      if (f_file_exists(controller_controlfile_s, F_false) == F_true) {
+      if (f_file_exists(data.setting.path_controlfile, F_false) == F_true) {
         data.setting.flag |= controller_main_flag_single_d;
       }
     #endif // _support_controller_controlfile_
index 673682ecfcf57074e75765157e94b1c3eabe20ef..f12e056838210ef24d9027840f0cf540d1998ee5 100644 (file)
@@ -167,7 +167,7 @@ extern "C" {
 
       for (index = 0; index < 4; ++index) {
 
-        if (main->program.parameters.array[codes[index]].result & f_console_result_found_d) {
+        if (main->program.parameters.array[codes[index]].result & f_console_result_value_d) {
           if (main->program.parameters.array[codes[index]].locations.used != main->program.parameters.array[codes[index]].values.used) {
             main->setting.state.status = F_status_set_error(F_parameter);
 
@@ -176,7 +176,7 @@ extern "C" {
             continue;
           }
         }
-        else if (main->program.parameters.array[codes[index]].result & f_console_result_value_d) {
+        else if (main->program.parameters.array[codes[index]].result & f_console_result_found_d) {
           if (flags[index]) main->setting.flag |= flags[index];
         }
       } // for
@@ -330,6 +330,34 @@ extern "C" {
     else if (main->program.parameters.array[controller_parameter_uninterruptible_e].result & f_console_result_found_d) {
       main->setting.flag &= ~controller_main_flag_interruptible_d;
     }
+
+    #ifdef _support_controller_controlfile_
+      if (main->program.parameters.array[controller_parameter_file_e].result & f_console_result_value_d) {
+        index = main->program.parameters.array[controller_parameter_file_e].values.array[main->program.parameters.array[controller_parameter_file_e].values.used - 1];
+
+        main->setting.path_controlfile.used = 0;
+
+        main->setting.state.status = f_string_dynamic_append_nulless(args[index], &main->setting.path_controlfile);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          controller_print_error(&main->program.error, F_status_debug_source_d);
+
+          return;
+        }
+      }
+      else if (main->program.parameters.array[controller_parameter_file_e].result & f_console_result_found_d) {
+        main->setting.state.status = F_status_set_error(F_parameter);
+
+        fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, controller_long_file_s);
+
+        return;
+      }
+      else {
+        main->setting.path_controlfile.string = controller_controlfile_s.string;
+        main->setting.path_controlfile.used = controller_controlfile_s.used;
+        main->setting.path_controlfile.size = 0;
+      }
+    #endif // _support_controller_controlfile_
   }
 #endif // _di_controller_setting_load_
 
index babc01a91f1d24c1194434726a082346c3672739..c9c1dfdd971b6dcfe41a8ffa111247068290f580 100644 (file)
@@ -23,6 +23,7 @@ extern "C" {
   enum {
     controller_parameter_cgroup_e = f_console_standard_parameter_last_e,
     controller_parameter_daemon_e,
+    controller_parameter_file_e,
     controller_parameter_interruptible_e,
     controller_parameter_pid_e,
     controller_parameter_settings_e,
@@ -38,6 +39,7 @@ extern "C" {
       \
       macro_f_console_parameter_t_initialize_3(controller_short_cgroup_s,          controller_long_cgroup_s,          1, f_console_flag_normal_d), \
       macro_f_console_parameter_t_initialize_3(controller_short_daemon_s,          controller_long_daemon_s,          0, f_console_flag_normal_d), \
+      macro_f_console_parameter_t_initialize_3(controller_short_file_s,            controller_long_file_s,            1, f_console_flag_normal_d | f_console_flag_disable_d), \
       macro_f_console_parameter_t_initialize_3(controller_short_interruptible_s,   controller_long_interruptible_s,   0, f_console_flag_normal_d), \
       macro_f_console_parameter_t_initialize_3(controller_short_pid_s,             controller_long_pid_s,             1, f_console_flag_normal_d), \
       macro_f_console_parameter_t_initialize_3(controller_short_settings_s,        controller_long_settings_s,        1, f_console_flag_normal_d), \
index 932964d6df2f0ece51ac6a316f8470a1b5c74a74..2b6c137bbdede884828ee15b89eb344406925f7b 100644 (file)
@@ -17,6 +17,7 @@ extern "C" {
 #ifndef _di_controller_parameter_s_
   const f_string_static_t controller_short_cgroup_s = macro_f_string_static_t_initialize_1(CONTROLLER_short_cgroup_s, 0, CONTROLLER_short_cgroup_s_length);
   const f_string_static_t controller_short_daemon_s = macro_f_string_static_t_initialize_1(CONTROLLER_short_daemon_s, 0, CONTROLLER_short_daemon_s_length);
+  const f_string_static_t controller_short_file_s = macro_f_string_static_t_initialize_1(CONTROLLER_short_file_s, 0, CONTROLLER_short_file_s_length);
   const f_string_static_t controller_short_interruptible_s = macro_f_string_static_t_initialize_1(CONTROLLER_short_interruptible_s, 0, CONTROLLER_short_interruptible_s_length);
   const f_string_static_t controller_short_pid_s = macro_f_string_static_t_initialize_1(CONTROLLER_short_pid_s, 0, CONTROLLER_short_pid_s_length);
   const f_string_static_t controller_short_settings_s = macro_f_string_static_t_initialize_1(CONTROLLER_short_settings_s, 0, CONTROLLER_short_settings_s_length);
@@ -27,6 +28,7 @@ extern "C" {
 
   const f_string_static_t controller_long_cgroup_s = macro_f_string_static_t_initialize_1(CONTROLLER_long_cgroup_s, 0, CONTROLLER_long_cgroup_s_length);
   const f_string_static_t controller_long_daemon_s = macro_f_string_static_t_initialize_1(CONTROLLER_long_daemon_s, 0, CONTROLLER_long_daemon_s_length);
+  const f_string_static_t controller_long_file_s = macro_f_string_static_t_initialize_1(CONTROLLER_long_file_s, 0, CONTROLLER_long_file_s_length);
   const f_string_static_t controller_long_interruptible_s = macro_f_string_static_t_initialize_1(CONTROLLER_long_interruptible_s, 0, CONTROLLER_long_interruptible_s_length);
   const f_string_static_t controller_long_pid_s = macro_f_string_static_t_initialize_1(CONTROLLER_long_pid_s, 0, CONTROLLER_long_pid_s_length);
   const f_string_static_t controller_long_settings_s = macro_f_string_static_t_initialize_1(CONTROLLER_long_settings_s, 0, CONTROLLER_long_settings_s_length);
index 493749e2adeb7f25584f5c5a987d7e685b770713..8d08a6ec056c3fb73e1bf07b241d975b8eeb7c2b 100644 (file)
@@ -82,6 +82,7 @@ extern "C" {
 #ifndef _di_controller_parameter_s_
   #define CONTROLLER_short_cgroup_s          "c"
   #define CONTROLLER_short_daemon_s          "d"
+  #define CONTROLLER_short_file_s            "f"
   #define CONTROLLER_short_interruptible_s   "I"
   #define CONTROLLER_short_pid_s             "p"
   #define CONTROLLER_short_settings_s        "s"
@@ -92,6 +93,7 @@ extern "C" {
 
   #define CONTROLLER_long_cgroup_s          "cgroup"
   #define CONTROLLER_long_daemon_s          "daemon"
+  #define CONTROLLER_long_file_s            "file"
   #define CONTROLLER_long_interruptible_s   "interruptible"
   #define CONTROLLER_long_pid_s             "pid"
   #define CONTROLLER_long_settings_s        "settings"
@@ -102,6 +104,7 @@ extern "C" {
 
   #define CONTROLLER_short_cgroup_s_length          1
   #define CONTROLLER_short_daemon_s_length          1
+  #define CONTROLLER_short_file_s_length            1
   #define CONTROLLER_short_interruptible_s_length   1
   #define CONTROLLER_short_pid_s_length             1
   #define CONTROLLER_short_settings_s_length        1
@@ -112,6 +115,7 @@ extern "C" {
 
   #define CONTROLLER_long_cgroup_s_length          6
   #define CONTROLLER_long_daemon_s_length          6
+  #define CONTROLLER_long_file_s_length            4
   #define CONTROLLER_long_interruptible_s_length   13
   #define CONTROLLER_long_pid_s_length             3
   #define CONTROLLER_long_settings_s_length        8
@@ -122,6 +126,7 @@ extern "C" {
 
   extern const f_string_static_t controller_short_cgroup_s;
   extern const f_string_static_t controller_short_daemon_s;
+  extern const f_string_static_t controller_short_file_s;
   extern const f_string_static_t controller_short_interruptible_s;
   extern const f_string_static_t controller_short_pid_s;
   extern const f_string_static_t controller_short_settings_s;
@@ -132,6 +137,7 @@ extern "C" {
 
   extern const f_string_static_t controller_long_cgroup_s;
   extern const f_string_static_t controller_long_daemon_s;
+  extern const f_string_static_t controller_long_file_s;
   extern const f_string_static_t controller_long_init_s;
   extern const f_string_static_t controller_long_interruptible_s;
   extern const f_string_static_t controller_long_pid_s;
index bd3b0ca0c10c836ea9ba3481e6f58c8d3c95d7af..edd5b7c5a337e3ab855e6dea94e42017278b10c6 100644 (file)
@@ -21,6 +21,13 @@ extern "C" {
   void controller_setting_delete(controller_setting_t * const setting) {
 
     if (!setting) return;
+
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &setting->path_pid.string, &setting->path_pid.used, &setting->path_pid.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &setting->path_setting.string, &setting->path_setting.used, &setting->path_setting.size);
+
+    #ifdef _support_controller_controlfile_
+      f_memory_array_resize(0, sizeof(f_char_t), (void **) &setting->path_controlfile.string, &setting->path_controlfile.used, &setting->path_controlfile.size);
+    #endif // _support_controller_controlfile_
   }
 #endif // _di_controller_setting_delete_
 
index 10b0c140e5ae8aab534b3773a4c336a866fcd2f9..04f58d2c4f6cf00a9bfc6dfbafc0e6d0e66fa368 100644 (file)
@@ -28,6 +28,8 @@ extern "C" {
  *
  *   - path_pid:     The name of the program.
  *   - path_setting: The long name of the program.
+ *
+ *   - path_controlfile: The path to the controlfile or initfile (if support is enabled).
  */
 #ifndef _di_controller_setting_t_
   typedef struct {
@@ -36,15 +38,30 @@ extern "C" {
 
     f_string_dynamic_t path_pid;
     f_string_dynamic_t path_setting;
+
+    #ifdef _support_controller_controlfile_
+      f_string_dynamic_t path_controlfile;
+    #endif // _support_controller_controlfile_
   } controller_setting_t;
 
-  #define controller_setting_t_initialize \
-    { \
-      controller_main_flag_none_d, \
-      f_state_t_initialize, \
-      f_string_dynamic_t_initialize, \
-      f_string_dynamic_t_initialize, \
-    }
+  #ifdef _support_controller_controlfile_
+    #define controller_setting_t_initialize \
+      { \
+        controller_main_flag_none_d, \
+        f_state_t_initialize, \
+        f_string_dynamic_t_initialize, \
+        f_string_dynamic_t_initialize, \
+        f_string_dynamic_t_initialize, \
+      }
+  #else
+    #define controller_setting_t_initialize \
+      { \
+        controller_main_flag_none_d, \
+        f_state_t_initialize, \
+        f_string_dynamic_t_initialize, \
+        f_string_dynamic_t_initialize, \
+      }
+  #endif // _support_controller_controlfile_
 #endif // _di_controller_setting_t_
 
 /**
index d037060e5f56d72ec669a027b21fcaffd85d51d5..b7d31f487e52dd9d18e6c52c6b1ac0315e5f4c8b 100644 (file)
@@ -126,7 +126,7 @@ extern "C" {
 
     f_file_t file = f_file_t_initialize;
 
-    f_status_t status = f_file_stream_open(controller_controlfile_s, f_string_empty_s, &file);
+    f_status_t status = f_file_stream_open(main->setting.path_controlfile, f_string_empty_s, &file);
 
     if (F_status_is_error(status)) {
       if (F_status_set_fine(status) == F_file_found_not) {
index 8de44ad5d2d5c8e322a3adf464cc4ad01b9ded22..d82b01689bb58ab4eb727c09c4626d1f2af577b1 100644 (file)
@@ -65,7 +65,9 @@ extern "C" {
 #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);
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+
+    controller_t * const main = (controller_t *) print->custom;
 
     fll_program_print_help_header(print, controller_program_name_long_s, controller_program_version_s);
 
@@ -75,6 +77,12 @@ extern "C" {
 
     fll_program_print_help_option(print, controller_short_cgroup_s, controller_long_cgroup_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "         Specify a custom control group file path, such as '" F_control_group_path_system_prefix_s F_control_group_path_system_default_s "'.");
     fll_program_print_help_option(print, controller_short_daemon_s, controller_long_daemon_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "         Run in daemon only mode (do not process the entry).");
+
+    if (!(main->program.parameters.array[controller_parameter_file_e].flag & f_console_flag_disable_d)) {
+      fl_print_format("  %Q%[%Q%]", print->to, f_console_symbol_short_normal_s, print->set->standout, controller_short_file_s, print->set->standout);
+      fl_print_format(", %Q%[%Q%]             Specify a custom path to the %Q.%r", print->to, f_console_symbol_long_normal_s, print->set->standout, controller_long_file_s, print->set->standout, controller_controlfile_s, f_string_eol_s);
+    }
+
     fll_program_print_help_option(print, controller_short_interruptible_s, controller_long_interruptible_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "  Designate that this program can be interrupted by a signal.");
     fll_program_print_help_option(print, controller_short_pid_s, controller_long_pid_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "            Specify a custom pid file path, such as 'controller/run/default.pid'.");
     fll_program_print_help_option(print, controller_short_settings_s, controller_long_settings_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "       Specify a custom settings path, such as 'controller/'.");
index 242951845ef181ef84d6d6b4765539f6508764f2..a93742e6a1f5288663a25fb2a01bd2273db338b4 100644 (file)
@@ -10,6 +10,8 @@ extern "C" {
     if (!main || !cache || !entry || !rule) return F_status_set_error(F_parameter);
 
     uint8_t for_item = F_true;
+    f_number_unsigned_t i = 0;
+    f_number_unsigned_t j = 0;
 
     rule->timeout_kill = entry->timeout_kill ? entry->timeout_kill : 0;
     rule->timeout_start = entry->timeout_start ? entry->timeout_start : 0;
@@ -66,21 +68,18 @@ extern "C" {
 
     if (!(main->setting.flag & controller_main_flag_single_d)) {
       cache->buffer_file.used = 0;
+      cache->content_items.used = 0;
+      cache->object_items.used = 0;
     }
 
     cache->buffer_item.used = 0;
     cache->buffer_path.used = 0;
 
-    cache->content_items.used = 0;
-    cache->object_items.used = 0;
-
     cache->action.name_action.used = 0;
     cache->action.name_file.used = 0;
     cache->action.name_item.used = 0;
 
     {
-      f_number_unsigned_t i = 0;
-      f_number_unsigned_t j = 0;
       f_number_unsigned_t k = 0;
       f_number_unsigned_t l = 0;
 
@@ -212,9 +211,6 @@ extern "C" {
         controller_print_error_status(&main->program.error, F_status_debug_source_d, F_status_set_fine(state.status));
       }
       else {
-        f_number_unsigned_t i = 0;
-        f_number_unsigned_t j = 0;
-
         f_range_t offset = f_range_t_initialize;
         f_state_t state = f_state_t_initialize;
 
@@ -283,6 +279,40 @@ extern "C" {
             } // for
 
             if (entry->status == F_equal_to_not) continue;
+
+            // Perform match on the alias.
+            for (j = 0; offset.start <= offset.stop && j < alias.used; ++offset.start) {
+
+              if (!cache->buffer_file.string[offset.start]) continue;
+
+              for (; j < alias.used && !alias.string[j]; ++j) {
+                // Do nothing.
+              } // for
+
+              if (cache->buffer_file.string[offset.start] != alias.string[j]) {
+                entry->status = F_equal_to_not;
+
+                break;
+              }
+
+              ++j;
+            } // for
+
+            if (entry->status == F_equal_to_not) continue;
+
+            // Perform match on the trailing slash.
+            for (j = 0; offset.start <= offset.stop && j < f_string_ascii_slash_forward_s.used; ++offset.start) {
+
+              if (!cache->buffer_file.string[offset.start]) continue;
+
+              if (cache->buffer_file.string[offset.start] != f_string_ascii_slash_forward_s.string[j]) {
+                entry->status = F_equal_to_not;
+
+                break;
+              }
+
+              ++j;
+            } // for
           }
 
           state.status = f_rip_dynamic_partial_nulless(cache->buffer_file, offset, &cache->action.name_item);