]> Kevux Git Server - fll/commitdiff
Update: Controller and control.
authorKevin Day <thekevinday@gmail.com>
Mon, 21 Feb 2022 01:52:21 +0000 (19:52 -0600)
committerKevin Day <thekevinday@gmail.com>
Mon, 21 Feb 2022 01:52:21 +0000 (19:52 -0600)
Fix bug in control where parameter should be "settings" and not "socket".

The controller can now detect the current path and provide a canonical relative path only for paths whose actual canonical path is within the current working directory that the controller program started in.

Fix printing of the help in the controller program (missing slashes).

Don't create socket and pid files when running validate and simulate.
When running simulate, still create the pid and socket files as appropriate.
Add new entry setting to allow explicitly setting the pid file path.

Remove no longer necessary functions that ensure terminating NULL.
The recent changes in the string functions now guarantee this.

Remove a lot of todo comments.
I will either get to them or not.

I plan on getting to writing IKI support.
It needs to happen and I can use the Fake program as an example.

18 files changed:
level_3/control/c/private-control.c
level_3/controller/c/common/private-setting.c
level_3/controller/c/common/private-setting.h
level_3/controller/c/controller.c
level_3/controller/c/controller.h
level_3/controller/c/controller/private-controller.c
level_3/controller/c/controller/private-controller.h
level_3/controller/c/entry/private-entry.c
level_3/controller/c/entry/private-entry.h
level_3/controller/c/entry/private-entry_print.c
level_3/controller/c/entry/private-entry_print.h
level_3/controller/c/rule/private-rule.c
level_3/controller/c/rule/private-rule.h
level_3/controller/data/settings/example/entries/up.entry
level_3/controller/data/settings/example/rules/script/create_socket_path.rule [new file with mode: 0644]
level_3/controller/documents/entry.txt
level_3/controller/documents/rule.txt
level_3/controller/specifications/entry.txt

index ec9076c65c495823928582f013d1dd2697c52576..5b6f8d6f29c3805773f070d648ed2f083e96fead 100644 (file)
@@ -152,7 +152,7 @@ extern "C" {
 
     data->cache.buffer_small.used = 0;
 
-    if (main->parameters.array[control_parameter_socket_e].result == f_console_result_additional_e) {
+    if (main->parameters.array[control_parameter_settings_e].result == f_console_result_additional_e) {
       const f_array_length_t index = main->parameters.array[control_parameter_settings_e].values.array[main->parameters.array[control_parameter_settings_e].values.used - 1];
 
       status = f_string_dynamic_append(data->argv[index], &data->cache.buffer_small);
index 76366f821d964923dfa9e14aa6b9ea24c100b40e..2ffb1e24bc95fa420445a85234bcc6fc540f5275 100644 (file)
@@ -10,6 +10,7 @@ extern "C" {
 
     f_string_dynamic_resize(0, &setting->path_control);
     f_string_dynamic_resize(0, &setting->path_cgroup);
+    f_string_dynamic_resize(0, &setting->path_current);
     f_string_dynamic_resize(0, &setting->path_pid);
     f_string_dynamic_resize(0, &setting->path_setting);
 
index 527d3e35bf20c02a6f7b499a8cf098c1ea23ecdc..e62f27797688687cbaf9c37744d68ea3cdb9fcb6 100644 (file)
@@ -77,6 +77,7 @@ extern "C" {
 
     f_string_dynamic_t path_cgroup;
     f_string_dynamic_t path_control;
+    f_string_dynamic_t path_current;
     f_string_dynamic_t path_pid;
     f_string_dynamic_t path_setting;
 
@@ -104,6 +105,7 @@ extern "C" {
     f_string_dynamic_t_initialize, \
     f_string_dynamic_t_initialize, \
     f_string_dynamic_t_initialize, \
+    f_string_dynamic_t_initialize, \
     controller_entry_t_initialize, \
     controller_entry_t_initialize, \
     controller_rules_t_initialize, \
index d69bd65cd17249762621c2fda301e93dffef4333..1c81e7b2a3acbd68300fa0198590e0699c15e8f3 100644 (file)
@@ -35,10 +35,10 @@ extern "C" {
     fll_program_print_help_option(main->output.to, main->context, controller_short_daemon_s, controller_long_daemon_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "         Run in daemon only mode (do not process the entry).");
     fll_program_print_help_option(main->output.to, main->context, controller_short_init_s, controller_long_init_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "           The program will run as an init replacement.");
     fll_program_print_help_option(main->output.to, main->context, controller_short_interruptible_s, controller_long_interruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "  Designate that this program can be interrupted by a signal.");
-    fll_program_print_help_option(main->output.to, main->context, controller_short_pid_s, controller_long_pid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "            Specify a custom pid file path, such as '" CONTROLLER_path_pid_s CONTROLLER_default_s CONTROLLER_path_pid_suffix_s "'.");
-    fll_program_print_help_option(main->output.to, main->context, controller_short_settings_s, controller_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "       Specify a custom settings path, such as '" CONTROLLER_path_settings_s "'.");
+    fll_program_print_help_option(main->output.to, main->context, controller_short_pid_s, controller_long_pid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "            Specify a custom pid file path, such as '" CONTROLLER_path_pid_s F_path_separator_s CONTROLLER_default_s CONTROLLER_path_pid_suffix_s "'.");
+    fll_program_print_help_option(main->output.to, main->context, controller_short_settings_s, controller_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "       Specify a custom settings path, such as '" CONTROLLER_path_settings_s F_path_separator_s "'.");
     fll_program_print_help_option(main->output.to, main->context, controller_short_simulate_s, controller_long_simulate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "       Run as a simulation.");
-    fll_program_print_help_option(main->output.to, main->context, controller_short_socket_s, controller_long_socket_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "         Specify a custom socket file path, such as '" CONTROLLER_path_socket_s CONTROLLER_default_s CONTROLLER_path_socket_suffix_s "'.");
+    fll_program_print_help_option(main->output.to, main->context, controller_short_socket_s, controller_long_socket_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "         Specify a custom socket file path, such as '" CONTROLLER_path_socket_s F_path_separator_s CONTROLLER_default_s CONTROLLER_path_socket_suffix_s "'.");
     fll_program_print_help_option(main->output.to, main->context, controller_short_uninterruptible_s, controller_long_uninterruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Designate that this program cannot be interrupted by a signal.");
     fll_program_print_help_option(main->output.to, main->context, controller_short_validate_s, controller_long_validate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "       Validate the settings (entry and rules) without running (does not simulate).");
 
@@ -203,41 +203,48 @@ extern "C" {
       setting.mode = controller_setting_mode_service_e;
     }
 
-    if (main->parameters.array[controller_parameter_settings_e].result == f_console_result_found_e) {
-      if (main->error.verbosity != f_console_verbosity_quiet_e) {
-        controller_lock_print(main->error.to, 0);
+    status = f_path_current(F_false, &setting.path_current);
 
-        fl_print_format("%r%[%QThe parameter '%]", main->error.to.stream, f_string_eol_s, main->error.context, main->error.prefix, main->error.context);
-        fl_print_format("%[%r%r%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_settings_s, main->context.set.notable);
-        fl_print_format("%[' is specified, but no value is given.%]%r", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s);
-
-        controller_unlock_print_flush(main->error.to, 0);
-      }
-
-      status = F_status_set_error(F_parameter);
+    if (F_status_is_error(status)) {
+      fll_error_print(main->error, F_status_set_fine(status), "f_path_current", F_true);
     }
-    else if (main->parameters.array[controller_parameter_settings_e].locations.used) {
-      const f_array_length_t index = main->parameters.array[controller_parameter_settings_e].values.array[main->parameters.array[controller_parameter_settings_e].values.used - 1];
+    else {
+      if (main->parameters.array[controller_parameter_settings_e].result == f_console_result_found_e) {
+        if (main->error.verbosity != f_console_verbosity_quiet_e) {
+          controller_lock_print(main->error.to, 0);
 
-      status = fll_path_canonical(argv[index], &setting.path_setting);
+          fl_print_format("%r%[%QThe parameter '%]", main->error.to.stream, f_string_eol_s, main->error.context, main->error.prefix, main->error.context);
+          fl_print_format("%[%r%r%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_settings_s, main->context.set.notable);
+          fl_print_format("%[' is specified, but no value is given.%]%r", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s);
 
-      if (F_status_is_error(status)) {
-        fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
-      }
-    }
-    else {
-      if (main->parameters.array[controller_parameter_init_e].result == f_console_result_found_e && !main->as_init) {
-        status = f_string_dynamic_append(controller_path_settings_init_s, &setting.path_setting);
+          controller_unlock_print_flush(main->error.to, 0);
+        }
+
+        status = F_status_set_error(F_parameter);
       }
-      else if (main->default_path_setting->used) {
-        status = f_string_dynamic_append(*main->default_path_setting, &setting.path_setting);
+      else if (main->parameters.array[controller_parameter_settings_e].locations.used) {
+        const f_array_length_t index = main->parameters.array[controller_parameter_settings_e].values.array[main->parameters.array[controller_parameter_settings_e].values.used - 1];
+
+        status = controller_path_canonical_relative(&setting, argv[index], &setting.path_setting);
+
+        if (F_status_is_error(status)) {
+          fll_error_file_print(main->error, F_status_set_fine(status), "controller_path_canonical_relative", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
+        }
       }
       else {
-        status = f_string_dynamic_append(controller_path_settings_s, &setting.path_setting);
-      }
+        if (main->parameters.array[controller_parameter_init_e].result == f_console_result_found_e && !main->as_init) {
+          status = f_string_dynamic_append(controller_path_settings_init_s, &setting.path_setting);
+        }
+        else if (main->default_path_setting->used) {
+          status = f_string_dynamic_append(*main->default_path_setting, &setting.path_setting);
+        }
+        else {
+          status = f_string_dynamic_append(controller_path_settings_s, &setting.path_setting);
+        }
 
-      if (F_status_is_error(status)) {
-        fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_append", F_true);
+        if (F_status_is_error(status)) {
+          fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_append", F_true);
+        }
       }
     }
 
@@ -259,10 +266,10 @@ extern "C" {
         const f_array_length_t index = main->parameters.array[controller_parameter_pid_e].values.array[main->parameters.array[controller_parameter_pid_e].values.used - 1];
 
         if (argv[index].used) {
-          status = fll_path_canonical(argv[index], &setting.path_pid);
+          status = controller_path_canonical_relative(&setting, argv[index], &setting.path_pid);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
+            fll_error_file_print(main->error, F_status_set_fine(status), "controller_path_canonical_relative", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
           }
         }
         else {
@@ -318,10 +325,10 @@ extern "C" {
         const f_array_length_t index = main->parameters.array[controller_parameter_cgroup_e].values.array[main->parameters.array[controller_parameter_cgroup_e].values.used - 1];
 
         if (argv[index].used) {
-          status = fll_path_canonical(argv[index], &setting.path_cgroup);
+          status = controller_path_canonical_relative(&setting, argv[index], &setting.path_cgroup);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
+            fll_error_file_print(main->error, F_status_set_fine(status), "controller_path_canonical_relative", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
           }
           else {
             status = f_string_append_assure(F_path_separator_s, 1, &setting.path_cgroup);
index 67f4c2ff017344c176da47155d7a2a23ceaee27f..bc9c751b7b4fd137e490de709be9a07e24560725 100644 (file)
  * This program provides system service management, much like sysvcontroller and controllerng.
  * This program can be controlled from user-space via the "control" program.
  * This program can be used in an initrd and should be capable of pivot root operations.
- *
- * @todo Implement "exit" files that are the opposite of "entry" files whereas rules specified within are all called via the "stop" action type.
- *       This would then allow for switching modes.
- *       The "exit" would be specified in the "entry", by name and would be found under "exits" directory alongside the "entries" directory.
- *
- * @todo check the return status of unlocks.
- *
- * @todo the read/write locks (and unlocks) needs to be more robust in that they need to attempt to keep going even on failure or need to wait until resolvable.
- *       this is done to help ensure that the controller program always continues onward.
- *
- * @todo just like with the read/write locks, the out of memory cases need to be handled to keep going instead of bailing.
- *       likely these will need to be sleeps on the premise that eventually memory will clear itself up.
  */
 #ifndef _controller_h
 #define _controller_h
index 70fe99d18130d5254d437043e2bc857eafbbb70c..2867e22b5124daed8e84c56493b6e0f64c6c4dd9 100644 (file)
@@ -30,27 +30,6 @@ extern "C" {
   }
 #endif // _di_controller_range_after_number_sign_
 
-#ifndef _di_controller_string_dynamic_rip_nulless_terminated_
-  f_status_t controller_dynamic_rip_nulless_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) {
-
-    return fl_string_dynamic_partial_rip_nulless(source, range, destination);
-  }
-#endif // _di_controller_string_dynamic_rip_nulless_terminated_
-
-#ifndef _di_controller_string_dynamic_append_terminated_
-  f_status_t controller_dynamic_append_terminated(const f_string_static_t source, f_string_dynamic_t *destination) {
-
-    return f_string_dynamic_append_nulless(source, destination);
-  }
-#endif // _di_controller_string_dynamic_append_terminated_
-
-#ifndef _di_controller_string_dynamic_partial_append_terminated_
-  f_status_t controller_dynamic_partial_append_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) {
-
-    return f_string_dynamic_partial_append(source, range, destination);
-  }
-#endif // _di_controller_string_dynamic_partial_append_terminated_
-
 #ifndef _di_controller_file_load_
   f_status_t controller_file_load(const controller_global_t global, const bool required, const f_string_static_t path_prefix, const f_string_static_t path_name, const f_string_static_t path_suffix, controller_cache_t * const cache) {
 
@@ -315,7 +294,7 @@ extern "C" {
       if (F_status_set_fine(status) == F_number) {
         cache->action.generic.used = 0;
 
-        status = controller_dynamic_rip_nulless_terminated(buffer, range, &cache->action.generic);
+        status = fl_string_dynamic_partial_rip_nulless(buffer, range, &cache->action.generic);
         if (F_status_is_error(status)) return status;
 
         status = f_account_id_by_name(cache->action.generic, id);
@@ -350,7 +329,7 @@ extern "C" {
       if (F_status_set_fine(status) == F_number) {
         cache->action.generic.used = 0;
 
-        status = controller_dynamic_rip_nulless_terminated(buffer, range, &cache->action.generic);
+        status = fl_string_dynamic_partial_rip_nulless(buffer, range, &cache->action.generic);
         if (F_status_is_error(status)) return status;
 
         status = f_account_group_id_by_name(cache->action.generic, id);
@@ -374,6 +353,40 @@ extern "C" {
   }
 #endif // _di_controller_get_id_group_
 
+#ifndef _di_controller_path_canonical_relative_
+  f_status_t controller_path_canonical_relative(const controller_setting_t * const setting, const f_string_static_t source, f_string_dynamic_t * const destination) {
+
+    {
+      const f_status_t status = fll_path_canonical(source, destination);
+      if (F_status_is_error(status)) return status;
+    }
+
+    if (destination->used >= setting->path_current.used) {
+      const f_string_range_t range = macro_f_string_range_t_initialize(setting->path_current.used);
+
+      if (fl_string_dynamic_partial_compare(*destination, setting->path_current, range, range) == F_equal_to) {
+        f_array_length_t length = destination->used - setting->path_current.used;
+
+        if (length) {
+          char temporary[--length];
+          temporary[length] = 0;
+
+          memcpy(temporary, destination->string + setting->path_current.used + 1, length);
+          memcpy(destination->string, temporary, length);
+
+          destination->string[length] = 0;
+          destination->used = length;
+        }
+        else {
+          destination->used = 0;
+        }
+      }
+    }
+
+    return F_none;
+  }
+#endif // _di_controller_path_canonical_relative_
+
 #ifndef _di_controller_perform_ready_
   f_status_t controller_perform_ready(const controller_global_t * const global, controller_cache_t * const cache, const bool is_entry) {
 
@@ -381,12 +394,29 @@ extern "C" {
       return F_none;
     }
 
+    if (global->main->parameters.array[controller_parameter_validate_e].result == f_console_result_found_e) {
+      if (global->main->parameters.array[controller_parameter_simulate_e].result == f_console_result_found_e && global->main->output.verbosity == f_console_verbosity_debug_e) {
+        controller_lock_print(global->main->output.to, global->thread);
+
+        fl_print_format("%rPID file '", global->main->output.to.stream, f_string_eol_s);
+        fl_print_format("%[%Q%]'.%r", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_pid, global->main->context.set.notable, f_string_eol_s);
+
+        if (global->setting->path_control.used) {
+          fl_print_format("%rControl socket '", global->main->output.to.stream, f_string_eol_s);
+          fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable);
+          fl_print_format("'.%r", global->main->output.to.stream, f_string_eol_s);
+        }
+
+        controller_unlock_print_flush(global->main->output.to, global->thread);
+      }
+
+      return F_none;
+    }
+
     f_status_t status = F_none;
 
     if (global->setting->entry.pid != controller_entry_pid_disable_e && !global->setting->path_pid.used) {
-      if (global->main->parameters.array[controller_parameter_validate_e].result == f_console_result_additional_e) {
-        status = controller_file_pid_create(global->main->pid, global->setting->path_pid);
-      }
+      status = controller_file_pid_create(global->main->pid, global->setting->path_pid);
 
       // Report pid file error but because this could be an "init" program, consider the pid file as optional and continue on.
       if (F_status_is_error(status)) {
@@ -434,14 +464,7 @@ extern "C" {
           controller_lock_print(global->main->output.to, global->thread);
 
           fl_print_format("%rPID file '", global->main->output.to.stream, f_string_eol_s);
-          fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_pid, global->main->context.set.notable);
-
-          if (global->main->parameters.array[controller_parameter_validate_e].result == f_console_result_none_e) {
-            fl_print_format("' created.%r", global->main->output.to.stream, f_string_eol_s);
-          }
-          else {
-            fl_print_format("'.%r", global->main->output.to.stream, f_string_eol_s);
-          }
+          fl_print_format("%[%Q%]' created.%r", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_pid, global->main->context.set.notable, f_string_eol_s);
 
           controller_unlock_print_flush(global->main->output.to, global->thread);
         }
@@ -575,13 +598,7 @@ extern "C" {
 
                   fl_print_format("%rControl socket '", global->main->output.to.stream, f_string_eol_s);
                   fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable);
-
-                  if (global->main->parameters.array[controller_parameter_validate_e].result == f_console_result_none_e) {
-                    fl_print_format("' created.%r", global->main->output.to.stream, f_string_eol_s);
-                  }
-                  else {
-                    fl_print_format("'.%r", global->main->output.to.stream, f_string_eol_s);
-                  }
+                  fl_print_format("' created.%r", global->main->output.to.stream, f_string_eol_s);
 
                   controller_unlock_print_flush(global->main->output.to, global->thread);
                 }
index 640cce4d3f5b3762ea4b612593fad566d3f06f05..cbab56db13fcc088bf57bc47fc08fad30f4ba703 100644 (file)
@@ -33,65 +33,6 @@ extern "C" {
 #endif // _di_controller_range_after_number_sign_
 
 /**
- * Rip a string from the source and then add a NULL after the end of the string.
- *
- * @param source
- *   The string to copy from.
- * @param destination
- *   The string to copy to.
- *
- * @return
- *   F_none on success.
- *
- *   Errors (with error bit) from: fl_string_dynamic_partial_rip_nulless().
- *
- * @see fl_string_dynamic_partial_rip_nulless()
- */
-#ifndef _di_controller_string_dynamic_rip_nulless_terminated_
-  extern f_status_t controller_dynamic_rip_nulless_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) F_attribute_visibility_internal_d;
-#endif // _di_controller_string_dynamic_rip_nulless_terminated_
-
-/**
- * Append a string and then add a NULL after the end of the string.
- *
- * @param source
- *   The string to copy from.
- * @param destination
- *   The string to copy to.
- *
- * @return
- *   F_none on success.
- *
- *   Errors (with error bit) from: f_string_dynamic_append_nulless().
- *
- * @see f_string_dynamic_append_nulless()
- */
-#ifndef _di_controller_string_dynamic_append_terminated_
-  extern f_status_t controller_dynamic_append_terminated(const f_string_static_t from, f_string_dynamic_t *destination) F_attribute_visibility_internal_d;
-#endif // _di_controller_string_dynamic_append_terminated_
-
-/**
- * Append given range from within a string and then add a NULL after the end of the string.
- *
- * @param from
- *   The string to copy from.
- * @param range
- *   The range within the from string to copy.
- * @param destination
- *   The string to copy to.
- *
- * @return
- *   F_none on success.
- *
- *   Errors (with error bit) from: f_string_dynamic_append().
- *
- * @see f_string_dynamic_append()
- */
-#ifndef _di_controller_string_dynamic_partial_append_terminated_
-  extern f_status_t controller_dynamic_partial_append_terminated(const f_string_static_t from, const f_string_range_t range, f_string_dynamic_t *destination) F_attribute_visibility_internal_d;
-#endif // _di_controller_string_dynamic_partial_append_terminated_
-
-/**
  * Load a file from the controller settings directory.
  *
  * @param global
@@ -253,6 +194,36 @@ extern "C" {
 #endif // _di_controller_get_id_group_
 
 /**
+ * Determine a canonical path and then if it is relative to the current working directory, make it relative.
+ *
+ * For example, given the paths "../hello/world/" and "../controller/files/" with a current working directory of "/tmp/controller", then a canonical path for these might look like:
+ * - "/tmp/hello/world/"
+ * - "/tmp/controller/files/"
+ *
+ * This function would instead result in the following:
+ * - "/tmp/hello/world/"
+ * - "files/"
+ *
+ * @param setting
+ *   The controller settings data.
+ * @param source
+ *   The source path to determine the relative canonical from.
+ * @param destination
+ *   The resulting relative canonical path.
+ *   The destination will be completely replaced on success.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: fll_path_canonical().
+ *
+ * @see fll_path_canonical()
+ */
+#ifndef _di_controller_path_canonical_relative_
+  extern f_status_t controller_path_canonical_relative(const controller_setting_t * const global, const f_string_static_t source, f_string_dynamic_t * const destination) F_attribute_visibility_internal_d;
+#endif // _di_controller_path_canonical_relative_
+
+/**
  * Perform all activities requiring the state to be "ready".
  *
  * This prints messages on errors.
@@ -344,7 +315,7 @@ extern "C" {
  * @param main
  *   The main program data.
  * @param setting
- *   The settings.
+ *   The controller settings data.
  * @param time
  *   The number of nanoseconds to sleep.
  *
index 7befb6329f691d91be5486d1dccdb2e7f319c0cc..a081875d749853f2db62bbe951698d245c134437 100644 (file)
@@ -229,10 +229,11 @@ extern "C" {
 
       action->line = ++cache->action.line_action;
 
-      status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_actions.array[i], &cache->action.name_action);
+      status = fl_string_dynamic_partial_rip_nulless(cache->buffer_file, cache->object_actions.array[i], &cache->action.name_action);
 
       if (F_status_is_error(status)) {
-        controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+        controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true, global.thread);
+
         break;
       }
 
@@ -414,17 +415,16 @@ extern "C" {
             if (action->parameters.array[0].used) {
 
               // Force the path to be canonical (removing all '../' parts).
-              status = fll_path_canonical(action->parameters.array[0], &cache->buffer_path);
+              status = controller_path_canonical_relative(global.setting, action->parameters.array[0], &cache->buffer_path);
 
               if (F_status_is_error(status)) {
-                // @todo instead call: fll_error_file_print().
-                // fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, argv[index], f_file_operation_verify_s, fll_error_file_type_path_e);
-                controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_path_canonical", F_true, global.thread);
+                controller_entry_print_error_file(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_path_canonical_relative", F_true, cache->action.generic, f_file_operation_analyze_s, fll_error_file_type_path_e, global.thread);
 
                 action->status = status;
 
                 if (F_status_set_fine(status) == F_memory_not) {
                   status_action = status;
+
                   break;
                 }
 
@@ -455,6 +455,7 @@ extern "C" {
 
                 if (F_status_set_fine(status) == F_memory_not) {
                   status_action = status;
+
                   break;
                 }
 
@@ -677,9 +678,6 @@ extern "C" {
     uint8_t error_has = F_false;
 
     // This effectively sets the read for an entry and resets the ready for an exit.
-    // @todo should there be a ready_exit instead?
-    // @todo the global.setting->ready in this function may need mutex lock protection.
-    // @todo disconnect the socket file if applicable.
     global.setting->ready = controller_setting_ready_no_e;
 
     cache->ats.used = 0;
@@ -705,10 +703,10 @@ extern "C" {
     cache->action.line_item = entry->items.array[0].line;
     cache->action.name_item.used = 0;
 
-    status = controller_dynamic_append_terminated(entry->items.array[0].name, &cache->action.name_item);
+    status = f_string_dynamic_append_nulless(entry->items.array[0].name, &cache->action.name_item);
 
     if (F_status_is_error(status)) {
-      controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global.thread);
+      controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global.thread);
 
       return status;
     }
@@ -722,10 +720,10 @@ extern "C" {
         cache->action.line_action = actions->array[cache->ats.array[at_j]].line;
         cache->action.name_action.used = 0;
 
-        status2 = controller_dynamic_append_terminated(controller_entry_action_type_name(actions->array[cache->ats.array[at_j]].type), &cache->action.name_action);
+        status2 = f_string_dynamic_append_nulless(controller_entry_action_type_name(actions->array[cache->ats.array[at_j]].type), &cache->action.name_action);
 
         if (F_status_is_error(status2)) {
-          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "controller_dynamic_append_terminated", F_true, global.thread);
+          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "f_string_dynamic_append_nulless", F_true, global.thread);
 
           return status2;
         }
@@ -817,10 +815,10 @@ extern "C" {
               cache->action.name_item.used = 0;
               cache->action.line_item = entry->items.array[i].line;
 
-              status2 = controller_dynamic_append_terminated(entry->items.array[i].name, &cache->action.name_item);
+              status2 = f_string_dynamic_append_nulless(entry->items.array[i].name, &cache->action.name_item);
 
               if (F_status_is_error(status2)) {
-                controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "controller_dynamic_append_terminated", F_true, global.thread);
+                controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "f_string_dynamic_append_nulless", F_true, global.thread);
 
                 return status2;
               }
@@ -872,10 +870,10 @@ extern "C" {
         cache->action.line_item = entry->items.array[cache->ats.array[at_i]].line;
         cache->action.name_item.used = 0;
 
-        status2 = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item);
+        status2 = f_string_dynamic_append_nulless(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item);
 
         if (F_status_is_error(status2)) {
-          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "controller_dynamic_append_terminated", F_true, global.thread);
+          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "f_string_dynamic_append_nulless", F_true, global.thread);
 
           return status2;
         }
@@ -915,7 +913,7 @@ extern "C" {
     controller_entry_actions_t *entry_actions = 0;
     controller_process_t *process = 0;
 
-    // an empty stack is used here because each rule here is the first rule run in the rule's scope.
+    // An empty stack is used here because each rule here is the first rule run in the rule's scope.
     const f_array_lengths_t stack = f_array_lengths_t_initialize;
 
     cache->ats.used = 0;
@@ -942,10 +940,10 @@ extern "C" {
     cache->action.line_item = entry->items.array[cache->ats.array[0]].line;
     cache->action.name_item.used = 0;
 
-    status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[0]].name, &cache->action.name_item);
+    status = f_string_dynamic_append_nulless(entry->items.array[cache->ats.array[0]].name, &cache->action.name_item);
 
     if (F_status_is_error(status)) {
-      controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread);
+      controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global->thread);
 
       return status;
     }
@@ -978,10 +976,10 @@ extern "C" {
         cache->action.line_action = entry_action->line;
         cache->action.name_action.used = 0;
 
-        status = controller_dynamic_append_terminated(controller_entry_action_type_name(entry_action->type), &cache->action.name_action);
+        status = f_string_dynamic_append_nulless(controller_entry_action_type_name(entry_action->type), &cache->action.name_action);
 
         if (F_status_is_error(status)) {
-          controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread);
+          controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global->thread);
 
           return status;
         }
@@ -1147,10 +1145,10 @@ extern "C" {
           cache->action.name_item.used = 0;
           cache->action.line_item = entry->items.array[cache->ats.array[at_i]].line;
 
-          status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item);
+          status = f_string_dynamic_append_nulless(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item);
 
           if (F_status_is_error(status)) {
-            controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread);
+            controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global->thread);
 
             return status;
           }
@@ -1519,10 +1517,10 @@ extern "C" {
         cache->action.line_item = entry->items.array[cache->ats.array[at_i]].line;
         cache->action.name_item.used = 0;
 
-        status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item);
+        status = f_string_dynamic_append_nulless(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item);
 
         if (F_status_is_error(status)) {
-          controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread);
+          controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global->thread);
 
           break;
         }
@@ -1717,10 +1715,11 @@ extern "C" {
             break;
           }
 
-          status = controller_dynamic_partial_append_terminated(cache->buffer_file, cache->object_items.array[i], &cache->action.name_item);
+          status = f_string_dynamic_partial_append(cache->buffer_file, cache->object_items.array[i], &cache->action.name_item);
 
           if (F_status_is_error(status)) {
-            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_partial_append_terminated", F_true, global.thread);
+            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append", F_true, global.thread);
+
             break;
           }
 
@@ -1728,6 +1727,7 @@ extern "C" {
 
           if (F_status_is_error(status)) {
             controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+
             break;
           }
 
@@ -1785,10 +1785,10 @@ extern "C" {
 
           entry->items.array[at].line = cache->action.line_item;
 
-          status = controller_dynamic_append_terminated(cache->action.name_item, &entry->items.array[at].name);
+          status = f_string_dynamic_append_nulless(cache->action.name_item, &entry->items.array[at].name);
 
           if (F_status_is_error(status)) {
-            controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true);
+            controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true);
 
             break;
           }
@@ -1873,10 +1873,10 @@ extern "C" {
                     cache->action.line_action = action->line;
                     cache->action.line_item = entry->items.array[i].line;
 
-                    status = controller_dynamic_append_terminated(entry->items.array[i].name, &cache->action.name_item);
+                    status = f_string_dynamic_append_nulless(entry->items.array[i].name, &cache->action.name_item);
 
                     if (F_status_is_error(status)) {
-                      controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true);
+                      controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true);
 
                       break;
                     }
@@ -1973,10 +1973,10 @@ extern "C" {
       line = ++cache->action.line_action;
       cache->action.name_action.used = 0;
 
-      status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_actions.array[i], &cache->action.name_action);
+      status = fl_string_dynamic_partial_rip_nulless(cache->buffer_file, cache->object_actions.array[i], &cache->action.name_action);
 
       if (F_status_is_error(status)) {
-        controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+        controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true, global.thread);
 
         break;
       }
@@ -1991,59 +1991,20 @@ extern "C" {
         cache->action.generic.used = 0;
         global.setting->path_control.used = 0;
 
-        status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->content_actions.array[i].array[0], &global.setting->path_control);
+        status = fl_string_dynamic_partial_rip_nulless(cache->buffer_file, cache->content_actions.array[i].array[0], &cache->action.generic);
 
         if (F_status_is_error(status)) {
-          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true, global.thread);
 
           global.setting->path_control.used = 0;
 
           break;
         }
 
-        if (f_path_is_relative(global.setting->path_control) == F_true) {
-
-          // Use the PID file path for creating a relative path to the control socket.
-          status = f_file_name_directory(global.setting->path_pid, &cache->action.generic);
-
-          if (F_status_is_error(status)) {
-            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_file_name_directory", F_true, global.thread);
-
-            global.setting->path_control.used = 0;
-
-            break;
-          }
-
-          status = f_string_dynamic_append(f_path_separator_s, &cache->action.generic);
-
-          if (F_status_is_error_not(status)) {
-            status = f_string_dynamic_append(global.setting->path_control, &cache->action.generic);
-          }
-
-          if (F_status_is_error(status)) {
-            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread);
-
-            global.setting->path_control.used = 0;
-
-            break;
-          }
-        }
-        else {
-          status = f_string_dynamic_append(global.setting->path_control, &cache->action.generic);
-
-          if (F_status_is_error(status)) {
-            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread);
-
-            global.setting->path_control.used = 0;
-
-            break;
-          }
-        }
-
-        status = fll_path_canonical(cache->action.generic, &global.setting->path_control);
+        status = controller_path_canonical_relative(global.setting, cache->action.generic, &global.setting->path_control);
 
         if (F_status_is_error(status)) {
-          controller_entry_print_error_file(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_path_canonical", F_true, cache->action.generic, f_file_operation_analyze_s, fll_error_file_type_path_e, global.thread);
+          controller_entry_print_error_file(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_path_canonical_relative", F_true, cache->action.generic, f_file_operation_analyze_s, fll_error_file_type_path_e, global.thread);
 
           global.setting->path_control.used = 0;
 
@@ -2083,10 +2044,10 @@ extern "C" {
 
         cache->action.generic.used = 0;
 
-        status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->content_actions.array[i].array[0], &cache->action.generic);
+        status = fl_string_dynamic_partial_rip_nulless(cache->buffer_file, cache->content_actions.array[i].array[0], &cache->action.generic);
 
         if (F_status_is_error(status)) {
-          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+          controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true, global.thread);
 
           break;
         }
@@ -2176,6 +2137,38 @@ extern "C" {
           continue;
         }
       }
+      else if (is_entry && fl_string_dynamic_compare(controller_pid_file_s, cache->action.name_action) == F_equal_to) {
+        if (cache->content_actions.array[i].used != 1) {
+          controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1);
+
+          continue;
+        }
+
+        if (global.main->parameters.array[controller_parameter_pid_e].result == f_console_result_additional_e) {
+          controller_entry_settings_read_print_setting_ignored(global, is_entry, *cache, i);
+        }
+        else {
+          cache->action.generic.used = 0;
+
+          status = fl_string_dynamic_partial_rip_nulless(cache->buffer_file, cache->content_actions.array[i].array[0], &cache->action.generic);
+
+          if (F_status_is_error(status)) {
+            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true, global.thread);
+
+            continue;
+          }
+
+          global.setting->path_pid.used = 0;
+
+          status = controller_path_canonical_relative(global.setting, cache->action.generic, &global.setting->path_pid);
+
+          if (F_status_is_error(status)) {
+            controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_path_canonical_relative", F_true, global.thread);
+
+            continue;
+          }
+        }
+      }
       else if (fl_string_dynamic_compare(controller_session_s, cache->action.name_action) == F_equal_to) {
         if (cache->content_actions.array[i].used != 1) {
           controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1);
index b2d05101f7f5aa24fc7a5a8c5af9fd48ba7483c9..175daf66c8b02608caf6cdd2cc653fad66b79e7d 100644 (file)
@@ -143,13 +143,15 @@ extern "C" {
  *   F_critical (with error bit) on any critical error.
  *   F_execute (with error bit) if the "execute" Item Action failed.
  *
+ *   Errors (with error bit) from: f_string_dynamic_append_nulless().
+ *
  *   Errors (with error bit) from: macro_f_array_lengths_t_increase_by().
  *   Errors (with error bit) from: controller_perform_ready().
- *   Errors (with error bit) from: controller_dynamic_append_terminated().
+ *
+ * @see f_string_dynamic_append_nulless()
  *
  * @see macro_f_array_lengths_t_increase_by()
  * @see controller_perform_ready()
- * @see controller_dynamic_append_terminated()
  */
 #ifndef _di_controller_entry_process_
   extern f_status_t controller_entry_process(const controller_global_t * const global, controller_cache_t * const cache, const bool failsafe, const bool is_entry) F_attribute_visibility_internal_d;
@@ -175,26 +177,28 @@ extern "C" {
  *   Errors (with error bit) from: controller_entry_items_increase_by().
  *   Errors (with error bit) from: controller_file_load().
  *   Errors (with error bit) from: controller_status_simplify_error().
- *   Errors (with error bit) from: controller_dynamic_append_terminated().
- *   Errors (with error bit) from: controller_dynamic_partial_append_terminated().
+ *
  *   Errors (with error bit) from: f_fss_count_lines().
- *   Errors (with error bit) from: fl_fss_apply_delimit().
  *   Errors (with error bit) from: f_string_dynamic_append().
+ *   Errors (with error bit) from: f_string_dynamic_append_nulless().
+ *   Errors (with error bit) from: f_string_dynamic_partial_append().
  *   Errors (with error bit) from: f_string_dynamic_partial_append_nulless().
  *   Errors (with error bit) from: f_string_dynamic_terminate().
+ *   Errors (with error bit) from: fl_fss_apply_delimit().
  *   Errors (with error bit) from: fll_fss_basic_list_read().
  *
  * @see controller_entry_actions_read()
  * @see controller_entry_items_increase_by()
  * @see controller_file_load()
  * @see controller_status_simplify_error()
- * @see controller_dynamic_append_terminated()
- * @see controller_dynamic_partial_append_terminated()
+ *
  * @see f_fss_count_lines()
- * @see fl_fss_apply_delimit()
  * @see f_string_dynamic_append()
+ * @see f_string_dynamic_append_nulless()
+ * @see f_string_dynamic_partial_append()
  * @see f_string_dynamic_partial_append_nulless()
  * @see f_string_dynamic_terminate()
+ * @see fl_fss_apply_delimit()
  * @see fll_fss_basic_list_read()
  */
 #ifndef _di_controller_entry_read_
@@ -213,6 +217,10 @@ extern "C" {
  *   The range in the list buffer representing the content.
  * @param cache
  *   A structure for containing and caching relevant data.
+ *
+ *   Errors (with error bit) from: controller_entry_print_error_file().
+ *
+ * @see controller_entry_print_error_file()
  */
 #ifndef _di_controller_entry_settings_read_
   extern f_status_t controller_entry_settings_read(const controller_global_t global, const bool is_entry, const f_string_range_t content_range, controller_cache_t * const cache) F_attribute_visibility_internal_d;
index 9c4c42e8a9e42568463c0f1bd60af765bdecc549..4b041aa18326a9307954a475be653ca70203e17c 100644 (file)
@@ -143,6 +143,23 @@ extern "C" {
   }
 #endif // _di_controller_entry_setting_read_print_error_with_range_
 
+#ifndef _di_controller_entry_settings_read_print_setting_ignored_
+  void controller_entry_settings_read_print_setting_ignored(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_array_length_t index) {
+
+    if (global.main->warning.verbosity != f_console_verbosity_debug_e) return;
+
+    controller_lock_print(global.main->warning.to, global.thread);
+
+    fl_print_format("%r%[%QThe %Q item setting '%]", global.main->warning.to.stream, f_string_eol_s, global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context);
+    fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.action.name_action, global.main->warning.notable);
+    fl_print_format("%[' is being ignored.%]%r", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s);
+
+    controller_entry_print_error_cache(is_entry, global.main->warning, cache.action);
+
+    controller_unlock_print_flush(global.main->warning.to, global.thread);
+  }
+#endif // _di_controller_entry_settings_read_print_setting_ignored_
+
 #ifndef _di_controller_entry_settings_read_print_setting_requires_exactly_
   void controller_entry_settings_read_print_setting_requires_exactly(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_number_unsigned_t total) {
 
@@ -188,8 +205,8 @@ extern "C" {
 
     fl_print_format("%r%[%QThe %Q item setting '%]", global.main->warning.to.stream, f_string_eol_s, global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context);
     fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.action.name_action, global.main->warning.notable);
-    fl_print_format("%[' has an unknown value '%]", global.main->warning.to.stream, f_string_eol_s, global.main->warning.context, global.main->warning.context);
-    fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.content_actions.array[index].array[0], global.main->warning.notable);
+    fl_print_format("%[' has an unknown value '%]", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context);
+    fl_print_format("%[%/Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.buffer_file, cache.content_actions.array[index].array[0], global.main->warning.notable);
     fl_print_format("%['.%]%r", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s);
 
     controller_entry_print_error_cache(is_entry, global.main->warning, cache.action);
index 01cdd7d813f397abece6622371d389cf2ec3db39..270316e450b4cc2493bb2171839152ac51f7e2ba 100644 (file)
@@ -179,6 +179,23 @@ extern "C" {
 #endif // _di_controller_entry_setting_read_print_error_with_range_
 
 /**
+ * Print a message for when an entry setting is being ignored.
+ *
+ * @param global
+ *   The global data.
+ * @param is_entry
+ *   If TRUE, then this loads as an entry.
+ *   If FALSE, then this loads as an exit.
+ * @param cache
+ *   A structure for containing and caching relevant data.
+ * @param total
+ *   The expected number of arguments.
+ */
+#ifndef _di_controller_entry_settings_read_print_setting_ignored_
+  extern void controller_entry_settings_read_print_setting_ignored(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_array_length_t index) F_attribute_visibility_internal_d;
+#endif // _di_controller_entry_settings_read_print_setting_ignored_
+
+/**
  * Print a message for when an entry setting action has the incorrect number of parameters.
  *
  * @param global
index cb0dd3d84783f6606d1be9500dca3e5bdaf7a69d..77c3d525c91c449edc3d58d4a05dda5adebbfe5f 100644 (file)
@@ -1539,10 +1539,10 @@ extern "C" {
       return F_status_set_error(F_file_found);
     }
 
-    status = controller_dynamic_append_terminated(pid_file, child_pid_file);
+    status = f_string_dynamic_append_nulless(pid_file, child_pid_file);
 
     if (F_status_is_error(status)) {
-      controller_print_error(thread, main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true);
+      controller_print_error(thread, main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true);
 
       return status;
     }
@@ -1912,10 +1912,10 @@ extern "C" {
       cache->action.line_action += ++item->line;
       cache->action.name_action.used = 0;
 
-      status = controller_dynamic_rip_nulless_terminated(cache->buffer_item, cache->range_action, &cache->action.name_action);
+      status = fl_string_dynamic_partial_rip_nulless(cache->buffer_item, cache->range_action, &cache->action.name_action);
 
       if (F_status_is_error(status)) {
-        controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true);
+        controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true);
 
         break;
       }
@@ -3383,10 +3383,10 @@ extern "C" {
 
           rule->items.array[rule->items.used].line = ++cache->action.line_item;
 
-          status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_items.array[i], &cache->action.name_item);
+          status = fl_string_dynamic_partial_rip_nulless(cache->buffer_file, cache->object_items.array[i], &cache->action.name_item);
 
           if (F_status_is_error(status)) {
-            controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true);
+            controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true);
 
             break;
           }
@@ -4197,7 +4197,7 @@ extern "C" {
         }
 
         if (type == controller_rule_setting_type_name_e || type == controller_rule_setting_type_script_e) {
-          status = controller_dynamic_rip_nulless_terminated(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value);
+          status = fl_string_dynamic_partial_rip_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value);
 
           if (F_status_is_error(status)) {
             setting_value->used = 0;
@@ -4537,10 +4537,10 @@ extern "C" {
 
             cache->action.generic.used = 0;
 
-            status = controller_dynamic_rip_nulless_terminated(cache->buffer_item, cache->content_actions.array[i].array[1], &cache->action.generic);
+            status = fl_string_dynamic_partial_rip_nulless(cache->buffer_item, cache->content_actions.array[i].array[1], &cache->action.generic);
 
             if (F_status_is_error(status)) {
-              controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true);
+              controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_string_dynamic_partial_rip_nulless", F_true);
 
               break;
             }
index ba2a7baec1637a540a062e53fd1deea5f7272d1e..76da84014898eb6288620c44057eb58308df450a 100644 (file)
@@ -706,14 +706,16 @@ extern "C" {
  *   Errors (with error bit) from: f_string_dynamics_increase().
  *   Errors (with error bit) from: f_string_maps_increase().
  *   Errors (with error bit) from: fll_fss_extended_read().
- *   Errors (with error bit) from: fll_path_canonical().
+ *
+ *   Errors (with error bit) from: controller_path_canonical_relative().
  *
  * @see f_string_dynamic_partial_append_nulless()
  * @see f_string_dynamics_increase()
  * @see f_string_maps_increase()
  * @see fl_string_dynamic_partial_rip_nulless()
  * @see fll_fss_extended_read()
- * @see fll_path_canonical()
+ *
+ * @see controller_path_canonical_relative()
  */
 #ifndef _di_controller_rule_setting_read_
   extern f_status_t controller_rule_setting_read(const controller_global_t global, const bool is_normal, const controller_setting_t setting, controller_cache_t * const cache, controller_rule_t * const rule) F_attribute_visibility_internal_d;
index 03793e5c30d155c055d3a3ff3e1177c6069e7829..c22112f94565d5fd4ea6402e6efaf8325b49f1c6 100644 (file)
@@ -1,8 +1,15 @@
 # fss-0005
 
+setting:
+  control controller/run/up.socket
+  pid ready
+  pid_file controller/run/up.pid
+
 main:
   failsafe maintenance
 
+  start script create_socket_path
+
   ready
 
 maintenance:
diff --git a/level_3/controller/data/settings/example/rules/script/create_socket_path.rule b/level_3/controller/data/settings/example/rules/script/create_socket_path.rule
new file mode 100644 (file)
index 0000000..b689b60
--- /dev/null
@@ -0,0 +1,14 @@
+# fss-000d
+
+setting:
+  name "Create Socket Path"
+
+  parameter verbose -v
+  parameter socket controller/run/
+
+script:
+  start {
+    if [[ ! -d "parameter:"socket"" ]] ; then
+      mkdir parameter:"verbose" -p parameter:"socket"
+    fi
+  }
index 3c66e43636f1feb154e33b3f1e235c84ef53a050..764cf35f5e4b0519eca0fe1571218f9c1508651f 100644 (file)
@@ -17,7 +17,7 @@ Entry Documentation:
   - The "setting" item Object\:
     Represents settings and is not an "item" that can be executed.
     A number of settings are supported, but if this Item Object is not specified, then defaults are used.
-    The following settings are available: "mode", "pid", "session", and "show".
+    The following settings are available: "mode", "pid", "pid_file", "session", and "show".
 
     - The "mode" setting\:
       Represents the mode in which the Entry is operating in.
@@ -41,6 +41,10 @@ Entry Documentation:
       For "require", check to see if the PID file exists for an entry at startup and then when "ready" create a pid file, display error on pid file already exists or on failure and then fail.
       For "ready", when "ready" create a pid file, display error on failure and then fail (does not check if PID file exists).
 
+    - The "pid_file" setting\:
+      When "pid" is not disabed this represents the path to the pid file.
+      If -p or --pid is passed to the controller program, then this value is ignored in favor of the value passed along the command line.
+
     - The "session" setting\:
       Represents the default way in which child processes are executed.
       This default can be overriden by individual Rules.
@@ -66,6 +70,8 @@ Entry Documentation:
       This should be possible in the cases of file systems that have pre-created a socket file at the designated path.
       When "readonly", the group, mode, and user are also not processed effectively resulting in the "control_group", "control_mode", and "control_user" settings being ignored.
 
+      Future versions might expand this into supporting network addresses in addition to socket files.
+
     - The "control_group" setting\:
       Represents the group name or group ID to assign to the socket file as the group.
 
index be7e850907490f8fee4f6254692bf2edb3f3f39b..7434a40c2b72cc2775f765da0da4368c1f915699 100644 (file)
@@ -19,7 +19,7 @@ Rule Documentation:
     - "name": A name used to represent this rule, which is printed to the user, screen, logs, etc...
     - "nice": A single niceness value to run all processes executed within this rule as (-20 gets to be greediest in CPU usage and 19 being the nicest in CPU usage).
     - "on": Define a Rule Action in which a specified dependency is needed, wanted, or wished for.
-    - "parameter": A statically defined IKI name and its associated value for use in this rule file. @todo make sure this is implemented and make sure to perform iki substitutions (with "define" being a reserved iki parameter name for environment variable usage, such as define:"PATH").
+    - "parameter": A statically defined IKI name and its associated value for use in this rule file.
     - "path": A single Content used to set a custom PATH environment variable value.
     - "script": An executable name of a script, such as "bash", to use for the "script" Rule Type (which likely defaults to "bash" if not specified).
     - "scheduler": A valid name of a scheduler to use followed by an optional priority number.
@@ -66,7 +66,6 @@ Rule Documentation:
     These parameters are only exposed in the specific rule file in which they are defined and cannot be shared between rules.
     A "parameter" variable and an "environment" variable are mutually exclusive but an environment variable, in theory, can have an IKI variable assigned to it inside of a "script".
     These IKI variables are only substituted within a Rule Item's Content (and not within a Rule Setting nor within a Rule Item's Object).
-    Note: IKI variables are not yet implemented.
 
   - In the case of "scheduler"\:
     The valid range of the priority number is dependent on the scheduler.
index 441d0d76a54b74e4ef66b59b6871beaa382a67b9..1b4ed29174d28053fdabd8e543f4ebb6b8e2ef6b 100644 (file)
@@ -24,6 +24,7 @@ Entry Specification:
     - "setting": optional, Actions may be one of\:
       - "mode": Exactly one Content that is one of "program" or "service".
       - "pid": Exactly one Content that is one of "disable", "require", or "ready".
+      - "pid_file": Exactly one Content that is a relative or absolute path to a pid file.
       - "session": Exactly one Content that is one of "new" or "same".
       - "show": Exactly one Content that is one of "normal" or "init".
       - "control": One to two Content.