]> Kevux Git Server - fll/commitdiff
Update: rewrite the execute functions to accept a parameter structure.
authorKevin Day <thekevinday@gmail.com>
Sat, 19 Dec 2020 04:55:00 +0000 (22:55 -0600)
committerKevin Day <thekevinday@gmail.com>
Sat, 19 Dec 2020 04:55:00 +0000 (22:55 -0600)
This changes the programs so that the execute function that handles piping data to the child in a separate function to normal execute function.
This happens via a private function and is therefore transparent to the caller.

The caller can select options to pass to tweak the operation of the execute function.
While I do not like using structures in this way as it complicate the code in one respect, in another respect it simplifies things.
There are also fewer parameters passed which is easier on the registers.

The f_execute_asynchronous_t structure is not needed with this design.
Future changes will include a new project (likely called f_asynchronous) to assist in performing asynchronous tasks.

Note: this go around I am trying constant pointers.
This makes it compatible when passing constants through.

20 files changed:
build/level_1/settings
build/monolithic/settings
build/scripts/bootstrap-example.sh
level_0/f_execute/c/execute-common.h
level_1/fl_execute/c/execute-common.h [new file with mode: 0644]
level_1/fl_execute/c/execute.h [new file with mode: 0644]
level_1/fl_execute/data/build/defines [new file with mode: 0644]
level_1/fl_execute/data/build/dependencies [new file with mode: 0644]
level_1/fl_execute/data/build/settings [new file with mode: 0644]
level_2/fll_execute/c/execute.c
level_2/fll_execute/c/execute.h
level_2/fll_execute/c/private-execute.c
level_2/fll_execute/c/private-execute.h
level_2/fll_execute/data/build/dependencies
level_3/controller/c/private-rule.c
level_3/fake/c/private-build.c
level_3/fake/c/private-fake.c
level_3/fake/c/private-make.c
level_3/firewall/c/firewall.c
level_3/firewall/c/private-firewall.c

index 730ed90a5702dd9377da56f15ad48ab152911894..a7d23f075e875c917d3ba3625d97f91afca650cc 100644 (file)
@@ -22,7 +22,7 @@ build_libraries -lc
 build_libraries-level -lfll_0
 build_sources_library color.c console.c conversion.c directory.c private-directory.c environment.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c iki.c print.c private-print.c status.c string.c private-string.c type.c private-type.c utf.c private-utf.c utf_file.c private-utf_file.c
 build_sources_program
-build_sources_headers color.h console.h conversion.h directory.h environment.h fss.h fss_basic.h fss_basic_list.h fss_embedded_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h print.h status.h string.h type.h utf.h utf_file.h
+build_sources_headers color.h console.h conversion.h directory.h environment.h execute.h execute-common.h fss.h fss_basic.h fss_basic_list.h fss_embedded_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h print.h status.h string.h type.h utf.h utf_file.h
 build_sources_script
 build_sources_setting
 build_script yes
index 95f8c489d8a8b06b3775cf583dd327827fefd395..07bdd4572d2f5e04d0256cce3be08af95f03c929 100644 (file)
@@ -22,7 +22,7 @@ build_libraries -lc
 build_libraries-monolithic
 build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/process.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/private-print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/type.c level_1/private-type.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c
 build_sources_program
-build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/process.h level_0/process-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/type.h level_1/utf.h level_1/utf_file.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h
+build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/process.h level_0/process-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/type.h level_1/utf.h level_1/utf_file.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h
 build_sources_script
 build_sources_setting
 build_script yes
index f0ad295b59c27810e483b1091009a9eff1b4c7cc..43208101665cbd7f0656620cb7ee0b59e0290862 100644 (file)
@@ -41,7 +41,7 @@ if [[ $1 == "individual" ]] ; then
   bash build/scripts/package.sh $verbose $color build -i
 
   if [[ $? -eq 0 ]] ; then
-    for i in f_type f_status f_memory f_string f_utf f_account f_color f_console f_conversion f_directory f_environment f_file f_fss f_iki f_path f_pipe f_print f_serialize f_signal f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_fss fl_iki fl_print fl_status fl_string fl_type fl_utf fl_utf_file fll_error fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do
+    for i in f_type f_status f_memory f_string f_utf f_account f_color f_console f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_path f_pipe f_print f_process f_serialize f_signal f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_print fl_status fl_string fl_type fl_utf fl_utf_file fll_error fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do
       echo && echo "Processing $i." &&
 
       cd package/individual/$i-$2/ &&
index 5e5ed2793417cd5e7504362f75bc7a93f39693d4..52dfedbe715a62ec464d85854fcf3ee0482a3f82 100644 (file)
 extern "C" {
 #endif
 
-/**
- * A structure for use in processing asynchronous execute behavior.
- *
- * Future versions may suppot stdwarn and stddebug if there ever is such a thing.
- *
- * Descriptors always use -1 to designate not used because 0 represent a valid descriptor.
- * The process ID always uses -1 to designate no valid process ID is set.
- *
- * input:   the input file descriptor.
- * output:  the output file descriptor.
- * error:   the error file descriptor.
- * process: the process ID whereas 0 represents a parent and anything greater than 0 represents a child.
- */
-#ifndef _di_f_execute_asynchronous_t_
-  typedef struct {
-    int input;
-    int output;
-    int error;
-    int process;
-  } f_execute_asynchronous_t;
-
-  #define f_execute_asynchronous_t_initialize { -1, -1, -1, -1 }
-
-  #define f_execute_asynchronous_t_clear(set) \
-    set.input = -1; \
-    set.output = -1; \
-    set.error = -1; \
-    set.process = -1;
-#endif // _di_f_execute_asynchronous_t_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/level_1/fl_execute/c/execute-common.h b/level_1/fl_execute/c/execute-common.h
new file mode 100644 (file)
index 0000000..d31e0ff
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Execute
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Defines common data to be used for/by project execute.
+ *
+ * This is auto-included by execute.h and should not need to be explicitly included.
+ */
+#ifndef _FL_execute_common_h
+#define _FL_execute_common_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A structure for containing additional parameters for the execute functions that call the execv() family of functions.
+ *
+ * bitwise options:
+ *   fl_execute_parameter_option_exit: use to desginate to exit after calling child otherwise child process will return.
+ *   fl_execute_parameter_option_path: use to designate that this is a path to a program (such as '/bin/bash').
+ *
+ * option:  accepts the bitwise options
+ * names:   the environment variable names, should have the same number of elements as values, set to 0 to not use.
+ * values:  the environment variable values, should have the same number of elements as names, set to 0 to not use.
+ * signals: the set of signals the child process should or should block, set to 0 to not use.
+ * data:    the data to pipe to the child process, set to 0 to not use.
+ */
+#ifndef _di_fl_execute_parameter_t_
+  #define fl_execute_parameter_option_exit 0x1
+  #define fl_execute_parameter_option_path 0x2
+
+  typedef struct {
+    uint8_t option;
+
+    const f_string_statics_t *names;
+    const f_string_statics_t *values;
+    const f_signal_how_t *signals;
+    const f_string_static_t *data;
+  } fl_execute_parameter_t;
+
+  #define fl_execute_parameter_t_initialize { 0, 0, 0, 0, 0 }
+
+  #define fl_macro_execute_parameter_t_initialize(option, names, values, signals, data) { option, names, values, signals, data }
+
+  #define fl_execute_parameter_t_clear(set) \
+    set.option = 0; \
+    set.names = 0; \
+    set.values = 0; \
+    set.signals = 0; \
+    set.data = 0;
+#endif // _di_fl_execute_parameter_t_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FL_execute_common_h
diff --git a/level_1/fl_execute/c/execute.h b/level_1/fl_execute/c/execute.h
new file mode 100644 (file)
index 0000000..ed970c0
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Execute
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides execute processing functionality.
+ */
+#ifndef _FL_execute_h
+#define _FL_execute_h
+
+// libc includes
+
+// fll-0 includes
+#include <level_0/type.h>
+#include <level_0/status.h>
+#include <level_0/execute.h>
+#include <level_0/signal.h>
+
+// fll-1 execute includes
+#include <level_1/execute-common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FL_execute_h
diff --git a/level_1/fl_execute/data/build/defines b/level_1/fl_execute/data/build/defines
new file mode 100644 (file)
index 0000000..4f13080
--- /dev/null
@@ -0,0 +1 @@
+# fss-0000
diff --git a/level_1/fl_execute/data/build/dependencies b/level_1/fl_execute/data/build/dependencies
new file mode 100644 (file)
index 0000000..ded2e76
--- /dev/null
@@ -0,0 +1,7 @@
+# fss-0000
+
+f_type
+f_status
+f_string
+f_signal
+f_execute
diff --git a/level_1/fl_execute/data/build/settings b/level_1/fl_execute/data/build/settings
new file mode 100644 (file)
index 0000000..312de21
--- /dev/null
@@ -0,0 +1,55 @@
+# fss-0001
+
+project_name fl_execute
+
+version_major 0
+version_minor 5
+version_micro 2
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_language c
+build_libraries -lc
+build_libraries-individual -lf_memory -lf_signal
+build_sources_library
+build_sources_program
+build_sources_headers execute.h execute-common.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static yes
+
+path_headers level_0
+path_headers_preserve no
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+path_sources
+path_standard yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g -fdiagnostics-color=always
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE
index 948e98aa1e438ae79b03c7ce9b960517ea843f50..0bb927e458572c9416ecb08dbcb55a832cc93ed5 100644 (file)
@@ -129,195 +129,131 @@ extern "C" {
   }
 #endif // _di_fll_execute_arguments_dynamic_add_set_
 
-#ifndef _di_fll_execute_path_
-  f_return_status fll_execute_path(const f_string_t program_path, const f_string_statics_t arguments, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result) {
+#ifndef _di_fll_execute_program_
+  f_return_status fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, int *result) {
     #ifndef _di_level_2_parameter_checking_
       if (!result) return F_status_set_error(F_parameter);
+
+      if (parameter && parameter->names) {
+        if (!parameter->values || parameter->names->used != parameter->values->used) {
+          return F_status_set_error(F_parameter);
+        }
+      }
     #endif // _di_level_2_parameter_checking_
 
     // create a string array that is compatible with execv() calls.
     f_string_t fixed_arguments[arguments.used + 2];
 
-    const f_string_t last_slash = strrchr(program_path, '/');
-    const f_string_length_t name_size = last_slash ? strnlen(last_slash, f_path_max) : strnlen(program_path, f_path_max);
+    const f_string_t last_slash = strrchr(program, f_path_separator_s[0]);
+    const f_string_length_t name_size = last_slash ? strnlen(last_slash, f_path_max) : strnlen(program, f_path_max);
 
     char program_name[name_size + 1];
 
     program_name[name_size] = 0;
 
-    private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program_path, arguments, name_size, program_name, fixed_arguments);
+    private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program, arguments, name_size, program_name, fixed_arguments);
+
+    // when the environment is to be cleared, a full path must be used.
+    if (parameter && !(parameter->option & fl_execute_parameter_option_path) && parameter->names) {
+      f_string_dynamic_t path = f_string_dynamic_t_initialize;
+      f_string_dynamics_t paths = f_string_dynamics_t_initialize;
 
-    {
-      const f_status_t status = f_file_exists(program_path);
+      f_status_t status = f_environment_get(f_path_environment_s, &path);
 
       if (F_status_is_error(status)) {
-        return status;
+
+        // Do not consider PATH is not available (or valid?) to be an error.
+        if (F_status_set_fine(status) == F_valid_not || F_status_set_fine(status) == F_failure) {
+          status = F_none;
+        }
       }
-      else if (status == F_false) {
-        return F_status_set_error(F_file_found_not);
+      else {
+        status = fl_environment_path_explode_dynamic(path, &paths);
       }
-    }
-
-    return private_fll_execute_fork(program_name, fixed_arguments, F_false, signals, pipe, result);
-  }
-#endif // _di_fll_execute_path_
-
-#ifndef _di_fll_execute_path_environment_
-  f_return_status fll_execute_path_environment(const f_string_t program_path, const f_string_statics_t arguments, const f_string_statics_t names, const f_string_statics_t values, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result) {
-    #ifndef _di_level_2_parameter_checking_
-      if (!result) return F_status_set_error(F_parameter);
-    #endif // _di_level_2_parameter_checking_
-
-    // create a string array that is compatible with execv() calls.
-    f_string_t fixed_arguments[arguments.used + 2];
-
-    const f_string_t last_slash = strrchr(program_path, '/');
-    const f_string_length_t name_size = last_slash ? strnlen(last_slash, f_path_max) : strnlen(program_path, f_path_max);
-
-    char program_name[name_size + 1];
-
-    private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program_path, arguments, name_size, program_name, fixed_arguments);
-
-    {
-      const f_status_t status = f_file_exists(program_path);
 
       if (F_status_is_error(status)) {
+        fl_string_dynamic_delete(&path);
+        fl_string_dynamics_delete(&paths);
+
         return status;
       }
-      else if (status == F_false) {
-        return F_status_set_error(F_file_found_not);
-      }
-    }
-
-    return private_fll_execute_fork_environment(program_name, fixed_arguments, F_false, names, values, signals, pipe, result);
-  }
-#endif // _di_fll_execute_path_environment_
-
-#ifndef _di_fll_execute_program_
-  f_return_status fll_execute_program(const f_string_t program_name, const f_string_statics_t arguments, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result) {
-    #ifndef _di_level_2_parameter_checking_
-      if (!result) return F_status_set_error(F_parameter);
-    #endif // _di_level_2_parameter_checking_
-
-    // create a string array that is compatible with execv() calls.
-    f_string_t fixed_arguments[arguments.used + 2];
-
-    fixed_arguments[0] = program_name;
-
-    for (f_array_length_t i = 0; i < arguments.used; i++) {
-      fixed_arguments[i + 1] = arguments.array[i].string;
-    } // for
-
-    // insert the required array terminated.
-    fixed_arguments[arguments.used + 1] = 0;
-
-    return private_fll_execute_fork(program_name, fixed_arguments, F_true, signals, pipe, result);
-  }
-#endif // _di_fll_execute_program_
-
-#ifndef _di_fll_execute_program_environment_
-  f_return_status fll_execute_program_environment(const f_string_t program_name, const f_string_statics_t arguments, const f_string_statics_t names, const f_string_statics_t values, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result) {
-    #ifndef _di_level_2_parameter_checking_
-      if (!result) return F_status_set_error(F_parameter);
-    #endif // _di_level_2_parameter_checking_
-
-    // create a string array that is compatible with execv() calls.
-    f_string_t fixed_arguments[arguments.used + 2];
-
-    fixed_arguments[0] = program_name;
-
-    for (f_array_length_t i = 0; i < arguments.used; i++) {
-      fixed_arguments[i + 1] = arguments.array[i].string;
-    } // for
-
-    // insert the required array terminated.
-    fixed_arguments[arguments.used + 1] = 0;
-
-    f_string_dynamic_t path = f_string_dynamic_t_initialize;
-    f_string_dynamics_t paths = f_string_dynamics_t_initialize;
 
-    f_status_t status = f_environment_get("PATH", &path);
+      f_macro_string_dynamic_t_delete(status, path);
 
-    if (F_status_is_error(status)) {
+      if (F_status_is_error(status)) {
+        f_macro_string_dynamics_t_delete_simple(paths);
 
-      // Do not consider PATH is not available (or valid?) to be an error.
-      if (F_status_set_fine(status) == F_valid_not || F_status_set_fine(status) == F_failure) {
-        status = F_none;
+        return status;
       }
-    }
-    else {
-      status = fl_environment_path_explode_dynamic(path, &paths);
-    }
-
-    if (F_status_is_error(status)) {
-      fl_string_dynamic_delete(&path);
-      fl_string_dynamics_delete(&paths);
-      return status;
-    }
 
-    f_macro_string_dynamic_t_delete(status, path);
-
-    if (F_status_is_error(status)) {
-      f_macro_string_dynamics_t_delete_simple(paths);
-      return status;
-    }
+      f_string_dynamic_t *found = 0;
 
-    const f_string_length_t program_name_length = strnlen(program_name, f_path_max);
-    f_string_dynamic_t *found = 0;
+      for (f_array_length_t i = 0; i < paths.used; i++) {
 
-    for (f_array_length_t i = 0; i < paths.used; i++) {
+        status = fl_string_append(program_name, name_size, &paths.array[i]);
 
-      status = fl_string_append(program_name, program_name_length, &paths.array[i]);
+        if (F_status_is_error_not(status)) {
+          status = fl_string_dynamic_terminate(&paths.array[i]);
+        }
 
-      if (F_status_is_error_not(status)) {
-        status = fl_string_dynamic_terminate(&paths.array[i]);
-      }
+        if (F_status_is_error_not(status)) {
+          status = f_file_exists(paths.array[i].string);
 
-      if (F_status_is_error_not(status)) {
-        status = f_file_exists(paths.array[i].string);
+          if (status == F_true) {
+            found = &paths.array[i];
+            break;
+          }
 
-        if (status == F_true) {
-          found = &paths.array[i];
-          break;
+          if (F_status_is_error(status)) {
+            status = F_status_set_fine(status);
+
+            // don't consider bad/non-accessible paths an error, just ignore them.
+            if (status == F_name) {
+              continue;
+            }
+            else if (status == F_directory) {
+              continue;
+            }
+            else if (status == F_access_denied) {
+              continue;
+            }
+          }
         }
 
         if (F_status_is_error(status)) {
-          status = F_status_set_fine(status);
+          fl_string_dynamics_delete(&paths);
 
-          // don't consider bad/non-accessible paths an error, just ignore them.
-          if (status == F_name) {
-            continue;
-          }
-          else if (status == F_directory) {
-            continue;
-          }
-          else if (status == F_access_denied) {
-            continue;
-          }
+          return status;
         }
-      }
+      } // for
 
-      if (F_status_is_error(status)) {
+      if (!found) {
         fl_string_dynamics_delete(&paths);
-        return status;
+
+        return F_status_set_error(F_file_found_not);
       }
-    } // for
 
-    if (!found) {
-      fl_string_dynamics_delete(&paths);
-      return F_status_set_error(F_file_found_not);
-    }
+      char program_path[found->used];
 
-    char program_path[found->used];
+      memcpy(&program_path, found->string, found->used);
 
-    memcpy(&program_path, found->string, found->used);
+      status = fl_string_dynamics_delete(&paths);
+      if (F_status_is_error(status)) return status;
 
-    status = fl_string_dynamics_delete(&paths);
-    if (F_status_is_error(status)) return status;
+      if (parameter && parameter->data) {
+        return private_fll_execute_fork_data(program_path, fixed_arguments, parameter, result);
+      }
 
-    return private_fll_execute_fork_environment(program_name, fixed_arguments, F_true, names, values, signals, pipe, result);
+      return private_fll_execute_fork(program_path, fixed_arguments, parameter, result);
+    }
+
+    if (parameter && parameter->data) {
+      return private_fll_execute_fork_data(program, fixed_arguments, parameter, result);
+    }
+
+    return private_fll_execute_fork(program, fixed_arguments, parameter, result);
   }
-#endif // _di_fll_execute_program_environment_
+#endif // _di_fll_execute_program_
 
 #ifdef __cplusplus
 } // extern "C"
index 64e7de94fa55f460cd8b81f16600a869f35c44c7..4631cac6ec03a35d8da064e21b6dfa3ded6839a6 100644 (file)
@@ -32,6 +32,7 @@
 
 // fll-1 includes
 #include <level_1/environment.h>
+#include <level_1/execute.h>
 #include <level_1/string.h>
 
 #ifdef __cplusplus
@@ -329,191 +330,40 @@ extern "C" {
 #endif // _di_fll_execute_arguments_dynamic_add_set_
 
 /**
- * Execute a program given some path + program name (such as "/bin/bash").
+ * Execute a program given by program name found in the PATH environment (such as "bash") or program path (such as "/bin/bash").
  *
- * This does validate that the program path exists.
+ * If parameter.names is specified:
+ *   Uses the provided environment array to designate the environment for the program being executed.
+ *   The environment is defined by the names and values pair.
+ *   This requires paramete.values to also be specified with the same used length as parameter.names.
  *
- * This does not call exit() when the child process exits.
- * Instead, this returns F_child and assigns the child's return code to result for the child process.
- * The caller is expected to handle the appropriate exit procedures and memory deallocation for the child process.
+ * When parameter.option has the fl_execute_parameter_option_path bit set, then this does validate the path to the program.
+ * Otherwise, this does not validate the path to the program.
  *
- * @param program_path
- *   The entire path to the program.
- * @param arguments
- *   An array of strings representing the arguments.
- * @param signals
- *   (optional) A pointer to the set of signals.
- *   Set to 0 to disable.
- * @param pipe
- *   (optional) A pointer to a string to pipe as standard input to the child process.
- *   Set to 0 to disable.
- * @param result
- *   The code returned after finishing execution of program_path.
- *
- * @return
- *   F_none on success.
- *   F_child on success but this is the child thread.
- *   F_failure (with error bit) on execution failure.
- *   F_fork (with error bit) on fork failure.
- *   F_pipe (with error bit) on pipe failure.
- *
- *   Errors (with error bit) from: f_file_exists().
- *   Errors (with error bit) from: f_signal_set_handle().
- *
- * @see close()
- * @see dup2()
- * @see execv()
- * @see execvp()
- * @see fork()
- * @see pipe()
- * @see waitpid()
- *
- * @see f_file_exists()
- * @see f_signal_set_handle()
- */
-#ifndef _di_fll_execute_path_
-  extern f_return_status fll_execute_path(const f_string_t program_path, const f_string_statics_t arguments, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result);
-#endif // _di_fll_execute_path_
-
-/**
- * Execute a program given some path + program name (such as "/bin/bash").
- *
- * Uses the provided environment array to designate the environment for the program being executed.
- * The environment is defined by the names and values pair.
- *
- * This does validate that the program path exists.
+ * When the parameter.option has the fl_execute_parameter_option_exit bit set, then this calls exit() when the child process returns.
+ * Otherwise, this returns F_child and assigns the child's return code to result for the child process.
+ * The caller is expected to handle the appropriate exit procedures and memory deallocation for the child process when F_child is returned.
  *
- * This does not call exit() when the child process exits.
- * Instead, this returns F_child and assigns the child's return code to result for the child process.
- * The caller is expected to handle the appropriate exit procedures and memory deallocation for the child process.
- *
- * @param program_path
- *   The entire path to the program.
+ * @param program
+ *   The name or path of the program.
  * @param arguments
  *   An array of strings representing the arguments.
- * @param names
- *   An array of strings representing the environment variable names.
- *   At most names.used variables are created.
- *   Duplicate names are overwritten.
- * @param values
- *   An array of strings representing the environment variable names.
- *   The values.used must be of at least names.used.
- *   Set individual strings.used to 0 for empty/NULL values.
- * @param signals
- *   (optional) A pointer to the set of signals.
- *   Set to 0 to disable.
- * @param pipe
- *   (optional) A pointer to a string to pipe as standard input to the child process.
- *   Set to 0 to disable.
- * @param result
- *   The code returned after finishing execution of program_path.
- *
- * @return
- *   F_none on success.
- *   F_child on success but this is the child thread.
- *   F_failure (with error bit) on execution failure.
- *   F_fork (with error bit) on fork failure.
- *   F_pipe (with error bit) on pipe failure.
- *
- *   Errors (with error bit) from: f_environment_set_dynamic().
- *   Errors (with error bit) from: f_file_exists().
- *   Errors (with error bit) from: f_signal_set_handle().
- *
- * @see close()
- * @see clearenv()
- * @see dup2()
- * @see execvp()
- * @see fork()
- * @see memcpy()
- * @see pipe()
- * @see strnlen()
- * @see waitpid()
- *
- * @see f_environment_set_dynamic()
- * @see f_file_exists()
- * @see f_signal_set_handle()
- */
-#ifndef _di_fll_execute_path_environment_
-  extern f_return_status fll_execute_path_environment(const f_string_t program_path, const f_string_statics_t arguments, const f_string_statics_t names, const f_string_statics_t values, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result);
-#endif // _di_fll_execute_path_environment_
-
-/**
- * Execute a program given by name found in the PATH environment (such as "bash").
- *
- * This does not validate the path to the program.
- *
- * This does not call exit() when the child process exits.
- * Instead, this returns F_child and assigns the child's return code to result for the child process.
- * The caller is expected to handle the appropriate exit procedures and memory deallocation for the child process.
- *
- * @param program_name
- *   The name of the program.
- * @param arguments
- *   An array of strings representing the arguments.
- * @param signals
- *   (optional) A pointer to the set of signals.
- *   Set to 0 to disable.
- * @param pipe
- *   (optional) A pointer to a string to pipe as standard input to the child process.
- *   Set to 0 to disable.
- * @param result
- *   The code returned after finishing execution of program.
- *
- * @return
- *   F_none on success.
- *   F_child on success but this is the child thread.
- *   F_failure (with error bit) on execution failure.
- *   F_fork (with error bit) on fork failure.
- *   F_pipe (with error bit) on pipe failure.
- *
- *   Errors (with error bit) from: f_file_exists().
- *   Errors (with error bit) from: f_signal_set_handle().
- *
- * @see close()
- * @see dup2()
- * @see execv()
- * @see execvp()
- * @see fork()
- * @see pipe()
- * @see waitpid()
- *
- * @see f_file_exists()
- * @see f_signal_set_handle()
- */
-#ifndef _di_fll_execute_program_
-  extern f_return_status fll_execute_program(const f_string_t program_name, const f_string_statics_t arguments, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result);
-#endif // _di_fll_execute_program_
-
-/**
- * Execute a program given by name found in the PATH environment (such as "bash").
- *
- * Uses the provided environment array to designate the environment for the program being executed.
- * The environment is defined by the names and values pair.
- *
- * This does not validate the path to the program.
- *
- * This does not call exit() when the child process exits.
- * Instead, this returns F_child and assigns the child's return code to result for the child process.
- * The caller is expected to handle the appropriate exit procedures and memory deallocation for the child process.
- *
- * @param program_name
- *   The name of the program.
- * @param arguments
- *   An array of strings representing the arguments.
- * @param names
- *   An array of strings representing the environment variable names.
- *   At most names.used variables are created.
- *   Duplicate names are overwritten.
- * @param values
- *   An array of strings representing the environment variable names.
- *   The values.used must be of at least names.used.
- *   Set individual strings.used to 0 for empty/null values.
- * @param signals
- *   (optional) A pointer to the set of signals.
- *   Set to 0 to disable.
- * @param pipe
- *   (optional) A pointer to a string to pipe as standard input to the child process.
- *   Set to 0 to disable.
+ * @param parameter
+ *   (optional) This and each of its fields are optional and are disabled when set to 0.
+ *   names:
+ *     An array of strings representing the environment variable names.
+ *     At most names.used variables are created.
+ *     Duplicate names are overwritten.
+ *   values:
+ *     An array of strings representing the environment variable names.
+ *     The values.used must be of at least names.used.
+ *     Set individual strings.used to 0 for empty/null values.
+ *   signals:
+ *     A pointer to the set of signals to have the child process block or not block.
+ *     When not specified, the child process uses the signal blocking behavior of the parent process.
+ *   data:
+ *     A pointer to a string to pipe as standard input to the child process.
+ *     The parent will block until the standard input is fully read or the child process exits.
  * @param result
  *   The code returned after finishing execution of program.
  *
@@ -536,7 +386,9 @@ extern "C" {
  * @see close()
  * @see clearenv()
  * @see dup2()
+ * @see execv()
  * @see execvp()
+ * @see exit()
  * @see fork()
  * @see memcpy()
  * @see pipe()
@@ -550,9 +402,9 @@ extern "C" {
  * @see fl_string_append()
  * @see fl_string_dynamic_terminate()
  */
-#ifndef _di_fll_execute_program_environment_
-  extern f_return_status fll_execute_program_environment(const f_string_t program_name, const f_string_statics_t arguments, const f_string_statics_t names, const f_string_statics_t values, const f_signal_how_t *signals, f_string_static_t * const pipe, int *result);
-#endif // _di_fll_execute_program_environment_
+#ifndef _di_fll_execute_program_
+  extern f_return_status fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, int *result);
+#endif // _di_fll_execute_program_
 
 #ifdef __cplusplus
 } // extern "C"
index 4f0cc5f46a223249bd6516190e08b853e9b93959..8d7db74e03c879f1f049c568b8c30cb4cf1fc7d3 100644 (file)
@@ -110,106 +110,73 @@ extern "C" {
   }
 #endif // !defined(_di_fll_execute_arguments_add_parameter_) || !defined(_di_fll_execute_arguments_add_parameter_set_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_set_)
 
-#if !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_program_)
-  f_return_status private_fll_execute_fork(const f_string_t program_path, const f_string_t fixed_arguments[], const bool program_is, const f_signal_how_t *signals, f_string_static_t * const pipe_data, int *result) {
-
-    int descriptors[2] = { -1, -1 };
-
-    if (pipe_data) {
-       if (pipe(descriptors) == -1) {
-         return F_status_set_error(F_pipe);
-       }
-    }
+#if !defined(_di_fll_execute_program_)
+  f_return_status private_fll_execute_fork(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, int *result) {
 
     const pid_t process_id = fork();
 
     if (process_id < 0) {
-
-      if (pipe_data) {
-        close(descriptors[0]);
-        close(descriptors[1]);
-      }
-
       return F_status_set_error(F_fork);
     }
 
     if (process_id) {
 
-      // close the read pipe for the parent.
-      close(descriptors[0]);
-    }
-    else {
-
-      // close the write pipe for the child.
-      close(descriptors[1]);
-
-      if (signals) {
-        f_signal_set_handle(SIG_BLOCK, &signals->block);
-        f_signal_set_handle(SIG_UNBLOCK, &signals->block_not);
-      }
+      // have the parent wait for the child process to finish.
+      waitpid(process_id, result, WUNTRACED | WCONTINUED);
 
-      if (pipe_data) {
-        dup2(descriptors[0], f_type_descriptor_input);
-      }
-
-      const int code = program_is ? execvp(program_path, fixed_arguments) : execv(program_path, fixed_arguments);
-
-      // close the write pipe for the child when done.
-      if (pipe_data) {
-        close(descriptors[0]);
-      }
+      // this must explicitly check for 0 (as opposed to checking (!result)).
+      if (result != 0) {
+        if (WIFEXITED(*result)) {
+          return F_none;
+        }
 
-      if (result) {
-        *result = code;
+        return F_status_set_error(F_failure);
       }
 
-      return F_child;
+      return F_none;
     }
 
-    // write all data, if child doesn't read this could block until child closes the pipe.
-    if (pipe_data) {
-      const f_file_t file = f_macro_file_t_initialize(0, descriptors[1], f_file_flag_write_only);
+    if (parameter && parameter->signals) {
+      f_signal_set_handle(SIG_BLOCK, &parameter->signals->block);
+      f_signal_set_handle(SIG_UNBLOCK, &parameter->signals->block_not);
+    }
 
-      f_file_write(file, *pipe_data, 0);
+    if (parameter && parameter->names) {
+      clearenv();
 
-      // close the write pipe for the parent when finished writing.
-      close(descriptors[1]);
+      for (f_array_length_t i = 0; i < parameter->names->used && i < parameter->values->used; i++) {
+        f_environment_set_dynamic(parameter->names->array[i], parameter->values->array[i], F_true);
+      } // for
     }
 
-    // have the parent wait for the child process to finish.
-    waitpid(process_id, result, WUNTRACED | WCONTINUED);
+    const int code = parameter && (parameter->option & fl_execute_parameter_option_path) ? execv(program, fixed_arguments) : execvp(program, fixed_arguments);
 
-    if (result != 0) {
-      if (WIFEXITED(*result)) {
-        return F_none;
-      }
+    if (result) {
+      *result = code;
+    }
 
-      return F_status_set_error(F_failure);
+    if (parameter && parameter->option & fl_execute_parameter_option_exit) {
+      exit(code);
     }
 
-    return F_none;
+    return F_child;
   }
-#endif // !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_program_)
+#endif // !defined(_di_fll_execute_program_)
 
-#if !defined(_di_fll_execute_path_environment_) || !defined(_di_fll_execute_program_environment_)
-  f_return_status private_fll_execute_fork_environment(const f_string_t program_path, const f_string_t fixed_arguments[], const bool program_is, const f_string_statics_t names, const f_string_statics_t values, const f_signal_how_t *signals, f_string_static_t * const pipe_data, int *result) {
+#if !defined(_di_fll_execute_program_)
+  f_return_status private_fll_execute_fork_data(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, int *result) {
 
     int descriptors[2] = { -1, -1 };
 
-    if (pipe_data) {
-       if (pipe(descriptors) == -1) {
-         return F_status_set_error(F_pipe);
-       }
+    if (pipe(descriptors) == -1) {
+      return F_status_set_error(F_pipe);
     }
 
     const pid_t process_id = fork();
 
     if (process_id < 0) {
-
-      if (pipe_data) {
-        close(descriptors[0]);
-        close(descriptors[1]);
-      }
+      close(descriptors[0]);
+      close(descriptors[1]);
 
       return F_status_set_error(F_fork);
     }
@@ -218,65 +185,68 @@ extern "C" {
 
       // close the read pipe for the parent.
       close(descriptors[0]);
-    }
-    else {
-
-      // close the write pipe for the child.
-      close(descriptors[1]);
 
-      if (signals) {
-        f_signal_set_handle(SIG_BLOCK, &signals->block);
-        f_signal_set_handle(SIG_UNBLOCK, &signals->block_not);
-      }
-
-      clearenv();
+      // write all data, if child doesn't read this could block until child closes the pipe.
+      {
+        const f_file_t file = f_macro_file_t_initialize(0, descriptors[1], f_file_flag_write_only);
 
-      for (f_array_length_t i = 0; i < names.used; i++) {
-        f_environment_set_dynamic(names.array[i], values.array[i], F_true);
-      } // for
+        f_file_write(file, *parameter->data, 0);
 
-      if (pipe_data) {
-        dup2(descriptors[0], f_type_descriptor_input);
+        // close the write pipe for the parent when finished writing.
+        close(descriptors[1]);
       }
 
-      const int code = program_is ? execvp(program_path, fixed_arguments) : execv(program_path, fixed_arguments);
+      // have the parent wait for the child process to finish.
+      waitpid(process_id, result, WUNTRACED | WCONTINUED);
 
-      // close the write pipe for the child when done.
-      if (pipe_data) {
-        close(descriptors[0]);
-      }
+      // this must explicitly check for 0 (as opposed to checking (!result)).
+      if (result != 0) {
+        if (WIFEXITED(*result)) {
+          return F_none;
+        }
 
-      if (result) {
-        *result = code;
+        return F_status_set_error(F_failure);
       }
 
-      return F_child;
+      return F_none;
     }
 
-    // write all data, if child doesn't read this could block until child closes the pipe.
-    if (pipe_data) {
-      const f_file_t file = f_macro_file_t_initialize(0, descriptors[1], f_file_flag_write_only);
+    // close the write pipe for the child.
+    close(descriptors[1]);
 
-      f_file_write(file, *pipe_data, 0);
+    if (parameter && parameter->signals) {
+      f_signal_set_handle(SIG_BLOCK, &parameter->signals->block);
+      f_signal_set_handle(SIG_UNBLOCK, &parameter->signals->block_not);
+    }
 
-      // close the write pipe for the parent when finished writing.
-      close(descriptors[1]);
+    if (parameter && parameter->names) {
+      clearenv();
+
+      for (f_array_length_t i = 0; i < parameter->names->used && i < parameter->values->used; i++) {
+        f_environment_set_dynamic(parameter->names->array[i], parameter->values->array[i], F_true);
+      } // for
     }
 
-    // have the parent wait for the child process to finish.
-    waitpid(process_id, result, WUNTRACED | WCONTINUED);
+    dup2(descriptors[0], f_type_descriptor_input);
 
-    if (result != 0) {
-      if (WIFEXITED(*result)) {
-        return F_none;
-      }
+    const int code = parameter && parameter->option & fl_execute_parameter_option_path ? execv(program, fixed_arguments) : execvp(program, fixed_arguments);
+
+    // close the write pipe for the child when done.
+    close(descriptors[0]);
 
-      return F_status_set_error(F_failure);
+    if (result) {
+      *result = code;
     }
+
+    if (parameter && parameter->option & fl_execute_parameter_option_exit) {
+      exit(code);
+    }
+
+    return F_child;
   }
-#endif // !defined(_di_fll_execute_path_environment_) || !defined(_di_fll_execute_program_environment_)
+#endif // !defined(_di_fll_execute_program_)
 
-#if !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_path_environment_)
+#if !defined(_di_fll_execute_program_)
   void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const f_string_length_t name_size, char program_name[], f_string_t fixed_arguments[]) {
 
     memcpy(program_name, program_path, name_size);
@@ -296,7 +266,7 @@ extern "C" {
     // insert the required end of array designator.
     fixed_arguments[arguments.used + 1] = 0;
   }
-#endif // !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_path_environment_)
+#endif // !defined(_di_fll_execute_program_)
 
 #ifdef __cplusplus
 } // extern "C"
index e024643ed43bb735c710b17be1110d8fb932face..5cb7c455e4295ed59b0785ddcc010567933f397f 100644 (file)
@@ -107,70 +107,78 @@ extern "C" {
 /**
  * Private function for performing the fork and execute operation.
  *
- * @param program_path
- *   The part of the path to the program representing the program name to copy from.
- * @param fixed_arguments
- *   A fixed array of strings representing the arguments.
- * @param program_is
- *   If TRUE then execvp() is called to perform execution.
- *   If FALSE then execv() is called to perform execution.
- * @param set_signal
- *   (optional) A pointer to the set of signals.
- *   Set to 0 to disable.
- * @param pipe_data
- *   (optional) A pointer to a string to pipe as standard input to the child process.
- *   Set to 0 to disable.
+ * This implementation ignores parameter.data.
+ *
+ * @param program
+ *   The name or path of the program.
+ * @param arguments
+ *   An array of strings representing the arguments.
+ * @param parameter
+ *   (optional) This and each of its fields are optional and are disabled when set to 0.
+ *   names:
+ *     An array of strings representing the environment variable names.
+ *     At most names.used variables are created.
+ *     Duplicate names are overwritten.
+ *   values:
+ *     An array of strings representing the environment variable values.
+ *     The values.used must be of at least names.used.
+ *     Set individual strings.used to 0 for empty/null values.
+ *   signals:
+ *     A pointer to the set of signals to have the child process block or not block.
+ *     When not specified, the child process uses the signal blocking behavior of the parent process.
+ *   data:
+ *     A pointer to a string to pipe as standard input to the child process.
+ *     The parent will block until the standard input is fully read or the child process exits.
  * @param result
- *   The code returned after finishing execution of program_path.
+ *   The code returned after finishing execution of program.
  *
  * @return
  *   F_none on success.
  *   F_child on success but this is the child thread.
  *   F_failure (with error bit) on execution failure.
  *   F_fork (with error bit) on fork failure.
- *   F_pipe (with error bit) on pipe failure.
  *
- * @see close()
- * @see dup2()
+ * @see clearenv()
  * @see execv()
  * @see execvp()
  * @see fork()
- * @see pipe()
  * @see waitpid()
  *
- * @see fll_execute_path()
+ * @see f_environment_set_dynamic()
+ * @see f_signal_set_handle()
  * @see fll_execute_program()
  */
-#if !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_program_)
-  extern f_return_status private_fll_execute_fork(const f_string_t program_path, const f_string_t fixed_arguments[], const bool program_is, const f_signal_how_t *signals, f_string_static_t * const pipe_data, int *result) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_program_)
+#if !defined(_di_fll_execute_program_)
+  extern f_return_status private_fll_execute_fork(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, int *result) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_execute_program_)
 
 /**
- * Private function for performing the fork and execute operation using a specified environment.
+ * Private function for performing the fork and execute operation.
  *
- * @param program_path
- *   The part of the path to the program representing the program name to copy from.
- * @param fixed_arguments
- *   A fixed array of strings representing the arguments.
- * @param program_is
- *   If TRUE then execvp() is called to perform execution.
- *   If FALSE then execv() is called to perform execution.
- * @param names
- *   An array of strings representing the environment variable names.
- *   At most names.used variables are created.
- *   Duplicate names are overwritten.
- * @param values
- *   An array of strings representing the environment variable names.
- *   The values.used must be of at least names.used.
- *   Set individual strings.used to 0 for empty/NULL values.
- * @param signals
- *   (optional) A pointer to the set of signals.
- *   Set to 0 to disable.
- * @param pipe_data
- *   (optional) A pointer to a string to pipe as standard input to the child process.
- *   Set to 0 to disable.
+ * This implementation requires parameter.data.
+ *
+ * @param program
+ *   The name or path of the program.
+ * @param arguments
+ *   An array of strings representing the arguments.
+ * @param parameter
+ *   (optional) This and each of its fields are optional and are disabled when set to 0.
+ *   names:
+ *     An array of strings representing the environment variable names.
+ *     At most names.used variables are created.
+ *     Duplicate names are overwritten.
+ *   values:
+ *     An array of strings representing the environment variable values.
+ *     The values.used must be of at least names.used.
+ *     Set individual strings.used to 0 for empty/null values.
+ *   signals:
+ *     A pointer to the set of signals to have the child process block or not block.
+ *     When not specified, the child process uses the signal blocking behavior of the parent process.
+ *   data:
+ *     A pointer to a string to pipe as standard input to the child process.
+ *     The parent will block until the standard input is fully read or the child process exits.
  * @param result
- *   The code returned after finishing execution of program_path.
+ *   The code returned after finishing execution of program.
  *
  * @return
  *   F_none on success.
@@ -179,22 +187,22 @@ extern "C" {
  *   F_fork (with error bit) on fork failure.
  *   F_pipe (with error bit) on pipe failure.
  *
- * @see close()
  * @see clearenv()
+ * @see close()
  * @see dup2()
+ * @see execv()
  * @see execvp()
  * @see fork()
- * @see memcpy()
  * @see pipe()
- * @see strnlen()
  * @see waitpid()
  *
- * @see fll_execute_path_environment()
- * @see fll_execute_program_environment()
+ * @see f_environment_set_dynamic()
+ * @see f_signal_set_handle()
+ * @see fll_execute_program()
  */
-#if !defined(_di_fll_execute_path_environment_) || !defined(_di_fll_execute_program_environment_)
-  extern f_return_status private_fll_execute_fork_environment(const f_string_t program_path, const f_string_t fixed_arguments[], const bool program_is, const f_string_statics_t names, const f_string_statics_t values, const f_signal_how_t *signals, f_string_static_t * const pipe_data, int *result) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_fll_execute_path_environment_) || !defined(_di_fll_execute_program_environment_)
+#if !defined(_di_fll_execute_program_)
+  extern f_return_status private_fll_execute_fork_data(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, int *result) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_execute_program_)
 
 /**
  * Private function for reconstructing the arguments into a fixed array.
@@ -213,12 +221,11 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- * @see fll_execute_path()
- * @see fll_execute_path_environment()
+ * @see fll_execute_program()
  */
-#if !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_path_environment_)
+#if !defined(_di_fll_execute_program_)
   extern void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const f_string_length_t name_size, char program_name[], f_string_t fixed_arguments[]) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_fll_execute_path_) || !defined(_di_fll_execute_path_environment_)
+#endif // !defined(_di_fll_execute_program_)
 
 #ifdef __cplusplus
 } // extern "C"
index 862211bfc4b56d238235431c41b1281d6bf2eaf4..44e3cdb68873d10e2d80ff813997599eb3fee8b5 100644 (file)
@@ -10,4 +10,5 @@ f_file
 f_path
 f_signal
 fl_environment
+fl_execute
 fl_string
index 44c40fcb7c398f30a47f5edd6535c75a23e3e862..f6c5fd48a905e8ac8f9071768c1c2bdb3805516f 100644 (file)
@@ -470,10 +470,11 @@ extern "C" {
     int result = 0;
 
     const f_string_dynamics_t arguments = f_string_dynamics_t_initialize;
+    fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, 0, 0, &signals, action.parameters.used ? &action.parameters.array[0] : 0);
 
     // @todo script program (such as: "bash") should be configurable somehow (a new entry setting? a new rule setting? both?).
     // @todo have the environment variables built before executing the script and then instead call fll_execute_program_environment() for all execute functions (with environment.names, environment.values).
-    f_status_t status = fll_execute_program(controller_string_bash, arguments, &signals, action.parameters.used ? &action.parameters.array[0] : 0, &result);
+    f_status_t status = fll_execute_program(controller_string_bash, arguments, &parameter, &result);
 
     if (status == F_child) {
       data->child = result;
index 7c335863a4933faa874105bd6f252da32b0fd4d8..00594f67610e25a718cad59d1dee5851bff36149 100644 (file)
@@ -664,7 +664,9 @@ extern "C" {
       f_signal_set_empty(&signals.block);
       f_signal_set_fill(&signals.block_not);
 
-      *status = fll_execute_path_environment(path.string, arguments, data_build.environment.names, data_build.environment.values, &signals, 0, &return_code);
+      fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(fl_execute_parameter_option_path, &data_build.environment.names, &data_build.environment.values, &signals, 0);
+
+      *status = fll_execute_program(path.string, arguments, &parameter, &return_code);
 
       fl_string_dynamics_delete(&arguments);
 
@@ -683,7 +685,7 @@ extern "C" {
             }
           }
           else {
-            fll_error_print(data.error, F_status_set_fine(*status), "fll_execute_path_environment", F_true);
+            fll_error_print(data.error, F_status_set_fine(*status), "fll_execute_program", F_true);
           }
         }
         else {
index 06c201e2b5656e0c4349db90be0adaa059daaac0..3a1b726416868ab131678f2ae35aa7527a146a14 100644 (file)
@@ -41,7 +41,9 @@ extern "C" {
       f_signal_set_empty(&signals.block);
       f_signal_set_fill(&signals.block_not);
 
-      *status = fll_execute_program_environment(program.string, arguments, environment.names, environment.values, &signals, 0, &return_code);
+      fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, &environment.names, &environment.values, &signals, 0);
+
+      *status = fll_execute_program(program.string, arguments, &parameter, &return_code);
 
       if (fake_signal_received(data)) {
         *status = F_status_set_error(F_signal);
index 04257d8fce633dcfe3771664e0ce1802e1401874..36267dac9a6ef6acdf548bb44bbe926e8a9e1177 100644 (file)
@@ -3846,12 +3846,9 @@ extern "C" {
     f_signal_set_empty(&signals.block);
     f_signal_set_fill(&signals.block_not);
 
-    if (as_shell) {
-      status = fll_execute_path_environment(program.string, arguments, data_make->environment.names, data_make->environment.values, &signals, 0, &return_code);
-    }
-    else {
-      status = fll_execute_program_environment(program.string, arguments, data_make->environment.names, data_make->environment.values, &signals, 0, &return_code);
-    }
+    fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(as_shell ? 0 : fl_execute_parameter_option_path, &data_make->environment.names, &data_make->environment.values, &signals, 0);
+
+    status = fll_execute_program(program.string, arguments, &parameter, &return_code);
 
     if (status == F_status_set_error(F_signal)) {
       return status;
index 844c7f08335db58201c94a89847116201a02d327..e196987660e717de1840cc4f1973eac3ca468225 100644 (file)
@@ -251,7 +251,7 @@ extern "C" {
           parameters.array[4].used = 9;
           parameters.array[5].used = 6;
 
-          status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, &return_code);
+          status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, &return_code);
 
           // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
           if (status == F_child) {
@@ -284,7 +284,7 @@ extern "C" {
           parameters.array[4].used = 9;
           parameters.array[5].used = 6;
 
-          status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, &return_code);
+          status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, &return_code);
 
           // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
           if (status == F_child) {
@@ -313,7 +313,7 @@ extern "C" {
           parameters.array[2].used = 9;
           parameters.array[3].used = 6;
 
-          status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, &return_code);
+          status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, &return_code);
 
           // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
           if (status == F_child) {
index 95e8438c7a4e5233329409d96e7e2a9cb542a21e..97beec1ca18c0ba654e7becf7a0816e51272050d 100644 (file)
@@ -752,7 +752,7 @@ f_return_status firewall_perform_commands(const firewall_local_data_t local, con
                       fprintf(f_type_debug, "\n");
                     }
 
-                    status = fll_execute_program((f_string_t) current_tool, arguments, 0, 0, &return_code);
+                    status = fll_execute_program((f_string_t) current_tool, arguments, 0, &return_code);
 
                     // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
                     if (status == F_child) {
@@ -826,7 +826,7 @@ f_return_status firewall_perform_commands(const firewall_local_data_t local, con
             fprintf(f_type_debug, "\n");
           }
 
-          status = fll_execute_program(current_tool, arguments, 0, 0, &return_code);
+          status = fll_execute_program(current_tool, arguments, 0, &return_code);
 
           // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
           if (status == F_child) {
@@ -1070,7 +1070,7 @@ f_return_status firewall_create_custom_chains(firewall_reserved_chains_t *reserv
         }
 
         tool = firewall_program_iptables;
-        status = fll_execute_program((f_string_t) firewall_tool_iptables, arguments, 0, 0, &return_code);
+        status = fll_execute_program((f_string_t) firewall_tool_iptables, arguments, 0, &return_code);
 
         // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
         if (status == F_child) {
@@ -1091,7 +1091,7 @@ f_return_status firewall_create_custom_chains(firewall_reserved_chains_t *reserv
           }
 
           tool = firewall_program_ip6tables;
-          status = fll_execute_program((f_string_t) firewall_tool_ip6tables, arguments, 0, 0, &return_code);
+          status = fll_execute_program((f_string_t) firewall_tool_ip6tables, arguments, 0, &return_code);
 
           // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
           if (status == F_child) {
@@ -1179,7 +1179,7 @@ f_return_status firewall_delete_chains(const firewall_data_t data) {
       fprintf(f_type_debug, "\n");
     }
 
-    status = fll_execute_program(tools[i], arguments, 0, 0, &return_code);
+    status = fll_execute_program(tools[i], arguments, 0, &return_code);
 
     // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
     if (status == F_child) {
@@ -1239,7 +1239,7 @@ f_return_status firewall_delete_chains(const firewall_data_t data) {
       fprintf(f_type_debug, "\n");
     }
 
-    status = fll_execute_program(tools[i], arguments, 0, 0, &return_code);
+    status = fll_execute_program(tools[i], arguments, 0, &return_code);
 
     // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
     if (status == F_child) {
@@ -1321,7 +1321,7 @@ f_return_status firewall_default_lock(const firewall_data_t data) {
         fprintf(f_type_debug, "\n");
       }
 
-      status = fll_execute_program(tools[j], arguments, 0, 0, &return_code);
+      status = fll_execute_program(tools[j], arguments, 0, &return_code);
 
       // immediately exit child process, @todo this may require additional memory deallocation and relating changes.
       if (status == F_child) {