From 235d9a2dca8e34caf9268b8a210248b8d8a60570 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 30 Dec 2020 15:13:29 -0600 Subject: [PATCH] Progress: control program, adding numerous FLL projects as needed. This focuses primarily on getting control groups working. There are also some f_account changes, but nothing in the control program used the f_account changes. --- build/level_0/settings | 4 +- build/level_1/settings | 4 +- build/level_2/settings | 4 +- build/monolithic/settings | 4 +- build/scripts/bootstrap-example.sh | 2 +- level_0/f_account/c/account-common.h | 172 +++++++ level_0/f_account/c/account.c | 264 ++++++++++ level_0/f_account/c/account.h | 86 +++- level_0/f_account/c/private-account.c | 83 +++ level_0/f_account/c/private-account.h | 49 ++ level_0/f_account/data/build/settings | 2 +- level_0/f_capability/c/capability-common.h | 2 +- level_0/f_control_group/c/control_group-common.h | 81 +++ level_0/f_control_group/c/control_group.h | 38 ++ level_0/f_control_group/data/build/defines | 1 + level_0/f_control_group/data/build/dependencies | 6 + level_0/f_control_group/data/build/settings | 55 ++ level_0/f_file/c/file-common.h | 3 +- level_0/f_status/c/status.h | 4 + level_0/f_string/c/string_dynamic.h | 4 +- level_0/f_string/c/string_map.h | 2 +- level_1/fl_control_group/c/control_group.c | 75 +++ level_1/fl_control_group/c/control_group.h | 87 ++++ level_1/fl_control_group/data/build/defines | 1 + level_1/fl_control_group/data/build/dependencies | 8 + level_1/fl_control_group/data/build/settings | 55 ++ level_1/fl_directory/c/directory.h | 2 +- level_1/fl_execute/c/execute-common.h | 20 +- level_1/fl_execute/c/execute.h | 3 + level_1/fl_execute/data/build/settings | 2 +- level_1/fl_status/c/status.c | 12 + level_1/fl_status/c/status.h | 562 +++++++++++---------- level_2/fll_control_group/c/control_group.c | 51 ++ level_2/fll_control_group/c/control_group.h | 60 +++ level_2/fll_control_group/data/build/defines | 1 + level_2/fll_control_group/data/build/dependencies | 13 + level_2/fll_control_group/data/build/settings | 55 ++ level_2/fll_error/c/error-common.h | 6 +- level_2/fll_execute/c/execute.h | 14 +- level_2/fll_execute/c/private-execute.c | 212 ++++++-- level_2/fll_execute/c/private-execute.h | 59 ++- level_2/fll_execute/data/build/dependencies | 2 + level_2/fll_execute/data/build/settings | 2 +- level_2/fll_status/c/status.c | 20 + level_3/byte_dump/c/byte_dump.h | 2 +- level_3/control/c/control.h | 2 +- level_3/controller/c/controller.h | 8 +- level_3/controller/c/private-common.h | 23 +- level_3/controller/c/private-rule.c | 194 +++++-- level_3/controller/c/private-rule.h | 6 +- level_3/controller/data/build/dependencies | 3 + level_3/controller/data/build/settings | 2 +- .../data/settings/example/entries/test.entry | 2 + .../settings/example/rules/command/multiple.rule | 10 + .../data/settings/example/rules/script/fail.rule | 2 +- .../settings/example/rules/script/require_me.rule | 14 + .../settings/example/rules/script/succeed.rule | 2 +- level_3/controller/documents/rule.txt | 12 +- level_3/controller/specifications/rule.txt | 2 +- level_3/fake/c/fake.h | 2 +- level_3/fake/c/private-fake.c | 2 +- level_3/fake/c/private-make.c | 2 +- level_3/fake/data/build/dependencies | 1 + level_3/fake/data/build/settings | 2 +- level_3/firewall/c/firewall.h | 2 +- level_3/firewall/data/build/dependencies | 2 + level_3/firewall/data/build/settings | 2 +- .../fss_basic_list_read/c/fss_basic_list_read.h | 2 +- .../fss_basic_list_write/c/fss_basic_list_write.h | 2 +- level_3/fss_basic_read/c/fss_basic_read.h | 2 +- level_3/fss_basic_write/c/fss_basic_write.h | 2 +- .../c/fss_embedded_list_read.h | 2 +- .../c/fss_embedded_list_write.h | 2 +- .../c/fss_extended_list_read.h | 2 +- .../c/fss_extended_list_write.h | 2 +- level_3/fss_extended_read/c/fss_extended_read.h | 2 +- level_3/fss_extended_write/c/fss_extended_write.h | 2 +- level_3/fss_status_code/c/fss_status_code.h | 2 +- level_3/iki_read/c/iki_read.h | 2 +- level_3/iki_write/c/iki_write.h | 2 +- level_3/init/c/init.h | 2 +- level_3/status_code/c/status_code.h | 2 +- 82 files changed, 2093 insertions(+), 428 deletions(-) create mode 100644 level_0/f_account/c/private-account.c create mode 100644 level_0/f_account/c/private-account.h create mode 100644 level_0/f_control_group/c/control_group-common.h create mode 100644 level_0/f_control_group/c/control_group.h create mode 100644 level_0/f_control_group/data/build/defines create mode 100644 level_0/f_control_group/data/build/dependencies create mode 100644 level_0/f_control_group/data/build/settings create mode 100644 level_1/fl_control_group/c/control_group.c create mode 100644 level_1/fl_control_group/c/control_group.h create mode 100644 level_1/fl_control_group/data/build/defines create mode 100644 level_1/fl_control_group/data/build/dependencies create mode 100644 level_1/fl_control_group/data/build/settings create mode 100644 level_2/fll_control_group/c/control_group.c create mode 100644 level_2/fll_control_group/c/control_group.h create mode 100644 level_2/fll_control_group/data/build/defines create mode 100644 level_2/fll_control_group/data/build/dependencies create mode 100644 level_2/fll_control_group/data/build/settings create mode 100644 level_3/controller/data/settings/example/rules/script/require_me.rule diff --git a/build/level_0/settings b/build/level_0/settings index a59c5a7..210815a 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -20,9 +20,9 @@ build_indexer ar build_language c build_libraries -lc -lcap build_libraries-level -build_sources_library account.c capability.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c private-print.c process.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c +build_sources_library account.c private-account.c capability.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c private-print.c process.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c build_sources_program -build_sources_headers account.h account-common.h capability.h capability-common.h color.h console.h console-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h execute.h execute-common.h file.h file-common.h fss.h fss-common.h fss_comment.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h memory.h memory_structure.h path.h path-common.h pipe.h print.h process.h process-common.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h status_array.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h string_triple.h type.h type_array.h utf.h utf-common.h +build_sources_headers account.h account-common.h capability.h capability-common.h color.h console.h console-common.h control_group.h control_group-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h execute.h execute-common.h file.h file-common.h fss.h fss-common.h fss_comment.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h memory.h memory_structure.h path.h path-common.h pipe.h print.h process.h process-common.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h status_array.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h string_triple.h type.h type_array.h utf.h utf-common.h build_sources_script build_sources_setting build_script yes diff --git a/build/level_1/settings b/build/level_1/settings index a7d23f0..94f4a28 100644 --- a/build/level_1/settings +++ b/build/level_1/settings @@ -20,9 +20,9 @@ build_indexer ar build_language c 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_library color.c console.c control_group.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 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_headers color.h console.h control_group.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 diff --git a/build/level_2/settings b/build/level_2/settings index d63d28a..4ba2922 100644 --- a/build/level_2/settings +++ b/build/level_2/settings @@ -20,9 +20,9 @@ build_indexer ar build_language c build_libraries -lc -lcap build_libraries-level -lfll_1 -lfll_0 -build_sources_library environment.c error.c private-error.c execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c fss_status.c iki.c private-iki.c path.c program.c status.c +build_sources_library control_group.c environment.c error.c private-error.c execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c fss_status.c iki.c private-iki.c path.c program.c status.c build_sources_program -build_sources_headers environment.h error.h error-common.h execute.h file.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 path.h program.h status.h +build_sources_headers control_group.h environment.h error.h error-common.h execute.h file.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 path.h program.h status.h build_sources_script build_sources_setting build_script yes diff --git a/build/monolithic/settings b/build/monolithic/settings index 44bb2c4..093c43e 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -20,9 +20,9 @@ build_indexer ar build_language c build_libraries -lc -lcap build_libraries-monolithic -build_sources_library level_0/account.c level_0/capability.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/environment.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_library level_0/account.c level_0/private-account.c level_0/capability.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/control_group.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/control_group.c level_2/environment.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/capability.h level_0/capability-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/environment.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/capability.h level_0/capability-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/control_group.h level_0/control_group-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/control_group.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/control_group.h level_2/environment.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 diff --git a/build/scripts/bootstrap-example.sh b/build/scripts/bootstrap-example.sh index 7d5593d..4a578e4 100644 --- a/build/scripts/bootstrap-example.sh +++ b/build/scripts/bootstrap-example.sh @@ -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_capability 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_environment 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_capability f_color f_console f_control_group 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_control_group 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_control_group fll_environment 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/ && diff --git a/level_0/f_account/c/account-common.h b/level_0/f_account/c/account-common.h index 625e1c1..8176234 100644 --- a/level_0/f_account/c/account-common.h +++ b/level_0/f_account/c/account-common.h @@ -27,6 +27,178 @@ extern "C" { #define f_account_pwd_length_fallback_second 32767 #endif // _di_f_account_defines_ +/** + * Provide a complete standard password account structure. + * + * id_user: The user ID. + * id_group: The group ID. + * home: The user's home directory. + * label: The user's display name (gecos). + * name: The user's account name. + * password: The user's password. + * shell: The user's shell program. + */ +#ifndef _di_f_account_t_ + typedef struct { + uid_t id_user; + gid_t id_group; + + f_string_dynamic_t home; + f_string_dynamic_t label; + f_string_dynamic_t name; + f_string_dynamic_t password; + f_string_dynamic_t shell; + } f_account_t; + + #define f_account_t_initialize { 0, 0, f_string_dynamic_t_initialize, f_string_dynamic_t_initialize, f_string_dynamic_t_initialize, f_string_dynamic_t_initialize, f_string_dynamic_t_initialize } + + #define f_macro_account_t_clear(account) \ + account.id_user = 0; \ + account.id_group = 0; \ + f_macro_account_t_clear(account.home); \ + f_macro_account_t_clear(account.label); \ + f_macro_account_t_clear(account.name); \ + f_macro_account_t_clear(account.password); \ + f_macro_account_t_clear(account.shell); + + #define f_macro_account_t_delete(status, account) \ + f_macro_string_dynamic_t_delete(status, account.home); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_delete(status, account.label); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_delete(status, account.name); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_delete(status, account.password); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_delete(status, account.shell); + + #define f_macro_account_t_destroy(status, account) \ + f_macro_string_dynamic_t_destroy(status, account.home); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_destroy(status, account.label); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_destroy(status, account.name); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_destroy(status, account.password); \ + if (F_status_is_error_not(status)) f_macro_string_dynamic_t_destroy(status, account.shell); + + #define f_macro_account_t_delete_simple(account) \ + f_macro_string_dynamic_t_delete_simple(account.home); \ + f_macro_string_dynamic_t_delete_simple(account.label); \ + f_macro_string_dynamic_t_delete_simple(account.name); \ + f_macro_string_dynamic_t_delete_simple(account.password); \ + f_macro_string_dynamic_t_delete_simple(account.shell); + + #define f_macro_account_t_destroy_simple(account) \ + f_macro_string_dynamic_t_destroy_simple(account.home); \ + f_macro_string_dynamic_t_destroy_simple(account.label); \ + f_macro_string_dynamic_t_destroy_simple(account.name); \ + f_macro_string_dynamic_t_destroy_simple(account.password); \ + f_macro_string_dynamic_t_destroy_simple(account.shell); +#endif // _di_f_account_t_ + +/** + * An array of accounts. + * + * array: the array of accounts. + * size: total amount of space available. + * used: total number of space used. + */ +#ifndef _di_f_accounts_t_ + typedef struct { + f_account_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_accounts_t; + + #define f_accounts_t_initialize { 0, 0, 0 } + + #define f_macro_accounts_t_clear(accounts) \ + accounts.array = 0; \ + accounts.size = 0; \ + accounts.used = 0; + + #define f_macro_accounts_new(status, accounts, length) \ + f_macro_accounts_clear(accounts) \ + status = f_memory_new((void **) & accounts.array, sizeof(f_account_t), length); \ + if (status == F_none) { \ + accounts.size = length; \ + accounts.used = 0; \ + } + + #define f_macro_string_accounts_t_delete(status, accounts) \ + status = F_none; \ + accounts.used = accounts.size; \ + while (accounts.used) { \ + accounts.used--; \ + f_macro_account_t_delete(status, accounts.array[accounts.used]); \ + if (status != F_none) break; \ + } \ + if (status == F_none) status = f_memory_delete((void **) & accounts.array, sizeof(f_account_t), accounts.size); \ + if (status == F_none) accounts.size = 0; + + #define f_macro_string_accounts_t_destroy(status, accounts) \ + status = F_none; \ + accounts.used = accounts.size; \ + while (accounts.used) { \ + accounts.used--; \ + f_macro_account_t_destroy(status, accounts.array[accounts.used]); \ + if (status != F_none) break; \ + } \ + if (status == F_none) status = f_memory_destroy((void **) & accounts.array, sizeof(f_account_t), accounts.size); \ + if (status == F_none) accounts.size = 0; + + #define f_macro_string_accounts_t_delete_simple(accounts) \ + accounts.used = accounts.size; \ + while (accounts.used) { \ + accounts.used--; \ + f_macro_account_t_delete_simple(accounts.array[accounts.used]); \ + } \ + f_memory_delete((void **) & accounts.array, sizeof(f_account_t), accounts.size); \ + accounts.size = 0; + + #define f_macro_string_accounts_t_destroy_simple(accounts) \ + accounts.used = accounts.size; \ + while (accounts.used > 0) { \ + accounts.used--; \ + f_macro_account_t_destroy_simple(accounts.array[accounts.used]); \ + } \ + f_memory_destroy((void **) & accounts.array, sizeof(f_account_t), accounts.size); \ + accounts.size = 0; + + #define f_macro_string_accounts_t_resize(status, accounts, new_length) \ + status = F_none; \ + if (new_length < accounts.size) { \ + for (f_array_length_t _macro__i = accounts.size - new_length; _macro__i < accounts.size; _macro__i++) { \ + f_macro_account_t_delete(status, accounts.array[_macro__i]); \ + if (status != F_none) break; \ + } \ + } \ + if (status == F_none) status = f_memory_resize((void **) & accounts.array, sizeof(f_account_t), accounts.size, new_length); \ + if (status == F_none) { \ + if (new_length > accounts.size) { \ + for (f_array_length_t _macro__i = accounts.size; _macro__i < new_length; _macro__i++) { \ + memset(&accounts.array[_macro__i], 0, sizeof(f_account_t)); \ + } \ + } \ + accounts.size = new_length; \ + if (accounts.used > accounts.size) accounts.used = new_length; \ + } + + #define f_macro_string_accounts_t_adjust(status, accounts, new_length) \ + status = F_none; \ + if (new_length < accounts.size) { \ + for (f_array_length_t _macro__i = accounts.size - new_length; _macro__i < accounts.size; _macro__i++) { \ + f_macro_account_t_destroy(status, accounts.array[_macro__i], f_account_t); \ + if (status != F_none) break; \ + } \ + } \ + if (status == F_none) status = f_memory_adjust((void **) & accounts.array, sizeof(f_account_t), accounts.size, new_length); \ + if (status == F_none) { \ + if (new_length > accounts.size) { \ + for (f_array_length_t _macro__i = accounts.size; _macro__i < new_length; _macro__i++) { \ + memset(&accounts.array[_macro__i], 0, sizeof(f_account_t)); \ + } \ + } \ + accounts.size = new_length; \ + if (accounts.used > accounts.size) accounts.used = new_length; \ + } +#endif // _di_f_accounts_t_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_account/c/account.c b/level_0/f_account/c/account.c index 86149d1..020bf5c 100644 --- a/level_0/f_account/c/account.c +++ b/level_0/f_account/c/account.c @@ -1,9 +1,176 @@ #include "account.h" +#include "private-account.h" #ifdef __cplusplus extern "C" { #endif +#ifndef _di_f_account_by_name_ + f_return_status f_account_by_name(const f_string_t name, f_account_t *account) { + #ifndef _di_level_0_parameter_checking_ + if (!account) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + account->id_user = 0; + account->id_group = 0; + account->home.used = 0; + account->label.used = 0; + account->name.used = 0; + account->password.used = 0; + account->shell.used = 0; + + f_status_t status = F_none; + + const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX); + + // note: pointer seems pointless except that it is used to determine if the name was found. + struct passwd password; + struct passwd *pointer = 0; + + size_t length = length_max; + + { + if (length == -1) { + length = f_account_pwd_length_fallback_first; + } + + // must be set to 0 to avoid problems due to the design of getpwnam()/getpwnam_r(). + errno = 0; + + char buffer[length]; + const int result = getpwnam_r(name, &password, buffer, length, &pointer); + + if (result) { + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max); + if (errno == ENFILE) return F_status_set_error(F_file_open_max); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + + if (errno == ERANGE) { + if (length_max > 0) return F_status_set_error(F_buffer_too_small); + } + else { + return F_status_set_error(F_failure); + } + } + else { + if (!pointer) { + return F_exist_not; + } + + return private_f_account_from_passwd(password, length, account); + } + } + + length = f_account_pwd_length_fallback_second; + + char buffer[f_account_pwd_length_fallback_second]; + + const int result = getpwnam_r(name, &password, buffer, length, &pointer); + + if (result) { + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max); + if (errno == ENFILE) return F_status_set_error(F_file_open_max); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + if (errno == ERANGE) return F_status_set_error(F_buffer_too_small); + + return F_status_set_error(F_failure); + } + + if (!pointer) { + return F_exist_not; + } + + return private_f_account_from_passwd(password, length, account); + } +#endif // _di_f_account_by_name_ + +#ifndef _di_f_account_by_id_ + f_return_status f_account_by_id(const uid_t id, f_account_t *account) { + #ifndef _di_level_0_parameter_checking_ + if (!account) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + account->id_user = 0; + account->id_group = 0; + account->home.used = 0; + account->label.used = 0; + account->name.used = 0; + account->password.used = 0; + account->shell.used = 0; + + f_status_t status = F_none; + + const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX); + + // note: pointer seems pointless except that it is used to determine if the name was found. + struct passwd password; + struct passwd *pointer = 0; + + size_t length = length_max; + + { + if (length == -1) { + length = f_account_pwd_length_fallback_first; + } + + // must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r(). + errno = 0; + + char buffer[length]; + const int result = getpwuid_r(id, &password, buffer, length, &pointer); + + if (result) { + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max); + if (errno == ENFILE) return F_status_set_error(F_file_open_max); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + + if (errno == ERANGE) { + if (length_max > 0) return F_status_set_error(F_buffer_too_small); + } + else { + return F_status_set_error(F_failure); + } + } + else { + if (!pointer) { + return F_exist_not; + } + + return private_f_account_from_passwd(password, length, account); + } + } + + length = f_account_pwd_length_fallback_second; + + char buffer[f_account_pwd_length_fallback_second]; + + const int result = getpwuid_r(id, &password, buffer, length, &pointer); + + if (result) { + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max); + if (errno == ENFILE) return F_status_set_error(F_file_open_max); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + if (errno == ERANGE) return F_status_set_error(F_buffer_too_small); + + return F_status_set_error(F_failure); + } + + if (!pointer) { + return F_exist_not; + } + + return private_f_account_from_passwd(password, length, account); + } +#endif // _di_f_account_by_id_ + #ifndef _di_f_account_id_group_by_name_ f_return_status f_account_id_group_by_name(const f_string_t name, gid_t *id) { #ifndef _di_level_0_parameter_checking_ @@ -162,6 +329,103 @@ extern "C" { } #endif // _di_f_account_id_user_by_name_ +#ifndef _di_f_account_name_user_by_id_ + f_return_status f_account_name_user_by_id(const uid_t id, f_string_dynamic_t *name) { + #ifndef _di_level_0_parameter_checking_ + if (!name) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + name->used = 0; + + f_status_t status = F_none; + + const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX); + + // note: pointer seems pointless except that it is used to determine if the name was found. + struct passwd password; + struct passwd *pointer = 0; + + size_t length = length_max + 1; + + { + if (length == -1) { + length = f_account_pwd_length_fallback_first; + } + + // must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r(). + errno = 0; + + char buffer[length]; + const int result = getpwuid_r(id, &password, buffer, length, &pointer); + + if (result) { + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max); + if (errno == ENFILE) return F_status_set_error(F_file_open_max); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + + if (errno == ERANGE) { + if (length_max > 0) return F_status_set_error(F_buffer_too_small); + } + else { + return F_status_set_error(F_failure); + } + } + else { + if (!pointer) { + return F_exist_not; + } + + const f_string_length_t name_length = strnlen(password.pw_name, length); + + f_macro_string_dynamic_t_resize(status, (*name), name_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(name->string, password.pw_name, name_length); + + name->string[name_length] = 0; + name->used = name_length; + + return F_none; + } + } + + length = f_account_pwd_length_fallback_second; + + char buffer[f_account_pwd_length_fallback_second]; + + const int result = getpwuid_r(id, &password, buffer, length, &pointer); + + if (result) { + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max); + if (errno == ENFILE) return F_status_set_error(F_file_open_max); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + if (errno == ERANGE) return F_status_set_error(F_buffer_too_small); + + return F_status_set_error(F_failure); + } + + if (!pointer) { + return F_exist_not; + } + + const f_string_length_t name_length = strnlen(password.pw_name, length); + + f_macro_string_dynamic_t_resize(status, (*name), name_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(name->string, password.pw_name, name_length); + + name->string[name_length] = 0; + name->used = name_length; + + return F_none; + } +#endif // _di_f_account_name_user_by_id_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_account/c/account.h b/level_0/f_account/c/account.h index 9be5caa..853e854 100644 --- a/level_0/f_account/c/account.h +++ b/level_0/f_account/c/account.h @@ -7,8 +7,8 @@ * * Provides account related functionality (users, groups, roles, etc..). * - * @todo POSIX as of POSIX.1-2001, at least getpwnam() does not call "not found" an error. - * For now, using getpwnam_r() in place of getpwnam() (and similar) seems the safest way to avoid this bad design. + * POSIX as of POSIX.1-2001, at least getpwnam() does not call "not found" an error. + * This uses getpwnam_r() in place of getpwnam() (and similar) as the safest way to avoid this bad design. */ #ifndef _F_account_h #define _F_account_h @@ -33,6 +33,61 @@ extern "C" { #endif /** + * Get the user account by the user name. + * + * @param name + * The user name. + * The name must be NULL terminated. + * @param account + * This is replaced with by the account information. + * All strings will be NULL terminated. + * + * @return + * F_none on success. + * F_buffer_too_small (with error bit) if the buffer is too small to store the account data. + * F_exist_non if no user by that name exists. + * F_file_descriptor_max (with error bit) if max file descriptors was reached. + * F_file_open_max (with error bit) too many open files. + * F_input_output (with error bit) if an I/O error occurred. + * F_interrupt (with error bit) when program received an interrupt signal, halting operation. + * F_memory_not (with error bit) if out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see getpwnam_r() + */ +#ifndef _di_f_account_by_name_ + extern f_return_status f_account_by_name(const f_string_t name, f_account_t *account); +#endif // _di_f_account_by_name_ + +/** + * Get the user account by the user id. + * + * @param id + * The id of the user. + * @param account + * This is replaced with by the account information. + * All strings will be NULL terminated. + * + * @return + * F_none on success. + * F_buffer_too_small (with error bit) if the buffer is too small to store the account data. + * F_exist_non if no user by that name exists. + * F_file_descriptor_max (with error bit) if max file descriptors was reached. + * F_file_open_max (with error bit) too many open files. + * F_input_output (with error bit) if an I/O error occurred. + * F_interrupt (with error bit) when program received an interrupt signal, halting operation. + * F_memory_not (with error bit) if out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see getpwuid_r() + */ +#ifndef _di_f_account_by_id_ + extern f_return_status f_account_by_id(const uid_t id, f_account_t *account); +#endif // _di_f_account_by_id_ + +/** * Get the group account id by the group name. * * @param name @@ -86,6 +141,33 @@ extern "C" { extern f_return_status f_account_id_user_by_name(const f_string_t name, uid_t *id); #endif // _di_f_account_id_user_by_name_ +/** + * Get the user account name by the user id. + * + * @param id + * The id of the user. + * @param name + * This is replaced with by the user name. + * The name will be NULL terminated. + * + * @return + * F_none on success. + * F_buffer_too_small (with error bit) if the buffer is too small to store the account data. + * F_exist_non if no user by that name exists. + * F_file_descriptor_max (with error bit) if max file descriptors was reached. + * F_file_open_max (with error bit) too many open files. + * F_input_output (with error bit) if an I/O error occurred. + * F_interrupt (with error bit) when program received an interrupt signal, halting operation. + * F_memory_not (with error bit) if out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_failure (with error bit) on any other error. + * + * @see getpwuid_r() + */ +#ifndef _di_f_account_name_user_by_id_ + extern f_return_status f_account_name_user_by_id(const uid_t id, f_string_dynamic_t *name); +#endif // _di_f_account_name_user_by_id_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_account/c/private-account.c b/level_0/f_account/c/private-account.c new file mode 100644 index 0000000..f79bd72 --- /dev/null +++ b/level_0/f_account/c/private-account.c @@ -0,0 +1,83 @@ +#include "account.h" +#include "private-account.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_account_by_name_) || !defined(_di_f_account_by_id_) + f_return_status private_f_account_from_passwd(const struct passwd password, const f_string_length_t password_length, f_account_t *account) { + f_status_t status = F_none; + + + // Account UID and GID. + account->id_user = password.pw_uid; + account->id_group = password.pw_gid; + + + // account home directory. + f_string_length_t string_length = strnlen(password.pw_dir, password_length); + + f_macro_string_dynamic_t_resize(status, account->home, string_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(account->home.string, password.pw_dir, string_length); + + account->home.string[string_length] = 0; + account->home.used = string_length; + + + // account label (gecos). + string_length = strnlen(password.pw_gecos, password_length); + + f_macro_string_dynamic_t_resize(status, account->label, string_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(account->label.string, password.pw_gecos, string_length); + + account->label.string[string_length] = 0; + account->label.used = string_length; + + + // account name. + string_length = strnlen(password.pw_name, password_length); + + f_macro_string_dynamic_t_resize(status, account->name, string_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(account->name.string, password.pw_name, string_length); + + account->name.string[string_length] = 0; + account->name.used = string_length; + + + // account password directory. + string_length = strnlen(password.pw_passwd, password_length); + + f_macro_string_dynamic_t_resize(status, account->password, string_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(account->password.string, password.pw_passwd, string_length); + + account->password.string[string_length] = 0; + account->password.used = string_length; + + + // account shell directory. + string_length = strnlen(password.pw_shell, password_length); + + f_macro_string_dynamic_t_resize(status, account->shell, string_length + 1); + if (F_status_is_error(status)) return status; + + memcpy(account->shell.string, password.pw_shell, string_length); + + account->shell.string[string_length] = 0; + account->shell.used = string_length; + + return F_none; + } +#endif // !defined(_di_f_account_by_name_) || !defined(_di_f_account_by_id_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_account/c/private-account.h b/level_0/f_account/c/private-account.h new file mode 100644 index 0000000..9cdab9c --- /dev/null +++ b/level_0/f_account/c/private-account.h @@ -0,0 +1,49 @@ +/** + * FLL - Level 0 + * + * Project: Account + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_F_account_h +#define _PRIVATE_F_account_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private helper for converting an entire "struct passwd" to a complete f_account_t. + * + * Intended to be shared to each of the different implementation variations. + * + * @param passwd + * The password structure. + * @param passwd_length + * The length of the password structure buffer. + * @param account + * This is replaced with by the account information. + * All strings will be NULL terminated. + * This assumes that all strings in account have their used set to the desired length, such as 0. + * + * @return + * F_none on success. + * + * Errors (with error bit) from f_macro_string_dynamic_t_resize(). + * + * @see f_account_by_name() + * @see f_account_by_id() + * @see f_macro_string_dynamic_t_resize() + */ +#if !defined(_di_f_account_by_name_) || !defined(_di_f_account_by_id_) + extern f_return_status private_f_account_from_passwd(const struct passwd password, const f_string_length_t password_length, f_account_t *account) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_account_by_name_) || !defined(_di_f_account_by_id_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_account_h diff --git a/level_0/f_account/data/build/settings b/level_0/f_account/data/build/settings index 8813f2d..eacbe7f 100644 --- a/level_0/f_account/data/build/settings +++ b/level_0/f_account/data/build/settings @@ -20,7 +20,7 @@ build_indexer ar build_language c build_libraries -lc build_libraries-individual -lf_memory -build_sources_library account.c +build_sources_library account.c private-account.c build_sources_program build_sources_headers account.h account-common.h build_sources_script diff --git a/level_0/f_capability/c/capability-common.h b/level_0/f_capability/c/capability-common.h index 599ff22..0af5f38 100644 --- a/level_0/f_capability/c/capability-common.h +++ b/level_0/f_capability/c/capability-common.h @@ -7,7 +7,7 @@ * * Defines common data to be used for/by capability related functionality. * - * This is auto-included by account.h and should not need to be explicitly included. + * This is auto-included by capability.h and should not need to be explicitly included. */ #ifndef _F_capability_common_h #define _F_capability_common_h diff --git a/level_0/f_control_group/c/control_group-common.h b/level_0/f_control_group/c/control_group-common.h new file mode 100644 index 0000000..95f0f6d --- /dev/null +++ b/level_0/f_control_group/c/control_group-common.h @@ -0,0 +1,81 @@ +/** + * FLL - Level 0 + * + * Project: Control Group + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Defines common data to be used for/by control group (cgroup) related functionality. + * + * This is auto-included by control.h and should not need to be explicitly included. + */ +#ifndef _F_control_group_common_h +#define _F_control_group_common_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The defines for control groups. + */ +#ifndef _di_fl_control_group_defines_ + #define f_control_group_path_system_default "sys/fs/cgroup/" + #define f_control_group_path_system_prefix "/" + #define f_control_group_path_system_suffix "/cgroup.procs" + + #define f_control_group_path_system_default_length 14 + #define f_control_group_path_system_prefix_length 1 + #define f_control_group_path_system_suffix_length 13 + + #define f_control_group_pid_length_max 64 + + const static f_string_t f_control_group_path_system_default_s = f_control_group_path_system_default; + const static f_string_t f_control_group_path_system_prefix_s = f_control_group_path_system_prefix; + const static f_string_t f_control_group_path_system_suffix_s = f_control_group_path_system_suffix; +#endif // _di_fl_control_group_defines_ + +/** + * Provide a structure for associating some process with one or more control groups (cgroups). + * + * as_new: If TRUE then the control group is to be unshared, and FALSE the control group is not to be unshared. + * path: The sysfs path, must have the trailing slash (such as "/sys/fs/cgroup/"). + * groups: An array of control groups, relative to the sysfs path (such as "memory/example"). + */ +#ifndef _di_f_control_group_t_ + typedef struct { + bool as_new; + + f_string_dynamic_t path; + f_string_dynamics_t groups; + } f_control_group_t; + + #define f_control_group_t_initialize { F_false, f_string_dynamic_t_initialize, f_string_dynamics_t_initialize } + + #define f_macro_control_group_t_clear(control) \ + control.as_new = F_false; \ + f_macro_string_dynamic_t_clear(control.path); \ + f_macro_string_dynamics_t_clear(control.groups); + + #define f_macro_control_group_t_delete(status, control) \ + f_macro_string_dynamic_t_delete(status, control.path); \ + if (F_status_is_error_not(status)) f_macro_string_dynamics_t_delete(status, control.groups); + + #define f_macro_control_group_t_destroy(status, control) \ + f_macro_string_dynamic_t_destroy(status, control.path); \ + if (F_status_is_error_not(status)) f_macro_string_dynamics_t_destroy(status, control.groups); + + #define f_macro_control_group_t_delete_simple(control) \ + f_macro_string_dynamic_t_delete_simple(control.path); \ + f_macro_string_dynamics_t_delete_simple(control.groups); + + #define f_macro_control_group_t_destroy_simple(control) \ + f_macro_string_dynamic_t_destroy_simple(control.path); \ + f_macro_string_dynamics_t_destroy_simple(control.groups); +#endif // _di_f_control_group_t_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_control_group_common_h diff --git a/level_0/f_control_group/c/control_group.h b/level_0/f_control_group/c/control_group.h new file mode 100644 index 0000000..100242b --- /dev/null +++ b/level_0/f_control_group/c/control_group.h @@ -0,0 +1,38 @@ +/** + * FLL - Level 1 + * + * Project: Control Group + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Provides control group (cgroup) related functionality. + * + * It appears that the control group, as documented in the Linux kernel, is changed via the sysfs instead of system calls. + * If there are system calls to set the control group for a given process then this will need to be updated to utilize that. + * Until then, this is an implementation that helps facilitate writing to the sysfs filesystem for adding a process to a particular control group. + * + * This is intended to be used with Control Groups (cgroups) Version 2. + */ +#ifndef _F_control_group_h +#define _F_control_group_h + +// libc includes + +// fll-0 includes +#include +#include +#include +#include + +// fll-1 control includes +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_control_group_h diff --git a/level_0/f_control_group/data/build/defines b/level_0/f_control_group/data/build/defines new file mode 100644 index 0000000..4f13080 --- /dev/null +++ b/level_0/f_control_group/data/build/defines @@ -0,0 +1 @@ +# fss-0000 diff --git a/level_0/f_control_group/data/build/dependencies b/level_0/f_control_group/data/build/dependencies new file mode 100644 index 0000000..d798245 --- /dev/null +++ b/level_0/f_control_group/data/build/dependencies @@ -0,0 +1,6 @@ +# fss-0000 + +f_type +f_status +f_memory +f_string diff --git a/level_0/f_control_group/data/build/settings b/level_0/f_control_group/data/build/settings new file mode 100644 index 0000000..48fec22 --- /dev/null +++ b/level_0/f_control_group/data/build/settings @@ -0,0 +1,55 @@ +# fss-0001 + +project_name f_control_group + +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 +build_sources_library +build_sources_program +build_sources_headers control_group.h control_group-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 diff --git a/level_0/f_file/c/file-common.h b/level_0/f_file/c/file-common.h index 4aece7b..5350e5d 100644 --- a/level_0/f_file/c/file-common.h +++ b/level_0/f_file/c/file-common.h @@ -116,7 +116,8 @@ extern "C" { #define f_file_t_initialize { 0, -1, f_file_flag_read_only, f_file_default_read_size, f_file_default_write_size } - #define f_macro_file_t_initialize(stream, id, flag) { stream, id, flag, f_file_default_read_size, f_file_default_write_size } + #define f_macro_file_t_initialize(stream, id, flag, read_size, write_size) { stream, id, flag, read_size, write_size } + #define f_macro_file_t_initialize2(stream, id, flag) { stream, id, flag, f_file_default_read_size, f_file_default_write_size } #define f_macro_file_t_clear(file) \ file.stream = 0; \ diff --git a/level_0/f_status/c/status.h b/level_0/f_status/c/status.h index a43b0d6..d16afd3 100644 --- a/level_0/f_status/c/status.h +++ b/level_0/f_status/c/status.h @@ -163,6 +163,10 @@ extern "C" { F_connected_not, F_container, F_container_not, + F_control, + F_control_not, + F_control_group, + F_control_group_not, F_critical, F_critical_not, F_deadlock, diff --git a/level_0/f_string/c/string_dynamic.h b/level_0/f_string/c/string_dynamic.h index f950bf2..9e1b2d4 100644 --- a/level_0/f_string/c/string_dynamic.h +++ b/level_0/f_string/c/string_dynamic.h @@ -146,10 +146,10 @@ extern "C" { #define f_string_dynamics_t_initialize f_string_statics_t_initialize - #define f_macro_string_dynamics_clear(dynamics) f_macro_string_statics_t_clear(dynamics) + #define f_macro_string_dynamics_t_clear(dynamics) f_macro_string_statics_t_clear(dynamics) #define f_macro_string_dynamics_new(status, dynamics, length) \ - f_macro_string_dynamics_clear(dynamics) \ + f_macro_string_dynamics_t_clear(dynamics) \ status = f_memory_new((void **) & dynamics.array, sizeof(f_string_dynamic_t), length); \ if (status == F_none) { \ dynamics.size = length; \ diff --git a/level_0/f_string/c/string_map.h b/level_0/f_string/c/string_map.h index aee9fba..b2fa00a 100644 --- a/level_0/f_string/c/string_map.h +++ b/level_0/f_string/c/string_map.h @@ -184,7 +184,7 @@ extern "C" { #define f_macro_string_map_multi_t_clear(map) \ f_macro_string_dynamic_t_clear(map.name) \ - f_macro_string_dynamics_clear(map.value) + f_macro_string_dynamics_t_clear(map.value) #define f_macro_string_map_multi_t_delete(status, map) \ f_macro_string_dynamic_t_delete(status, map.name) \ diff --git a/level_1/fl_control_group/c/control_group.c b/level_1/fl_control_group/c/control_group.c new file mode 100644 index 0000000..c541fa0 --- /dev/null +++ b/level_1/fl_control_group/c/control_group.c @@ -0,0 +1,75 @@ +#include "control_group.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fl_control_group_apply_ + f_return_status fl_control_group_apply(const f_control_group_t control_group, const pid_t id) { + #ifndef _di_level_1_parameter_checking_ + if (!id) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (control_group.as_new) { + if (unshare(CLONE_NEWCGROUP) < 0) { + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + if (errno == ENOSPC) return F_status_set_error(F_space_not); + if (errno == EPERM) return F_status_set_error(F_prohibited); + + return F_status_set_error(F_failure); + } + } + + f_file_t file = f_macro_file_t_initialize2(0, -1, f_file_flag_write_only); + f_status_t status = F_none; + f_string_length_t length = 0; + + for (f_array_length_t i = 0; i < control_group.groups.used; ++i) { + + if (!control_group.groups.array[i].used) continue; + + length = control_group.path.used + control_group.groups.array[i].used + f_control_group_path_system_suffix_length; + + char path[length + 1]; + + if (control_group.path.used) { + memcpy(path, control_group.path.string, control_group.path.used); + } + + memcpy(path + control_group.path.used, control_group.groups.array[i].string, control_group.groups.array[i].used); + memcpy(path + control_group.path.used + f_control_group_path_system_default_length, f_control_group_path_system_suffix, f_control_group_path_system_suffix_length); + + path[length] = 0; + + status = f_file_stream_open(path, 0, &file); + if (F_status_is_error(status)) break; + + fprintf(file.stream, "%llu", id); + fflush(file.stream); + + f_file_stream_close(F_true, &file); + if (F_status_is_error(status)) break; + } // for + + if (F_status_is_error(status)) { + return status; + } + + return F_none; + } +#endif // _di_fl_control_group_apply_ + +#ifndef _di_fl_control_group_delete_ + f_return_status fl_control_group_delete(f_control_group_t *control_group) { + f_status_t status = F_none; + + f_macro_control_group_t_delete(status, (*control_group)); + + return status; + } +#endif // _di_fl_control_group_delete_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_1/fl_control_group/c/control_group.h b/level_1/fl_control_group/c/control_group.h new file mode 100644 index 0000000..445bef7 --- /dev/null +++ b/level_1/fl_control_group/c/control_group.h @@ -0,0 +1,87 @@ +/** + * FLL - Level 1 + * + * Project: Control Group + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Provides control group (cgroup) related functionality. + * + * It appears that the control group, as documented in the Linux kernel, is changed via the sysfs instead of system calls. + * If there are system calls to set the control group for a given process then this will need to be updated to utilize that. + * Until then, this is an implementation that helps facilitate writing to the sysfs filesystem for adding a process to a particular control group. + * + * This is intended to be used with Control Groups (cgroups) Version 2. + */ +#ifndef _FL_control_group_h +#define _FL_control_group_h + +// include pre-requirements +#define _GNU_SOURCE + +// libc includes +#include +#include +#include + +// fll-0 includes +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Apply the given control groups to the process represented by the PID. + * + * @param control + * The control group(s) to apply. + * @param id + * The PID of the process to apply the control group(s) to. + * + * @return + * F_none on success. + * F_memory_not (with error bit) if a out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if the current user/process has insufficient privileges to set certain cgroup settings. + * F_space_not (with error bit) if a maximum resource limit is reached and there is not enough space. + * F_failure (with error bit) on any other error. + * + * Errors (with error bit) from: f_file_stream_open(). + * + * @see fprintf() + * @see fflush() + * @see memcpy() + * @see unshare() + * + * @see f_file_stream_close() + * @see f_file_stream_open() + */ +#ifndef _di_fl_control_group_apply_ + extern f_return_status fl_control_group_apply(const f_control_group_t control_group, const pid_t id); +#endif // _di_fl_control_group_apply_ + +/** + * Delete the control group structure. + * + * @param control_group + * The control group to delete. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_control_group_delete_ + extern f_return_status fl_control_group_delete(f_control_group_t *control_group); +#endif // _di_fl_control_group_delete_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _FL_control_group_h diff --git a/level_1/fl_control_group/data/build/defines b/level_1/fl_control_group/data/build/defines new file mode 100644 index 0000000..4f13080 --- /dev/null +++ b/level_1/fl_control_group/data/build/defines @@ -0,0 +1 @@ +# fss-0000 diff --git a/level_1/fl_control_group/data/build/dependencies b/level_1/fl_control_group/data/build/dependencies new file mode 100644 index 0000000..1a6851d --- /dev/null +++ b/level_1/fl_control_group/data/build/dependencies @@ -0,0 +1,8 @@ +# fss-0000 + +f_type +f_status +f_memory +f_string +f_control_group +f_file diff --git a/level_1/fl_control_group/data/build/settings b/level_1/fl_control_group/data/build/settings new file mode 100644 index 0000000..ca16cd7 --- /dev/null +++ b/level_1/fl_control_group/data/build/settings @@ -0,0 +1,55 @@ +# fss-0001 + +project_name fl_control_group + +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_file -lf_memory +build_sources_library control_group.c +build_sources_program +build_sources_headers control_group.h +build_sources_script +build_sources_setting +build_script yes +build_shared yes +build_static yes + +path_headers level_1 +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 diff --git a/level_1/fl_directory/c/directory.h b/level_1/fl_directory/c/directory.h index c89197f..46e55c4 100644 --- a/level_1/fl_directory/c/directory.h +++ b/level_1/fl_directory/c/directory.h @@ -83,7 +83,7 @@ extern "C" { f_directory_statuss_t *failures; } fl_directory_recurse_t; - #define fl_directory_recurse_t_initialize { fl_directory_recurse_depth_max, f_file_default_read_size, F_false, f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), 0, 0 } + #define fl_directory_recurse_t_initialize { fl_directory_recurse_depth_max, f_file_default_read_size, F_false, f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), 0, 0 } #endif // _di_fl_directory_recurse_t_ /** diff --git a/level_1/fl_execute/c/execute-common.h b/level_1/fl_execute/c/execute-common.h index 455b5b7..7cc9e2c 100644 --- a/level_1/fl_execute/c/execute-common.h +++ b/level_1/fl_execute/c/execute-common.h @@ -80,13 +80,13 @@ extern "C" { * Control Groups, or cgroups, exist here as a full file path in which the PID of a child process is to be written to. * This may change as more is learned about using cgroups, but it is not known if there are any functions available like set_cgroup(..). * - * nice: the niceness value to assign the child process to, set to 0 to not use. - * id_user: the id of the user to assign the child process to, set to 0 to not use. - * id_group: the id of the group to assign the child process to, set to 0 to not use. - * capability: all of the capabilities to assign the child process to, set to 0 to not use (f_capability_t is a pointer). - * id_groups: the ids of each supplemental group to assign the child process to, set to 0 to not use. - * scheduler: the scheduler to assign the child process to, set to 0 to not use. - * controls: an array of cgroups (control groups) to assign the child PID to, set to 0 to not use. + * nice: the niceness value to assign the child process to, set to 0 to not use. + * id_user: the id of the user to assign the child process to, set to 0 to not use. + * id_group: the id of the group to assign the child process to, set to 0 to not use. + * capability: all of the capabilities to assign the child process to, set to 0 to not use (f_capability_t is a pointer). + * id_groups: the ids of each supplemental group to assign the child process to, set to 0 to not use. + * scheduler: the scheduler to assign the child process to, set to 0 to not use. + * control_group: an array of cgroups (control groups) to assign the child PID to, set to 0 to not use. */ #ifndef _di_fl_execute_as_t_ typedef struct { @@ -97,12 +97,12 @@ extern "C" { f_int32s_t *id_groups; fl_execute_scheduler_t *scheduler; - f_string_dynamics_t *controls; + f_control_group_t *control_group; } fl_execute_as_t; #define fl_execute_as_t_initialize { 0, 0, 0, 0, 0, 0, 0 } - #define fl_macro_execute_as_t_initialize(nice, id_user, id_group, capability, id_groups, scheduler, controls) { nice, id_user, id_group, capability, id_groups, scheduler, controls } + #define fl_macro_execute_as_t_initialize(nice, id_user, id_group, capability, id_groups, scheduler, control_group) { nice, id_user, id_group, capability, id_groups, scheduler, control_group } #define fl_execute_as_t_clear(as) \ as.nice = 0; \ @@ -111,7 +111,7 @@ extern "C" { as.capability = 0; \ as.id_groups = 0; \ as.scheduler = 0; \ - as.controls = 0; + as.control_group = 0; #endif // _di_fl_execute_as_t_ #ifdef __cplusplus diff --git a/level_1/fl_execute/c/execute.h b/level_1/fl_execute/c/execute.h index ab3ba2d..9f03005 100644 --- a/level_1/fl_execute/c/execute.h +++ b/level_1/fl_execute/c/execute.h @@ -14,6 +14,9 @@ #ifndef _FL_execute_h #define _FL_execute_h +// include pre-requirements +#define _GNU_SOURCE + // libc includes #include #include diff --git a/level_1/fl_execute/data/build/settings b/level_1/fl_execute/data/build/settings index a13c57c..bdcf717 100644 --- a/level_1/fl_execute/data/build/settings +++ b/level_1/fl_execute/data/build/settings @@ -29,7 +29,7 @@ build_script yes build_shared yes build_static yes -path_headers level_0 +path_headers level_1 path_headers_preserve no path_library_script script path_library_shared shared diff --git a/level_1/fl_status/c/status.c b/level_1/fl_status/c/status.c index 0b311ca..aae9382 100644 --- a/level_1/fl_status/c/status.c +++ b/level_1/fl_status/c/status.c @@ -272,6 +272,18 @@ extern "C" { case F_container_not: *string = FL_status_string_container_not; break; + case F_control: + *string = FL_status_string_control; + break; + case F_control_not: + *string = FL_status_string_control_not; + break; + case F_control_group: + *string = FL_status_string_control_group; + break; + case F_control_group_not: + *string = FL_status_string_control_group_not; + break; case F_critical: *string = FL_status_string_critical; break; diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h index f11acf6..9a3710f 100644 --- a/level_1/fl_status/c/status.h +++ b/level_1/fl_status/c/status.h @@ -163,283 +163,291 @@ extern "C" { #endif // _di_F_status_signal_ #ifndef _di_F_status_basic_ - #define FL_status_string_none "F_none" - #define FL_status_string_absolute "F_absolute" - #define FL_status_string_absolute_not "F_absolute_not" - #define FL_status_string_address "F_address" - #define FL_status_string_address_not "F_address_not" - #define FL_status_string_block "F_block" - #define FL_status_string_block_not "F_block_not" - #define FL_status_string_bound "F_bound" - #define FL_status_string_bound_not "F_bound_not" - #define FL_status_string_capability "F_capability" - #define FL_status_string_capability_not "F_capability_not" - #define FL_status_string_child "F_child" - #define FL_status_string_child_not "F_child_not" - #define FL_status_string_complete "F_complete" - #define FL_status_string_complete_not "F_complete_not" - #define FL_status_string_connected "F_connected" - #define FL_status_string_connected_not "F_connected_not" - #define FL_status_string_container "F_container" - #define FL_status_string_container_not "F_container_not" - #define FL_status_string_critical "F_critical" - #define FL_status_string_critical_not "F_critical_not" - #define FL_status_string_deadlock "F_deadlock" - #define FL_status_string_deadlock_not "F_deadlock_not" - #define FL_status_string_descriptor "F_descriptor" - #define FL_status_string_descriptor_not "F_descriptor_not" - #define FL_status_string_device "F_device" - #define FL_status_string_device_not "F_device_not" - #define FL_status_string_dummy "F_dummy" - #define FL_status_string_dummy_not "F_dummy_not" - #define FL_status_string_encoding "F_encoding" - #define FL_status_string_encoding_not "F_encoding_not" - #define FL_status_string_eof "F_eof" - #define FL_status_string_eof_not "F_eof_not" - #define FL_status_string_eol "F_eol" - #define FL_status_string_eol_not "F_eol_not" - #define FL_status_string_eos "F_eos" - #define FL_status_string_eos_not "F_eos_not" - #define FL_status_string_exist "F_exist" - #define FL_status_string_exist_not "F_exist_not" - #define FL_status_string_failure "F_failure" - #define FL_status_string_failure_not "F_failure_not" - #define FL_status_string_fork "F_fork" - #define FL_status_string_fork_not "F_fork_not" - #define FL_status_string_found "F_found" - #define FL_status_string_found_not "F_found_not" - #define FL_status_string_group "F_group" - #define FL_status_string_group_not "F_group_not" - #define FL_status_string_ignore "F_ignore" - #define FL_status_string_ignore_not "F_ignore_not" - #define FL_status_string_input "F_input" - #define FL_status_string_input_not "F_input_not" - #define FL_status_string_input_output "F_input_output" - #define FL_status_string_interrupt "F_interrupt" - #define FL_status_string_interrupt_not "F_interrupt_not" - #define FL_status_string_known "F_known" - #define FL_status_string_known_not "F_known_not" - #define FL_status_string_link "F_link" - #define FL_status_string_link_not "F_link_not" - #define FL_status_string_lock "F_lock" - #define FL_status_string_lock_not "F_lock_not" - #define FL_status_string_loop "F_loop" - #define FL_status_string_loop_not "F_loop_not" - #define FL_status_string_maybe "F_maybe" - #define FL_status_string_maybe_not "F_maybe_not" - #define FL_status_string_minor "F_minor" - #define FL_status_string_minor_not "F_minor_not" - #define FL_status_string_moderate "F_moderate" - #define FL_status_string_moderate_not "F_moderate_not" - #define FL_status_string_mount "F_mount" - #define FL_status_string_mount_not "F_mount_not" - #define FL_status_string_name "F_name" - #define FL_status_string_name_not "F_name_not" - #define FL_status_string_nice "F_nice" - #define FL_status_string_nice_not "F_nice_not" - #define FL_status_string_optional "F_optional" - #define FL_status_string_optional_not "F_optional_not" - #define FL_status_string_output "F_output" - #define FL_status_string_output_not "F_output_not" - #define FL_status_string_parameter "F_parameter" - #define FL_status_string_parameter_not "F_parameter_not" - #define FL_status_string_parent "F_parent" - #define FL_status_string_parent_not "F_parent_not" - #define FL_status_string_pipe "F_pipe" - #define FL_status_string_pipe_not "F_pipe_not" - #define FL_status_string_port "F_port" - #define FL_status_string_port_not "F_port_not" - #define FL_status_string_prohibited "F_prohibited" - #define FL_status_string_prohibited_not "F_prohibited_not" - #define FL_status_string_range "F_range" - #define FL_status_string_range_not "F_range_not" - #define FL_status_string_read "F_read" - #define FL_status_string_read_not "F_read_not" - #define FL_status_string_read_only "F_read_only" - #define FL_status_string_ready "F_ready" - #define FL_status_string_ready_not "F_ready_not" - #define FL_status_string_recurse "F_recurse" - #define FL_status_string_recurse_not "F_recurse_not" - #define FL_status_string_relative "F_relative" - #define FL_status_string_relative_not "F_relative_not" - #define FL_status_string_require "F_require" - #define FL_status_string_require_not "F_require_not" - #define FL_status_string_resource "F_resource" - #define FL_status_string_resource_not "F_resource_not" - #define FL_status_string_search "F_search" - #define FL_status_string_search_not "F_search_not" - #define FL_status_string_schedule "F_schedule" - #define FL_status_string_schedule_not "F_schedule_not" - #define FL_status_string_signal "F_signal" - #define FL_status_string_signal_not "F_signal_not" - #define FL_status_string_space "F_space" - #define FL_status_string_space_not "F_space_not" - #define FL_status_string_stop "F_stop" - #define FL_status_string_stop_not "F_stop_not" - #define FL_status_string_string "F_string" - #define FL_status_string_string_not "F_string_not" - #define FL_status_string_string_too_large "F_string_too_large" - #define FL_status_string_string_too_small "F_string_too_small" - #define FL_status_string_syntax "F_syntax" - #define FL_status_string_syntax_not "F_syntax_not" - #define FL_status_string_supported "F_supported" - #define FL_status_string_supported_not "F_supported_not" - #define FL_status_string_user "F_user" - #define FL_status_string_user_not "F_user_not" - #define FL_status_string_utf "F_utf" - #define FL_status_string_utf_not "F_utf_not" - #define FL_status_string_valid "F_valid" - #define FL_status_string_valid_not "F_valid_not" - #define FL_status_string_value "F_value" - #define FL_status_string_value_not "F_value_not" - #define FL_status_string_wait "F_wait" - #define FL_status_string_wait_not "F_wait_not" - #define FL_status_string_warn "F_warn" - #define FL_status_string_warn_not "F_warn_not" - #define FL_status_string_world "F_world" - #define FL_status_string_world_not "F_world_not" - #define FL_status_string_write "F_write" - #define FL_status_string_write_not "F_write_not" - #define FL_status_string_write_only "F_write_only" - - #define FL_status_string_none_length 6 - #define FL_status_string_absolute_length 10 - #define FL_status_string_absolute_not_length 14 - #define FL_status_string_address_length 9 - #define FL_status_string_address_not_length 13 - #define FL_status_string_block_length 7 - #define FL_status_string_block_not_length 11 - #define FL_status_string_bound_length 7 - #define FL_status_string_bound_not_length 11 - #define FL_status_string_capability_length 12 - #define FL_status_string_capability_not_length 16 - #define FL_status_string_child_length 7 - #define FL_status_string_child_not_length 11 - #define FL_status_string_complete_length 10 - #define FL_status_string_complete_not_length 14 - #define FL_status_string_connected_length 11 - #define FL_status_string_connected_not_length 15 - #define FL_status_string_container_length 11 - #define FL_status_string_container_not_length 15 - #define FL_status_string_critical_length 10 - #define FL_status_string_critical_not_length 14 - #define FL_status_string_deadlock_length 10 - #define FL_status_string_deadlock_not_length 14 - #define FL_status_string_descriptor_length 12 - #define FL_status_string_descriptor_not_length 16 - #define FL_status_string_device_length 8 - #define FL_status_string_device_not_length 12 - #define FL_status_string_dummy_length 7 - #define FL_status_string_dummy_not_length 11 - #define FL_status_string_encoding_length 10 - #define FL_status_string_encoding_not_length 14 - #define FL_status_string_eof_length 5 - #define FL_status_string_eof_not_length 9 - #define FL_status_string_eol_length 5 - #define FL_status_string_eol_not_length 9 - #define FL_status_string_eos_length 5 - #define FL_status_string_eos_not_length 9 - #define FL_status_string_exist_length 7 - #define FL_status_string_exist_not_length 11 - #define FL_status_string_failure_length 9 - #define FL_status_string_failure_not_length 13 - #define FL_status_string_fork_length 6 - #define FL_status_string_fork_not_length 10 - #define FL_status_string_found_length 7 - #define FL_status_string_found_not_length 11 - #define FL_status_string_group_length 7 - #define FL_status_string_group_not_length 11 - #define FL_status_string_ignore_length 8 - #define FL_status_string_ignore_not_length 12 - #define FL_status_string_input_length 7 - #define FL_status_string_input_not_length 11 - #define FL_status_string_input_output_length 14 - #define FL_status_string_interrupt_length 11 - #define FL_status_string_interrupt_not_length 15 - #define FL_status_string_known_length 7 - #define FL_status_string_known_not_length 11 - #define FL_status_string_link_length 6 - #define FL_status_string_link_not_length 10 - #define FL_status_string_lock_length 6 - #define FL_status_string_lock_not_length 10 - #define FL_status_string_loop_length 6 - #define FL_status_string_loop_not_length 10 - #define FL_status_string_maybe_length 7 - #define FL_status_string_maybe_not_length 11 - #define FL_status_string_minor_length 7 - #define FL_status_string_minor_not_length 11 - #define FL_status_string_moderate_length 10 - #define FL_status_string_moderate_not_length 14 - #define FL_status_string_mount_length 7 - #define FL_status_string_mount_not_length 11 - #define FL_status_string_name_length 6 - #define FL_status_string_name_not_length 10 - #define FL_status_string_nice_length 6 - #define FL_status_string_nice_not_length 10 - #define FL_status_string_optional_length 10 - #define FL_status_string_optional_not_length 14 - #define FL_status_string_output_length 8 - #define FL_status_string_output_not_length 12 - #define FL_status_string_parameter_length 11 - #define FL_status_string_parameter_not_length 15 - #define FL_status_string_parent_length 8 - #define FL_status_string_parent_not_length 12 - #define FL_status_string_pipe_length 6 - #define FL_status_string_pipe_not_length 10 - #define FL_status_string_port_length 6 - #define FL_status_string_port_not_length 10 - #define FL_status_string_prohibited_length 12 - #define FL_status_string_prohibited_not_length 16 - #define FL_status_string_range_length 7 - #define FL_status_string_range_not_length 11 - #define FL_status_string_read_length 6 - #define FL_status_string_read_not_length 10 - #define FL_status_string_read_only_length 11 - #define FL_status_string_ready_length 7 - #define FL_status_string_ready_not_length 11 - #define FL_status_string_recurse_length 9 - #define FL_status_string_recurse_not_length 13 - #define FL_status_string_relative_length 10 - #define FL_status_string_relative_not_length 14 - #define FL_status_string_require_length 9 - #define FL_status_string_require_not_length 13 - #define FL_status_string_resource_length 10 - #define FL_status_string_resource_not_length 14 - #define FL_status_string_search_length 8 - #define FL_status_string_search_not_length 12 - #define FL_status_string_schedule_length 10 - #define FL_status_string_schedule_not_length 14 - #define FL_status_string_signal_length 8 - #define FL_status_string_signal_not_length 12 - #define FL_status_string_space_length 7 - #define FL_status_string_space_not_length 11 - #define FL_status_string_stop_length 6 - #define FL_status_string_stop_not_length 10 - #define FL_status_string_string_length 8 - #define FL_status_string_string_not_length 12 - #define FL_status_string_string_too_large_length 18 - #define FL_status_string_string_too_small_length 18 - #define FL_status_string_supported_length 11 - #define FL_status_string_supported_not_length 15 - #define FL_status_string_syntax_length 8 - #define FL_status_string_syntax_not_length 12 - #define FL_status_string_user_length 6 - #define FL_status_string_user_not_length 10 - #define FL_status_string_utf_length 5 - #define FL_status_string_utf_not_length 9 - #define FL_status_string_valid_length 7 - #define FL_status_string_valid_not_length 11 - #define FL_status_string_value_length 7 - #define FL_status_string_value_not_length 11 - #define FL_status_string_wait_length 6 - #define FL_status_string_wait_not_length 10 - #define FL_status_string_warn_length 6 - #define FL_status_string_warn_not_length 10 - #define FL_status_string_world_length 7 - #define FL_status_string_world_not_length 11 - #define FL_status_string_write_length 7 - #define FL_status_string_write_not_length 11 - #define FL_status_string_write_only_length 12 + #define FL_status_string_none "F_none" + #define FL_status_string_absolute "F_absolute" + #define FL_status_string_absolute_not "F_absolute_not" + #define FL_status_string_address "F_address" + #define FL_status_string_address_not "F_address_not" + #define FL_status_string_block "F_block" + #define FL_status_string_block_not "F_block_not" + #define FL_status_string_bound "F_bound" + #define FL_status_string_bound_not "F_bound_not" + #define FL_status_string_capability "F_capability" + #define FL_status_string_capability_not "F_capability_not" + #define FL_status_string_child "F_child" + #define FL_status_string_child_not "F_child_not" + #define FL_status_string_complete "F_complete" + #define FL_status_string_complete_not "F_complete_not" + #define FL_status_string_connected "F_connected" + #define FL_status_string_connected_not "F_connected_not" + #define FL_status_string_container "F_container" + #define FL_status_string_container_not "F_container_not" + #define FL_status_string_control "F_control" + #define FL_status_string_control_not "F_control_not" + #define FL_status_string_control_group "F_control_group" + #define FL_status_string_control_group_not "F_control_group_not" + #define FL_status_string_critical "F_critical" + #define FL_status_string_critical_not "F_critical_not" + #define FL_status_string_deadlock "F_deadlock" + #define FL_status_string_deadlock_not "F_deadlock_not" + #define FL_status_string_descriptor "F_descriptor" + #define FL_status_string_descriptor_not "F_descriptor_not" + #define FL_status_string_device "F_device" + #define FL_status_string_device_not "F_device_not" + #define FL_status_string_dummy "F_dummy" + #define FL_status_string_dummy_not "F_dummy_not" + #define FL_status_string_encoding "F_encoding" + #define FL_status_string_encoding_not "F_encoding_not" + #define FL_status_string_eof "F_eof" + #define FL_status_string_eof_not "F_eof_not" + #define FL_status_string_eol "F_eol" + #define FL_status_string_eol_not "F_eol_not" + #define FL_status_string_eos "F_eos" + #define FL_status_string_eos_not "F_eos_not" + #define FL_status_string_exist "F_exist" + #define FL_status_string_exist_not "F_exist_not" + #define FL_status_string_failure "F_failure" + #define FL_status_string_failure_not "F_failure_not" + #define FL_status_string_fork "F_fork" + #define FL_status_string_fork_not "F_fork_not" + #define FL_status_string_found "F_found" + #define FL_status_string_found_not "F_found_not" + #define FL_status_string_group "F_group" + #define FL_status_string_group_not "F_group_not" + #define FL_status_string_ignore "F_ignore" + #define FL_status_string_ignore_not "F_ignore_not" + #define FL_status_string_input "F_input" + #define FL_status_string_input_not "F_input_not" + #define FL_status_string_input_output "F_input_output" + #define FL_status_string_interrupt "F_interrupt" + #define FL_status_string_interrupt_not "F_interrupt_not" + #define FL_status_string_known "F_known" + #define FL_status_string_known_not "F_known_not" + #define FL_status_string_link "F_link" + #define FL_status_string_link_not "F_link_not" + #define FL_status_string_lock "F_lock" + #define FL_status_string_lock_not "F_lock_not" + #define FL_status_string_loop "F_loop" + #define FL_status_string_loop_not "F_loop_not" + #define FL_status_string_maybe "F_maybe" + #define FL_status_string_maybe_not "F_maybe_not" + #define FL_status_string_minor "F_minor" + #define FL_status_string_minor_not "F_minor_not" + #define FL_status_string_moderate "F_moderate" + #define FL_status_string_moderate_not "F_moderate_not" + #define FL_status_string_mount "F_mount" + #define FL_status_string_mount_not "F_mount_not" + #define FL_status_string_name "F_name" + #define FL_status_string_name_not "F_name_not" + #define FL_status_string_nice "F_nice" + #define FL_status_string_nice_not "F_nice_not" + #define FL_status_string_optional "F_optional" + #define FL_status_string_optional_not "F_optional_not" + #define FL_status_string_output "F_output" + #define FL_status_string_output_not "F_output_not" + #define FL_status_string_parameter "F_parameter" + #define FL_status_string_parameter_not "F_parameter_not" + #define FL_status_string_parent "F_parent" + #define FL_status_string_parent_not "F_parent_not" + #define FL_status_string_pipe "F_pipe" + #define FL_status_string_pipe_not "F_pipe_not" + #define FL_status_string_port "F_port" + #define FL_status_string_port_not "F_port_not" + #define FL_status_string_prohibited "F_prohibited" + #define FL_status_string_prohibited_not "F_prohibited_not" + #define FL_status_string_range "F_range" + #define FL_status_string_range_not "F_range_not" + #define FL_status_string_read "F_read" + #define FL_status_string_read_not "F_read_not" + #define FL_status_string_read_only "F_read_only" + #define FL_status_string_ready "F_ready" + #define FL_status_string_ready_not "F_ready_not" + #define FL_status_string_recurse "F_recurse" + #define FL_status_string_recurse_not "F_recurse_not" + #define FL_status_string_relative "F_relative" + #define FL_status_string_relative_not "F_relative_not" + #define FL_status_string_require "F_require" + #define FL_status_string_require_not "F_require_not" + #define FL_status_string_resource "F_resource" + #define FL_status_string_resource_not "F_resource_not" + #define FL_status_string_search "F_search" + #define FL_status_string_search_not "F_search_not" + #define FL_status_string_schedule "F_schedule" + #define FL_status_string_schedule_not "F_schedule_not" + #define FL_status_string_signal "F_signal" + #define FL_status_string_signal_not "F_signal_not" + #define FL_status_string_space "F_space" + #define FL_status_string_space_not "F_space_not" + #define FL_status_string_stop "F_stop" + #define FL_status_string_stop_not "F_stop_not" + #define FL_status_string_string "F_string" + #define FL_status_string_string_not "F_string_not" + #define FL_status_string_string_too_large "F_string_too_large" + #define FL_status_string_string_too_small "F_string_too_small" + #define FL_status_string_syntax "F_syntax" + #define FL_status_string_syntax_not "F_syntax_not" + #define FL_status_string_supported "F_supported" + #define FL_status_string_supported_not "F_supported_not" + #define FL_status_string_user "F_user" + #define FL_status_string_user_not "F_user_not" + #define FL_status_string_utf "F_utf" + #define FL_status_string_utf_not "F_utf_not" + #define FL_status_string_valid "F_valid" + #define FL_status_string_valid_not "F_valid_not" + #define FL_status_string_value "F_value" + #define FL_status_string_value_not "F_value_not" + #define FL_status_string_wait "F_wait" + #define FL_status_string_wait_not "F_wait_not" + #define FL_status_string_warn "F_warn" + #define FL_status_string_warn_not "F_warn_not" + #define FL_status_string_world "F_world" + #define FL_status_string_world_not "F_world_not" + #define FL_status_string_write "F_write" + #define FL_status_string_write_not "F_write_not" + #define FL_status_string_write_only "F_write_only" + + #define FL_status_string_none_length 6 + #define FL_status_string_absolute_length 10 + #define FL_status_string_absolute_not_length 14 + #define FL_status_string_address_length 9 + #define FL_status_string_address_not_length 13 + #define FL_status_string_block_length 7 + #define FL_status_string_block_not_length 11 + #define FL_status_string_bound_length 7 + #define FL_status_string_bound_not_length 11 + #define FL_status_string_capability_length 12 + #define FL_status_string_capability_not_length 16 + #define FL_status_string_child_length 7 + #define FL_status_string_child_not_length 11 + #define FL_status_string_complete_length 10 + #define FL_status_string_complete_not_length 14 + #define FL_status_string_connected_length 11 + #define FL_status_string_connected_not_length 15 + #define FL_status_string_container_length 11 + #define FL_status_string_container_not_length 15 + #define FL_status_string_control_length 9 + #define FL_status_string_control_not_length 13 + #define FL_status_string_control_group_length 15 + #define FL_status_string_control_group_not_length 19 + #define FL_status_string_critical_length 10 + #define FL_status_string_critical_not_length 14 + #define FL_status_string_deadlock_length 10 + #define FL_status_string_deadlock_not_length 14 + #define FL_status_string_descriptor_length 12 + #define FL_status_string_descriptor_not_length 16 + #define FL_status_string_device_length 8 + #define FL_status_string_device_not_length 12 + #define FL_status_string_dummy_length 7 + #define FL_status_string_dummy_not_length 11 + #define FL_status_string_encoding_length 10 + #define FL_status_string_encoding_not_length 14 + #define FL_status_string_eof_length 5 + #define FL_status_string_eof_not_length 9 + #define FL_status_string_eol_length 5 + #define FL_status_string_eol_not_length 9 + #define FL_status_string_eos_length 5 + #define FL_status_string_eos_not_length 9 + #define FL_status_string_exist_length 7 + #define FL_status_string_exist_not_length 11 + #define FL_status_string_failure_length 9 + #define FL_status_string_failure_not_length 13 + #define FL_status_string_fork_length 6 + #define FL_status_string_fork_not_length 10 + #define FL_status_string_found_length 7 + #define FL_status_string_found_not_length 11 + #define FL_status_string_group_length 7 + #define FL_status_string_group_not_length 11 + #define FL_status_string_ignore_length 8 + #define FL_status_string_ignore_not_length 12 + #define FL_status_string_input_length 7 + #define FL_status_string_input_not_length 11 + #define FL_status_string_input_output_length 14 + #define FL_status_string_interrupt_length 11 + #define FL_status_string_interrupt_not_length 15 + #define FL_status_string_known_length 7 + #define FL_status_string_known_not_length 11 + #define FL_status_string_link_length 6 + #define FL_status_string_link_not_length 10 + #define FL_status_string_lock_length 6 + #define FL_status_string_lock_not_length 10 + #define FL_status_string_loop_length 6 + #define FL_status_string_loop_not_length 10 + #define FL_status_string_maybe_length 7 + #define FL_status_string_maybe_not_length 11 + #define FL_status_string_minor_length 7 + #define FL_status_string_minor_not_length 11 + #define FL_status_string_moderate_length 10 + #define FL_status_string_moderate_not_length 14 + #define FL_status_string_mount_length 7 + #define FL_status_string_mount_not_length 11 + #define FL_status_string_name_length 6 + #define FL_status_string_name_not_length 10 + #define FL_status_string_nice_length 6 + #define FL_status_string_nice_not_length 10 + #define FL_status_string_optional_length 10 + #define FL_status_string_optional_not_length 14 + #define FL_status_string_output_length 8 + #define FL_status_string_output_not_length 12 + #define FL_status_string_parameter_length 11 + #define FL_status_string_parameter_not_length 15 + #define FL_status_string_parent_length 8 + #define FL_status_string_parent_not_length 12 + #define FL_status_string_pipe_length 6 + #define FL_status_string_pipe_not_length 10 + #define FL_status_string_port_length 6 + #define FL_status_string_port_not_length 10 + #define FL_status_string_prohibited_length 12 + #define FL_status_string_prohibited_not_length 16 + #define FL_status_string_range_length 7 + #define FL_status_string_range_not_length 11 + #define FL_status_string_read_length 6 + #define FL_status_string_read_not_length 10 + #define FL_status_string_read_only_length 11 + #define FL_status_string_ready_length 7 + #define FL_status_string_ready_not_length 11 + #define FL_status_string_recurse_length 9 + #define FL_status_string_recurse_not_length 13 + #define FL_status_string_relative_length 10 + #define FL_status_string_relative_not_length 14 + #define FL_status_string_require_length 9 + #define FL_status_string_require_not_length 13 + #define FL_status_string_resource_length 10 + #define FL_status_string_resource_not_length 14 + #define FL_status_string_search_length 8 + #define FL_status_string_search_not_length 12 + #define FL_status_string_schedule_length 10 + #define FL_status_string_schedule_not_length 14 + #define FL_status_string_signal_length 8 + #define FL_status_string_signal_not_length 12 + #define FL_status_string_space_length 7 + #define FL_status_string_space_not_length 11 + #define FL_status_string_stop_length 6 + #define FL_status_string_stop_not_length 10 + #define FL_status_string_string_length 8 + #define FL_status_string_string_not_length 12 + #define FL_status_string_string_too_large_length 18 + #define FL_status_string_string_too_small_length 18 + #define FL_status_string_supported_length 11 + #define FL_status_string_supported_not_length 15 + #define FL_status_string_syntax_length 8 + #define FL_status_string_syntax_not_length 12 + #define FL_status_string_user_length 6 + #define FL_status_string_user_not_length 10 + #define FL_status_string_utf_length 5 + #define FL_status_string_utf_not_length 9 + #define FL_status_string_valid_length 7 + #define FL_status_string_valid_not_length 11 + #define FL_status_string_value_length 7 + #define FL_status_string_value_not_length 11 + #define FL_status_string_wait_length 6 + #define FL_status_string_wait_not_length 10 + #define FL_status_string_warn_length 6 + #define FL_status_string_warn_not_length 10 + #define FL_status_string_world_length 7 + #define FL_status_string_world_not_length 11 + #define FL_status_string_write_length 7 + #define FL_status_string_write_not_length 11 + #define FL_status_string_write_only_length 12 #endif // _di_F_status_basic_ #ifndef _di_F_status_array_ diff --git a/level_2/fll_control_group/c/control_group.c b/level_2/fll_control_group/c/control_group.c new file mode 100644 index 0000000..6aa95a0 --- /dev/null +++ b/level_2/fll_control_group/c/control_group.c @@ -0,0 +1,51 @@ +#include "control_group.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fll_control_group_prepare_ + f_return_status fll_control_group_prepare(const f_control_group_t control_group) { + f_status_t status = F_none; + + if (control_group.path.used) { + status = f_directory_exists(control_group.path.string); + if (F_status_is_error(status)) return status; + + if (status == F_false) { + return F_status_set_error(F_directory_not); + } + } + + f_string_length_t length = 0; + + for (f_array_length_t i = 0; i < control_group.groups.used; ++i) { + + if (!control_group.groups.array[i].used) continue; + + length = control_group.path.used + control_group.groups.array[i].used; + + char path[length + 1]; + + if (control_group.path.used) { + memcpy(path, control_group.path.string, control_group.path.used); + } + + memcpy(path + control_group.path.used, control_group.groups.array[i].string, control_group.groups.array[i].used); + path[length] = 0; + + status = fl_directory_create(path, length, f_file_mode_all_rwx); + if (F_status_is_error(status)) break; + } // for + + if (F_status_is_error(status)) { + return status; + } + + return F_none; + } +#endif // _di_fll_control_group_prepare_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_2/fll_control_group/c/control_group.h b/level_2/fll_control_group/c/control_group.h new file mode 100644 index 0000000..ba06370 --- /dev/null +++ b/level_2/fll_control_group/c/control_group.h @@ -0,0 +1,60 @@ +/** + * FLL - Level 2 + * + * Project: Control Group + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Provides control group (cgroup) related functionality. + */ +#ifndef _FLL_control_h +#define _FLL_control_h + +// libc includes + +// fll-0 includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fll-1 includes +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Make sure all directories specified in groups exist, creating all directories in the path. + * + * This does not, however, create the control_group.path and will error out if that directory does not exist. + * + * @param control + * The control group(s) to ensure the directories exist. + * + * @return + * F_none on success. + * F_directory_not (with error bit) if control_group.path does not exist. + * + * Errors (with error bit) from: f_directory_exists(). + * Errors (with error bit) from: fl_directory_create(). + * + * @see f_directory_exists() + * @see fl_directory_create() + */ +#ifndef _di_fll_control_group_prepare_ + extern f_return_status fll_control_group_prepare(const f_control_group_t control_group); +#endif // _di_fll_control_group_prepare_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _FLL_control_h diff --git a/level_2/fll_control_group/data/build/defines b/level_2/fll_control_group/data/build/defines new file mode 100644 index 0000000..4f13080 --- /dev/null +++ b/level_2/fll_control_group/data/build/defines @@ -0,0 +1 @@ +# fss-0000 diff --git a/level_2/fll_control_group/data/build/dependencies b/level_2/fll_control_group/data/build/dependencies new file mode 100644 index 0000000..5e94b53 --- /dev/null +++ b/level_2/fll_control_group/data/build/dependencies @@ -0,0 +1,13 @@ +# fss-0000 + +f_type +f_status +f_memory +f_string +f_utf +f_control_group +f_directory +f_file +f_path +fl_control_group +fl_directory diff --git a/level_2/fll_control_group/data/build/settings b/level_2/fll_control_group/data/build/settings new file mode 100644 index 0000000..6afda91 --- /dev/null +++ b/level_2/fll_control_group/data/build/settings @@ -0,0 +1,55 @@ +# fss-0001 + +project_name fll_control_group + +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 -lfl_control_group -lfl_directory -lf_directory -lf_file -lf_memory -lf_path -lf_utf +build_sources_library control_group.c +build_sources_program +build_sources_headers control_group.h +build_sources_script +build_sources_setting +build_script yes +build_shared yes +build_static yes + +path_headers level_2 +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 diff --git a/level_2/fll_error/c/error-common.h b/level_2/fll_error/c/error-common.h index b5d8e0c..6b15caa 100644 --- a/level_2/fll_error/c/error-common.h +++ b/level_2/fll_error/c/error-common.h @@ -64,7 +64,7 @@ extern "C" { } fll_error_print_t; #define fll_error_print_t_initialize { \ - f_macro_file_t_initialize(f_type_error, f_type_descriptor_error, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_error, f_type_descriptor_error, f_file_flag_write_only), \ f_console_verbosity_normal, \ fll_error_print_error, \ f_color_set_t_initialize, \ @@ -72,8 +72,8 @@ extern "C" { } #define fll_macro_error_print_t_initialize(to, verbosity, prefix, context, notable) { to, verbosity, prefix, context, notable } - #define fll_macro_error_print_t_initialize_debug() fll_macro_error_print_t_initialize(f_macro_file_t_initialize(f_type_debug, f_type_descriptor_debug, f_file_flag_write_only), f_console_verbosity_normal, fll_error_print_debug, f_color_set_t_initialize, f_color_set_t_initialize) - #define fll_macro_error_print_t_initialize_warning() fll_macro_error_print_t_initialize(f_macro_file_t_initialize(f_type_warning, f_type_descriptor_warning, f_file_flag_write_only), f_console_verbosity_normal, fll_error_print_warning, f_color_set_t_initialize, f_color_set_t_initialize) + #define fll_macro_error_print_t_initialize_debug() fll_macro_error_print_t_initialize(f_macro_file_t_initialize2(f_type_debug, f_type_descriptor_debug, f_file_flag_write_only), f_console_verbosity_normal, fll_error_print_debug, f_color_set_t_initialize, f_color_set_t_initialize) + #define fll_macro_error_print_t_initialize_warning() fll_macro_error_print_t_initialize(f_macro_file_t_initialize2(f_type_warning, f_type_descriptor_warning, f_file_flag_write_only), f_console_verbosity_normal, fll_error_print_warning, f_color_set_t_initialize, f_color_set_t_initialize) #endif // _di_fll_error_print_t_ #ifdef __cplusplus diff --git a/level_2/fll_execute/c/execute.h b/level_2/fll_execute/c/execute.h index 817a859..3db3dc5 100644 --- a/level_2/fll_execute/c/execute.h +++ b/level_2/fll_execute/c/execute.h @@ -13,6 +13,9 @@ #ifndef _FLL_execute_h #define _FLL_execute_h +// include pre-requirements +#define _GNU_SOURCE + // libc includes #include #include @@ -30,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +41,7 @@ #include // fll-1 includes +#include #include #include #include @@ -387,9 +392,11 @@ extern "C" { * 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 returns F_capability, F_group, and F_user only for the child process and must be treated the same as F_child for the purposes of understanding what the current process is. + * This returns F_capability, F_group, and F_user only by the child process and must be treated the same as F_child for the purposes of understanding what the current process is. * These are essentialy F_child with explicit error codes that are returned instead of performing the desired execution. * + * This returns F_control_group and F_schedule only by the parent process and represents that the child process could not be executed. + * * @param program * The name or path of the program. * The string pointer may be set to 0, to designate that the first index in arguments is assumed to be the program. @@ -420,14 +427,16 @@ extern "C" { * * @return * F_none on success. + * F_child on success but this is the child thread. * F_capability (with error bit) on failure to set capabilities in the child (only the child process returns this). + * F_control_group (with error bit) on failure to set capabilities in the child (only the parent process returns this). * F_child (with error bit) on any failure without an explicit failure code (like F_group) before calling execute but this is the child thread. * F_failure (with error bit) on execution failure. * F_fork (with error bit) on fork failure. * F_group (with error bit) on failure to set GID in the child (only the child process returns this). * F_nice (with error bit) on failure to set process niceness in the child (only the child process returns this). * F_pipe (with error bit) on pipe failure. - * F_schedule (with error bit) on failure to set scheduler in the child (only the child process returns this). + * F_schedule (with error bit) on failure to set scheduler in the child (only the parent process returns this). * F_user (with error bit) on failure to set UID in the child (only the child process returns this). * * Errors (with error bit) from: f_capability_process_set(). @@ -462,6 +471,7 @@ extern "C" { * @see f_environment_get() * @see f_file_exists() * @see f_signal_set_handle() + * @see fl_control_group_apply() * @see fl_environment_path_explode_dynamic() * @see fl_string_append() * @see fl_string_dynamic_terminate() diff --git a/level_2/fll_execute/c/private-execute.c b/level_2/fll_execute/c/private-execute.c index fdb45f3..3f5b0d2 100644 --- a/level_2/fll_execute/c/private-execute.c +++ b/level_2/fll_execute/c/private-execute.c @@ -117,7 +117,7 @@ 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_program_) - f_return_status private_fll_execute_as(const fl_execute_as_t as, fl_execute_parameter_t * const parameter, int *result) { + f_return_status private_fll_execute_as_child(const fl_execute_as_t as, fl_execute_parameter_t * const parameter, int *result) { if (as.nice) { errno = 0; @@ -133,25 +133,6 @@ extern "C" { } } - if (as.scheduler) { - const int process_id = getpid(); - - struct sched_param parameter_schedule; - parameter_schedule.sched_priority = as.scheduler->priority; - - errno = 0; - - if (sched_setscheduler(process_id, as.scheduler->policy, ¶meter_schedule) == -1) { - *result = -1; - - if (parameter && parameter->option & fl_execute_parameter_option_exit) { - exit(*result); - } - - return F_status_set_error(F_schedule); - } - } - if (as.capability) { const f_status_t status = f_capability_process_set(as.capability); @@ -207,18 +188,92 @@ extern "C" { #endif // !defined(_di_fll_execute_program_) #if !defined(_di_fll_execute_program_) + f_return_status private_fll_execute_as_parent(const fl_execute_as_t as, const pid_t id_child, fl_execute_parameter_t * const parameter, char *result) { + + if (as.scheduler) { + struct sched_param parameter_schedule; + parameter_schedule.sched_priority = as.scheduler->priority; + + errno = 0; + + if (sched_setscheduler(id_child, as.scheduler->policy, ¶meter_schedule) == -1) { + result[0] = '1'; + + return F_status_set_error(F_schedule); + } + } + + if (as.control_group) { + if (F_status_is_error(fl_control_group_apply(*as.control_group, id_child))) { + result[0] = '1'; + + return F_status_set_error(F_control_group); + } + } + + return F_none; + } +#endif // !defined(_di_fll_execute_program_) + +#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, fl_execute_as_t * const as, int *result) { - const pid_t process_id = fork(); + int descriptors[2] = { -1, -1 }; + + if (as) { + if (pipe(descriptors) == -1) { + return F_status_set_error(F_pipe); + } + } + + const pid_t id_process = fork(); + + if (id_process < 0) { + if (as) { + close(descriptors[0]); + close(descriptors[1]); + } - if (process_id < 0) { return F_status_set_error(F_fork); } - if (process_id) { + if (id_process) { + + if (as) { + + // close the read pipe for the parent. + close(descriptors[0]); + + // have the parent perform all appropriate access controls and then send either '0' for no error or '1' for error to the child. + { + char string_result[2] = { '0', 0 }; + + const f_file_t file = f_macro_file_t_initialize2(0, descriptors[1], f_file_flag_write_only); + + f_string_static_t result = f_string_static_t_initialize; + + result.string = string_result; + result.used = 1; + result.size = 2; + + const f_status_t status = private_fll_execute_as_parent(*as, id_process, parameter, string_result); + + // inform the child that it can now safely begin (or exit). + if (F_status_is_error(f_file_write(file, result, 0))) { + string_result[0] = '1'; + } + + // close the write pipe for the parent when finished writing. + close(descriptors[1]); + + if (F_status_is_error(status)) { + return status; + } + } + } // have the parent wait for the child process to finish. - waitpid(process_id, result, WUNTRACED | WCONTINUED); + waitpid(id_process, result, WUNTRACED | WCONTINUED); // this must explicitly check for 0 (as opposed to checking (!result)). if (result != 0) { @@ -232,6 +287,38 @@ extern "C" { return F_none; } + if (as) { + + // close the write pipe for the child. + close(descriptors[1]); + + char string_response[2] = { 0, 0 }; + + f_string_static_t response = f_string_static_t_initialize; + + response.string = string_response; + response.used = 0; + response.size = 2; + + const f_file_t file = f_macro_file_t_initialize(0, descriptors[0], f_file_flag_read_only, 1, 1); + + f_file_read_block(file, &response); + + if (!response.used || response.string[0] == '1') { + close(descriptors[0]); + + if (result) { + *result = -1; + } + + if (parameter && parameter->option & fl_execute_parameter_option_exit) { + exit(-1); + } + + return F_child; + } + } + if (parameter && parameter->signals) { f_signal_set_handle(SIG_BLOCK, ¶meter->signals->block); f_signal_set_handle(SIG_UNBLOCK, ¶meter->signals->block_not); @@ -246,7 +333,11 @@ extern "C" { } if (as) { - const f_status_t status = private_fll_execute_as(*as, parameter, result); + + // close the write pipe for the child when done. + close(descriptors[0]); + + const f_status_t status = private_fll_execute_as_child(*as, parameter, result); if (F_status_is_error(status)) { return status; @@ -276,32 +367,58 @@ extern "C" { return F_status_set_error(F_pipe); } - const pid_t process_id = fork(); + const pid_t id_process = fork(); - if (process_id < 0) { + if (id_process < 0) { close(descriptors[0]); close(descriptors[1]); return F_status_set_error(F_fork); } - if (process_id) { + if (id_process) { // close the read pipe for the parent. close(descriptors[0]); - // 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); + char string_result[2] = { '0', 0 }; + + const f_file_t file = f_macro_file_t_initialize2(0, descriptors[1], f_file_flag_write_only); + + f_status_t status = F_none; + + // have the parent perform all appropriate access controls and then send either '0' for no error or '1' for error to the child. + if (as) { + f_string_static_t result = f_string_static_t_initialize; - f_file_write(file, *parameter->data, 0); + result.string = string_result; + result.used = 1; + result.size = 2; + + status = private_fll_execute_as_parent(*as, id_process, parameter, string_result); + + // inform the child that it can now safely begin (or exit). + if (F_status_is_error(f_file_write(file, result, 0))) { + string_result[0] = '1'; + } + } + + // write all data, if child doesn't read this could block until child closes the pipe. + if (string_result[0] == '0') { + f_file_write(file, *parameter->data, 0); + } // close the write pipe for the parent when finished writing. close(descriptors[1]); + + if (F_status_is_error(status)) { + return status; + } } // have the parent wait for the child process to finish. - waitpid(process_id, result, WUNTRACED | WCONTINUED); + waitpid(id_process, result, WUNTRACED | WCONTINUED); // this must explicitly check for 0 (as opposed to checking (!result)). if (result != 0) { @@ -318,6 +435,35 @@ extern "C" { // close the write pipe for the child. close(descriptors[1]); + // wait for parent to tell child to begin. + if (as) { + char string_response[2] = { 0, 0 }; + + f_string_static_t response = f_string_static_t_initialize; + + response.string = string_response; + response.used = 0; + response.size = 2; + + const f_file_t file = f_macro_file_t_initialize(0, descriptors[0], f_file_flag_read_only, 1, 1); + + f_file_read_block(file, &response); + + if (!response.used || response.string[0] == '1') { + close(descriptors[0]); + + if (result) { + *result = -1; + } + + if (parameter && parameter->option & fl_execute_parameter_option_exit) { + exit(-1); + } + + return F_child; + } + } + if (parameter && parameter->signals) { f_signal_set_handle(SIG_BLOCK, ¶meter->signals->block); f_signal_set_handle(SIG_UNBLOCK, ¶meter->signals->block_not); @@ -334,7 +480,7 @@ extern "C" { dup2(descriptors[0], f_type_descriptor_input); if (as) { - const f_status_t status = private_fll_execute_as(*as, parameter, result); + const f_status_t status = private_fll_execute_as_child(*as, parameter, result); if (F_status_is_error(status)) { return status; diff --git a/level_2/fll_execute/c/private-execute.h b/level_2/fll_execute/c/private-execute.h index 3e9a048..e946412 100644 --- a/level_2/fll_execute/c/private-execute.h +++ b/level_2/fll_execute/c/private-execute.h @@ -139,7 +139,47 @@ extern "C" { * @see fll_execute_program() */ #if !defined(_di_fll_execute_program_) - extern f_return_status private_fll_execute_as(const fl_execute_as_t as, fl_execute_parameter_t * const parameter, int *result) f_gcc_attribute_visibility_internal; + extern f_return_status private_fll_execute_as_child(const fl_execute_as_t as, fl_execute_parameter_t * const parameter, int *result) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fll_execute_program_) + +/** + * Private function for perform the execute as operations. + * + * This should be executed in the parent thread. + * + * @param as + * The "as" operations to perform. + * @param id_child + * The child PID. + * @param parameter + * (optional) This and most of its fields are optional and are disabled when set to 0. + * This function only cares about "option" on this structure. + * option: + * A bitwise set of options, such as: fl_execute_parameter_option_exit, and fl_execute_parameter_option_path. + * @param result + * A NULL termianted 2-byte string array where the first character represents the return code ('0' for success, '1' for failure). + * + * @return + * F_none on success. + * F_capability (with error bit) on failure to set capabilities. + * F_group (with error bit) on failure to set GID. + * F_nice (with error bit) on failure to set process niceness. + * F_schedule (with error bit) on failure to set scheduler. + * F_user (with error bit) on failure to set UID. + * + * @see exit() + * @see getpid() + * @see nice() + * @see sched_setscheduler() + * @see setgid() + * @see setgroups() + * @see setuid() + * + * @see f_capability_process_set() + * @see fll_execute_program() + */ +#if !defined(_di_fll_execute_program_) + extern f_return_status private_fll_execute_as_parent(const fl_execute_as_t as, const pid_t id_child, fl_execute_parameter_t * const parameter, char *result) f_gcc_attribute_visibility_internal; #endif // !defined(_di_fll_execute_program_) /** @@ -176,23 +216,30 @@ extern "C" { * * @return * F_none on success. - * F_capability (with error bit) on failure to set capabilities in the child (only the child process returns this). * F_child on success but this is the child thread. + * F_capability (with error bit) on failure to set capabilities in the child (only the child process returns this). + * F_control_group (with error bit) on failure to set capabilities in the child (only the parent process returns this). + * F_child (with error bit) on any failure without an explicit failure code (like F_group) before calling execute but this is the child thread. * F_failure (with error bit) on execution failure. * F_fork (with error bit) on fork failure. * F_group (with error bit) on failure to set GID in the child (only the child process returns this). * F_nice (with error bit) on failure to set process niceness in the child (only the child process returns this). - * F_schedule (with error bit) on failure to set scheduler in the child (only the child process returns this). + * F_pipe (with error bit) on pipe failure. + * F_schedule (with error bit) on failure to set scheduler in the child (only the parent process returns this). * F_user (with error bit) on failure to set UID in the child (only the child process returns this). * * @see clearenv() + * @see close() + * @see dup2() * @see execv() * @see execvp() * @see fork() + * @see pipe() * @see waitpid() * * @see f_environment_set_dynamic() * @see f_signal_set_handle() + * @see fl_control_group_apply() * @see fll_execute_program() */ #if !defined(_di_fll_execute_program_) @@ -233,14 +280,16 @@ extern "C" { * * @return * F_none on success. - * F_capability (with error bit) on failure to set capabilities in the child (only the child process returns this). * F_child on success but this is the child thread. + * F_capability (with error bit) on failure to set capabilities in the child (only the child process returns this). + * F_control_group (with error bit) on failure to set capabilities in the child (only the parent process returns this). + * F_child (with error bit) on any failure without an explicit failure code (like F_group) before calling execute but this is the child thread. * F_failure (with error bit) on execution failure. * F_fork (with error bit) on fork failure. * F_group (with error bit) on failure to set GID in the child (only the child process returns this). * F_nice (with error bit) on failure to set process niceness in the child (only the child process returns this). * F_pipe (with error bit) on pipe failure. - * F_schedule (with error bit) on failure to set scheduler in the child (only the child process returns this). + * F_schedule (with error bit) on failure to set scheduler in the child (only the parent process returns this). * F_user (with error bit) on failure to set UID in the child (only the child process returns this). * * @see clearenv() diff --git a/level_2/fll_execute/data/build/dependencies b/level_2/fll_execute/data/build/dependencies index 9f34036..0b7c46f 100644 --- a/level_2/fll_execute/data/build/dependencies +++ b/level_2/fll_execute/data/build/dependencies @@ -4,12 +4,14 @@ f_type f_status f_memory f_string +f_account f_capability f_environment f_execute f_file f_path f_signal +fl_control_group fl_environment fl_execute fl_string diff --git a/level_2/fll_execute/data/build/settings b/level_2/fll_execute/data/build/settings index a789937..44665a6 100644 --- a/level_2/fll_execute/data/build/settings +++ b/level_2/fll_execute/data/build/settings @@ -19,7 +19,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -lcap -build_libraries-individual -lfl_environment -lfl_string -lf_capability -lf_environment -lf_file -lf_memory -lf_path -lf_signal -lf_utf +build_libraries-individual -lfl_control_group -lfl_environment -lfl_string -lf_account -lf_capability -lf_environment -lf_file -lf_memory -lf_path -lf_signal -lf_utf build_sources_library execute.c private-execute.c build_sources_program build_sources_headers execute.h diff --git a/level_2/fll_status/c/status.c b/level_2/fll_status/c/status.c index 6d749f5..41cfd2d 100644 --- a/level_2/fll_status/c/status.c +++ b/level_2/fll_status/c/status.c @@ -456,6 +456,26 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_control, length, FL_status_string_control_length) == F_equal_to) { + *code = F_control; + return F_none; + } + + if (fl_string_compare(string, FL_status_string_control_not, length, FL_status_string_control_not_length) == F_equal_to) { + *code = F_control_not; + return F_none; + } + + if (fl_string_compare(string, FL_status_string_control_group, length, FL_status_string_control_group_length) == F_equal_to) { + *code = F_control_group; + return F_none; + } + + if (fl_string_compare(string, FL_status_string_control_group_not, length, FL_status_string_control_group_not_length) == F_equal_to) { + *code = F_control_group_not; + return F_none; + } + if (fl_string_compare(string, FL_status_string_critical, length, FL_status_string_critical_length) == F_equal_to) { *code = F_critical; return F_none; diff --git a/level_3/byte_dump/c/byte_dump.h b/level_3/byte_dump/c/byte_dump.h index 67062b1..0829a66 100644 --- a/level_3/byte_dump/c/byte_dump.h +++ b/level_3/byte_dump/c/byte_dump.h @@ -231,7 +231,7 @@ extern "C" { byte_dump_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ 0, \ 0, \ diff --git a/level_3/control/c/control.h b/level_3/control/c/control.h index 0311111..8c92cfb 100644 --- a/level_3/control/c/control.h +++ b/level_3/control/c/control.h @@ -100,7 +100,7 @@ extern "C" { control_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_color_context_t_initialize, \ } diff --git a/level_3/controller/c/controller.h b/level_3/controller/c/controller.h index 4c4c826..28b4200 100644 --- a/level_3/controller/c/controller.h +++ b/level_3/controller/c/controller.h @@ -19,6 +19,9 @@ */ #ifndef _controller_h +// include pre-requirements +#define _GNU_SOURCE + // libc includes #include #include @@ -36,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -49,11 +53,13 @@ // fll-1 includes #include #include +#include #include #include #include // fll-2 includes +#include #include #include #include @@ -180,7 +186,7 @@ extern "C" { controller_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ fll_macro_error_print_t_initialize_warning(), \ 0, \ diff --git a/level_3/controller/c/private-common.h b/level_3/controller/c/private-common.h index 58a5ddc..714397a 100644 --- a/level_3/controller/c/private-common.h +++ b/level_3/controller/c/private-common.h @@ -23,12 +23,14 @@ extern "C" { #define controller_string_command "command" #define controller_string_consider "consider" #define controller_string_control "control" + #define controller_string_control_group "control_group" #define controller_string_deadline "deadline" #define controller_string_default "default" #define controller_string_define "define" #define controller_string_entry "entry" #define controller_string_entries "entries" #define controller_string_environment "environment" + #define controller_string_existing "existing" #define controller_string_fail "fail" #define controller_string_failsafe "failsafe" #define controller_string_fifo "fifo" @@ -42,6 +44,7 @@ extern "C" { #define controller_string_method "method" #define controller_string_name "name" #define controller_string_need "need" + #define controller_string_new "new" #define controller_string_nice "nice" #define controller_string_no "no" #define controller_string_optional "optional" @@ -85,12 +88,14 @@ extern "C" { #define controller_string_command_length 7 #define controller_string_consider_length 8 #define controller_string_control_length 7 + #define controller_string_control_group_length 13 #define controller_string_deadline_length 8 #define controller_string_define_length 6 #define controller_string_default_length 7 #define controller_string_entry_length 5 #define controller_string_entries_length 7 #define controller_string_environment_length 11 + #define controller_string_existing_length 8 #define controller_string_fail_length 4 #define controller_string_failsafe_length 8 #define controller_string_fifo_length 4 @@ -103,6 +108,7 @@ extern "C" { #define controller_string_method_length 6 #define controller_string_name_length 4 #define controller_string_need_length 4 + #define controller_string_new_length 3 #define controller_string_nice_length 4 #define controller_string_no_length 2 #define controller_string_optional_length 8 @@ -262,7 +268,7 @@ extern "C" { #ifndef _di_controller_rule_t_ enum { controller_rule_setting_type_capability = 1, - controller_rule_setting_type_control, + controller_rule_setting_type_control_group, controller_rule_setting_type_define, controller_rule_setting_type_environment, controller_rule_setting_type_group, @@ -284,10 +290,11 @@ extern "C" { #define controller_rule_option_wait 0x8 // bitwise codes representing properties on controller_rule_t that have been found in the rule file. - #define controller_rule_has_group 0x1 - #define controller_rule_has_nice 0x2 - #define controller_rule_has_scheduler 0x4 - #define controller_rule_has_user 0x8 + #define controller_rule_has_control_group 0x1 + #define controller_rule_has_group 0x2 + #define controller_rule_has_nice 0x4 + #define controller_rule_has_scheduler 0x8 + #define controller_rule_has_user 0x10 typedef struct { f_status_t status; @@ -306,7 +313,6 @@ extern "C" { f_string_dynamic_t id; f_string_dynamic_t name; - f_string_dynamic_t control; f_string_dynamic_t path; f_string_dynamic_t script; @@ -319,6 +325,7 @@ extern "C" { f_string_dynamics_t wish; f_capability_t capability; + f_control_group_t control_group; f_int32s_t groups; fl_execute_scheduler_t scheduler; @@ -341,7 +348,6 @@ extern "C" { f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ f_string_maps_t_initialize, \ f_string_maps_t_initialize, \ f_string_dynamics_t_initialize, \ @@ -349,6 +355,7 @@ extern "C" { f_string_dynamics_t_initialize, \ f_string_dynamics_t_initialize, \ f_capability_t_initialize, \ + f_control_group_t_initialize, \ f_int32s_t_initialize, \ fl_execute_scheduler_t_initialize, \ controller_rule_items_initialize, \ @@ -357,7 +364,6 @@ extern "C" { #define controller_macro_rule_t_delete_simple(rule) \ fl_string_dynamic_delete(&rule.id); \ fl_string_dynamic_delete(&rule.name); \ - fl_string_dynamic_delete(&rule.control); \ fl_string_dynamic_delete(&rule.path); \ fl_string_dynamic_delete(&rule.script); \ f_macro_string_maps_t_delete_simple(rule.define) \ @@ -367,6 +373,7 @@ extern "C" { fl_string_dynamics_delete(&rule.want); \ fl_string_dynamics_delete(&rule.wish); \ f_capability_delete(&rule.capability); \ + fl_control_group_delete(&rule.control_group); \ fl_type_int32s_delete(&rule.groups); \ controller_macro_rule_items_t_delete_simple(rule.items) #endif // _di_controller_rule_t_ diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index cb67233..04f6643 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -393,14 +393,19 @@ extern "C" { #endif // _di_controller_rule_error_print_ #ifndef _di_controller_rule_error_print_execute_ - void controller_rule_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code) { + void controller_rule_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code, const f_status_t status) { if (output.verbosity != f_console_verbosity_quiet) { fprintf(output.to.stream, "%c", f_string_eol_s[0]); fprintf(output.to.stream, "%s%sThe %s '", output.context.before->string, output.prefix ? output.prefix : f_string_empty_s, script_is ? controller_string_script : controller_string_program); fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, name ? name : f_string_empty_s, output.notable.after->string); - if (code) { + if (status == F_control_group || status == F_schedule) { + fprintf(output.to.stream, "%s' failed due to a failure to setup the '", output.context.before->string); + fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, status == F_control_group ? controller_string_control_group : controller_string_scheduler, output.notable.after->string); + fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol_s[0]); + } + else if (code) { fprintf(output.to.stream, "%s' failed with the exit code '", output.context.before->string); fprintf(output.to.stream, "%s%s%i%s", output.context.after->string, output.notable.before->string, code, output.notable.after->string); fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol_s[0]); @@ -484,14 +489,28 @@ extern "C" { as.scheduler = &rule->scheduler; } - if (rule->control.used) { - // @todo: as.controls = + if (rule->has & controller_rule_has_control_group) { + as.control_group = &rule->control_group; + + // make sure all required cgroup directories exist. + if (rule->status == F_known_not) { + status = fll_control_group_prepare(rule->control_group); + + if (F_status_is_error(status)) { + fll_error_print(data->error, F_status_set_fine(status), "fll_control_group_prepare", F_true); + + rule->status = F_status_set_error(F_failure); + return status; + } + } } status = fll_environment_load_names(rule->environment, &environment); if (F_status_is_error(status)) { fll_error_print(data->error, F_status_set_fine(status), "fll_environment_load_names", F_true); + + rule->status = F_status_set_error(F_failure); return status; } @@ -642,19 +661,21 @@ extern "C" { } if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_failure) { - controller_rule_error_print_execute(data->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result); + status = F_status_set_fine(status); + + if (status == F_control_group || status == F_failure || status == F_schedule) { + controller_rule_error_print_execute(data->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result, status); } - else if (F_status_set_fine(status) == F_file_found_not) { + else if (status == F_file_found_not) { controller_rule_error_print_execute_not_found(data->error, F_false, program); } else { - fll_error_print(data->error, F_status_set_fine(status), "fll_execute_program_environment", F_true); + fll_error_print(data->error, status, "fll_execute_program", F_true); } data->child = 0; - return status; + return F_status_set_error(status); } // @todo wait for pid file or timeout. @@ -693,15 +714,19 @@ extern "C" { } if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_failure) { - controller_rule_error_print_execute(data->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result); + status = F_status_set_fine(status); + + if (status == F_control_group || status == F_failure || status == F_schedule) { + controller_rule_error_print_execute(data->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result, status); } - else if (F_status_set_fine(status) == F_file_found_not) { + else if (status == F_file_found_not) { controller_rule_error_print_execute_not_found(data->error, F_false, program); } else { - fll_error_print(data->error, F_status_set_fine(status), "fll_execute_program_environment", F_true); + fll_error_print(data->error, status, "fll_execute_program", F_true); } + + status = F_status_set_error(status); } data->child = 0; @@ -1361,15 +1386,23 @@ extern "C" { rule->nice = 0; f_macro_time_spec_t_clear(rule->timestamp); + f_macro_control_group_t_clear(rule->control_group); rule->id.used = 0; rule->name.used = 0; - rule->control.used = 0; rule->path.used = 0; rule->scheduler.policy = 0; rule->scheduler.priority = 0; rule->script.used = 0; + for (f_array_length_t i = 0; i < rule->control_group.groups.used; ++i) { + rule->control_group.groups.array[i].used = 0; + } // for + + rule->control_group.as_new = F_false; + rule->control_group.path.used = 0; + rule->control_group.groups.used = 0; + rule->define.used = 0; rule->parameter.used = 0; @@ -1570,7 +1603,6 @@ extern "C" { return F_false; } - rule->status = F_none; return F_true; } #endif // _di_controller_rule_read_ @@ -1634,8 +1666,8 @@ extern "C" { if (fl_string_dynamic_compare_string(controller_string_capability, cache->name_item, controller_string_capability_length) == F_equal_to) { type = controller_rule_setting_type_capability; } - else if (fl_string_dynamic_compare_string(controller_string_control, cache->name_item, controller_string_control_length) == F_equal_to) { - type = controller_rule_setting_type_control; + else if (fl_string_dynamic_compare_string(controller_string_control_group, cache->name_item, controller_string_control_group_length) == F_equal_to) { + type = controller_rule_setting_type_control_group; } else if (fl_string_dynamic_compare_string(controller_string_define, cache->name_item, controller_string_define_length) == F_equal_to) { type = controller_rule_setting_type_define; @@ -1827,11 +1859,107 @@ extern "C" { continue; } - if (type == controller_rule_setting_type_control || type == controller_rule_setting_type_name || type == controller_rule_setting_type_path || type == controller_rule_setting_type_script) { - if (type == controller_rule_setting_type_control) { - setting_value = &rule->control; + if (type == controller_rule_setting_type_control_group) { + + if (cache->content_actions.array[i].used < 2 || rule->has & controller_rule_has_control_group) { + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol_s[0]); + fprintf(data.error.to.stream, "%s%sRule setting requires two or more Content.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s, data.error.context.after->string, f_string_eol_s[0]); + + controller_rule_error_print(data.error, *cache, F_false); + } + + if (F_status_is_error_not(status_return)) { + status_return = F_status_set_error(F_valid_not); + } + + continue; + } + + if (fl_string_dynamic_partial_compare_string(controller_string_existing, cache->buffer_item, controller_string_existing_length, cache->content_actions.array[i].array[0]) == F_equal_to) { + rule->control_group.as_new = F_false; + } + else if (fl_string_dynamic_partial_compare_string(controller_string_new, cache->buffer_item, controller_string_new_length, cache->content_actions.array[i].array[0]) == F_equal_to) { + rule->control_group.as_new = F_true; + } + else { + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol_s[0]); + fprintf(data.error.to.stream, "%s%sRule setting has an unknown option '", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s); + fprintf(data.error.to.stream, "%s%s", data.error.context.after->string, data.error.notable.before->string); + f_print_dynamic_partial(data.error.to.stream, cache->buffer_item, cache->content_actions.array[i].array[0]); + fprintf(data.error.to.stream, "%s%s'.%s%c", data.error.notable.after->string, data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]); + + controller_rule_error_print(data.error, *cache, F_false); + } + + if (F_status_is_error_not(status_return)) { + status_return = F_status_set_error(F_valid_not); + } + + continue; + } + + rule->control_group.path.used = 0; + + // @todo path prefix needs to be configurable via a parameter. + status = fl_string_append(f_control_group_path_system_prefix, f_control_group_path_system_prefix_length, &rule->control_group.path); + + if (F_status_is_error_not(status)) { + status = fl_string_append(f_control_group_path_system_default, f_control_group_path_system_default_length, &rule->control_group.path); + } + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true); + } + else { + rule->control_group.groups.used = 0; + + for (j = 1; j < cache->content_actions.array[i].used; ++j) { + + status = fl_string_dynamics_increase(&rule->control_group.groups); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true); + break; + } + + rule->control_group.groups.array[rule->control_group.groups.used].used = 0; + + status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[j], &rule->control_group.groups.array[rule->control_group.groups.used]); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true); + break; + } + + rule->control_group.groups.used++; + } // for } - else if (type == controller_rule_setting_type_name) { + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { + return status; + } + + rule->control_group.path.used = 0; + + if (F_status_is_error_not(status_return)) { + status_return = status; + } + + controller_rule_error_print(data.error, *cache, F_false); + continue; + } + + rule->has |= controller_rule_has_control_group; + + continue; + } + + if (type == controller_rule_setting_type_name || type == controller_rule_setting_type_path || type == controller_rule_setting_type_script) { + if (type == controller_rule_setting_type_name) { setting_value = &rule->name; } else if (type == controller_rule_setting_type_path) { @@ -1857,7 +1985,7 @@ extern "C" { continue; } - if (type == controller_rule_setting_type_control || type == controller_rule_setting_type_name || type == controller_rule_setting_type_script) { + if (type == controller_rule_setting_type_name || type == controller_rule_setting_type_script) { status = controller_string_dynamic_rip_nulless_terminated(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value); @@ -1876,12 +2004,7 @@ extern "C" { continue; } - if (type == controller_rule_setting_type_control) { - // @todo validate that this is a valid path. - // @todo append setting.path_control, then path_separator, and then this string. - // @todo the control path doesn't have to exist just yet, but print a warning if it doesn't and debug is visible. - } - else if (type == controller_rule_setting_type_name || type == controller_rule_setting_type_script) { + if (type == controller_rule_setting_type_name || type == controller_rule_setting_type_script) { status = controller_validate_has_graph(*setting_value); if (status == F_false || F_status_set_fine(status) == F_complete_not_utf) { @@ -1952,7 +2075,6 @@ extern "C" { continue; } - if (type == controller_rule_setting_type_scheduler) { if (cache->content_actions.array[i].used < 1 || cache->content_actions.array[i].used > 2 || rule->has & controller_rule_has_scheduler) { @@ -2623,9 +2745,19 @@ extern "C" { fprintf(data.output.stream, "%s(unsupported)%s%c", data.context.set.warning.before->string, data.context.set.warning.after->string, f_string_eol_s[0]); } - fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_control, data.context.set.important.after->string, rule->control.used ? rule->control.string : f_string_empty_s, f_string_eol_s[0]); - fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_path, data.context.set.important.after->string, rule->path.used ? rule->path.string : f_string_empty_s, f_string_eol_s[0]); + fprintf(data.output.stream, " %s%s%s", data.context.set.important.before->string, controller_string_control_group, data.context.set.important.after->string); + if (rule->has & controller_rule_has_control_group) { + fprintf(data.output.stream, " %s", rule->control_group.as_new ? controller_string_new : controller_string_existing); + + for (i = 0; i < rule->control_group.groups.used; ++i) { + if (rule->control_group.groups.array[i].used) { + fprintf(data.output.stream, " "); + f_print_dynamic(data.output.stream, rule->control_group.groups.array[i]); + } + } // for + } + fprintf(data.output.stream, "%c", f_string_eol_s[0]); fprintf(data.output.stream, " %s%s%s", data.context.set.important.before->string, controller_string_scheduler, data.context.set.important.after->string); if (rule->has & controller_rule_has_scheduler) { diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h index 3f67e1c..b5f14ac 100644 --- a/level_3/controller/c/private-rule.h +++ b/level_3/controller/c/private-rule.h @@ -164,9 +164,11 @@ extern "C" { * The name of the program or script. * @param code * The code returned by the executed program or script. + * @param status + * The status code representing the failure (without the error bit set). */ #ifndef _di_controller_rule_error_print_execute_ - extern void controller_rule_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code) f_gcc_attribute_visibility_internal; + extern void controller_rule_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code, const f_status_t status) f_gcc_attribute_visibility_internal; #endif // _di_controller_rule_error_print_execute_ /** @@ -206,7 +208,7 @@ extern "C" { * @param cache * A structure for containing and caching relevant data. * @param index - * The position in the setting.rules array representing the rule to simulate. + * The position in the setting.rules array representing the rule to execute. * @param type * The action to perform based on the action type codes. * diff --git a/level_3/controller/data/build/dependencies b/level_3/controller/data/build/dependencies index 5af11e3..3f87592 100644 --- a/level_3/controller/data/build/dependencies +++ b/level_3/controller/data/build/dependencies @@ -9,6 +9,7 @@ f_account f_capability f_color f_console +f_control_group f_conversion f_directory f_environment @@ -22,11 +23,13 @@ f_print f_signal fl_color fl_console +fl_control_group fl_conversion fl_fss fl_iki fl_string fl_type +fll_control_group fll_environment fll_error fll_execute diff --git a/level_3/controller/data/build/settings b/level_3/controller/data/build/settings index 5e3ed2b..d780fc7 100644 --- a/level_3/controller/data/build/settings +++ b/level_3/controller/data/build/settings @@ -19,7 +19,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -lcap -build_libraries-individual -lfll_environment -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_conversion -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_type -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf +build_libraries-individual -lfll_control_group -lfll_environment -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_control_group -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_type -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_sources_library controller.c private-control.c private-controller.c private-entry.c private-rule.c diff --git a/level_3/controller/data/settings/example/entries/test.entry b/level_3/controller/data/settings/example/entries/test.entry index 2cfb52d..2efd908 100644 --- a/level_3/controller/data/settings/example/entries/test.entry +++ b/level_3/controller/data/settings/example/entries/test.entry @@ -11,6 +11,8 @@ main: item last first: + consider script require_me + rule script succeed rule script php rule command multiple diff --git a/level_3/controller/data/settings/example/rules/command/multiple.rule b/level_3/controller/data/settings/example/rules/command/multiple.rule index da9ca3f..bb18ec3 100644 --- a/level_3/controller/data/settings/example/rules/command/multiple.rule +++ b/level_3/controller/data/settings/example/rules/command/multiple.rule @@ -3,11 +3,21 @@ setting: name "Multiple Commands: id, whoami, date, etc.." capability "all=" + control_group new memory/example nice 15 scheduler batch 0 #user kevin #group list 8 root + need script require_me + +script: + start { + echo + echo "Current cgroup for self (PPID $PPID, PID $$) is: '$(cat /proc/self/cgroup)'" + sleep 20 + } + command: start { id diff --git a/level_3/controller/data/settings/example/rules/script/fail.rule b/level_3/controller/data/settings/example/rules/script/fail.rule index e2671cf..bfc0f0b 100644 --- a/level_3/controller/data/settings/example/rules/script/fail.rule +++ b/level_3/controller/data/settings/example/rules/script/fail.rule @@ -1,7 +1,7 @@ # fss-000d setting: - name "Scipt #2" + name "Script #2" need script succeed script: diff --git a/level_3/controller/data/settings/example/rules/script/require_me.rule b/level_3/controller/data/settings/example/rules/script/require_me.rule new file mode 100644 index 0000000..2cc1cc8 --- /dev/null +++ b/level_3/controller/data/settings/example/rules/script/require_me.rule @@ -0,0 +1,14 @@ +# fss-000d + +setting: + name "Example script for needs, wants, and wishes." + environment PATH + script sh + +script: + start { + echo + echo "This should be included via a need, want, or wish." + echo + } + diff --git a/level_3/controller/data/settings/example/rules/script/succeed.rule b/level_3/controller/data/settings/example/rules/script/succeed.rule index 9080c60..925df1c 100644 --- a/level_3/controller/data/settings/example/rules/script/succeed.rule +++ b/level_3/controller/data/settings/example/rules/script/succeed.rule @@ -1,7 +1,7 @@ # fss-000d setting: - name "Scipt #1" + name "Script #1" environment PATH script sh diff --git a/level_3/controller/documents/rule.txt b/level_3/controller/documents/rule.txt index 1fdf144..45199d6 100644 --- a/level_3/controller/documents/rule.txt +++ b/level_3/controller/documents/rule.txt @@ -10,7 +10,7 @@ Rule Documentation: The "settings" Rule Type has the following FSS-0001 (Extended) Content\: "capability": Define a set of capabilities in which to use, using the capability "text" format (such as "= cap_chown+ep"). - "control": Define a control group (cgroup) in which everything within this rule executes under. + "control_group": Define a control group (cgroup) in which everything within this rule executes under. "define": Define a custom environment variable with a given variable, and automatically expose it to processes executed within this rule. "environment": A set of environment variables to expose to the processes executed within this rule (PATH is always exposed). "group": A set of group names or IDs to execute as with the first group being the primary group and all remaining being supplementary groups. @@ -30,6 +30,8 @@ Rule Documentation: Due to capabilities only being a draft in the POSIX standard, one may expect "capabilities" support may not be available and in such a case this setting will do nothing. If the dependent project (f_capability) does not have libcap support enabled, then capabilities will be unsupported by the compilation of this project. + In the case of "control", the first argument is either "existing" or "new", where for "existing" the process is run inside the existing control used by the parent and when "new" the process is executed within a new control group namespace entirely. + In the case of "group" and "user", only users and groups that the user the controller program is being run as may be used. In the case of "want" and "wish", if the desired rule is either not found or is otherwise disabled, then this will not fail or otherwise block the wanting or wishing rule. @@ -75,11 +77,3 @@ Rule Documentation: The "create" Content designates that this controller program to create the PID file after successfully starting the service. The "use" Content designates that the called program will provide the PID file after successfully starting the service. For both "create" and "program" the PID file is expected to only exist on success or failure and the existence thereof designates the success or failure rate. - - The following Content are the same as those specified in the Settings above except that they apply to a specific Rule Item instead of all Rule Items in the file\: - - "capability" - - "control" - - "group" - - "nice" - - "scheduler" - - "user" diff --git a/level_3/controller/specifications/rule.txt b/level_3/controller/specifications/rule.txt index 5df9b62..32d1100 100644 --- a/level_3/controller/specifications/rule.txt +++ b/level_3/controller/specifications/rule.txt @@ -29,7 +29,7 @@ Rule Specification: The "settings" Rule Type has the following FSS-0001 (Extended)\: "capability": One Content representing capabilities. - "control": One Content representing a valid control group (cgroup) name, must have at least 1 graph character (non-whitespace printing character) (leading and trailing whitespace are trimmed off). + "control_group": Two or more Content, the first Content being either "existing" or "new" and the remaining representing a valid control group (cgroup) name, must have at least 1 graph character (non-whitespace printing character) (leading and trailing whitespace are trimmed off). "define": Two Content, the first Content must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits). "environment": Zero or more Content, each must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits). "group": One or more Content representing group names or group ids. diff --git a/level_3/fake/c/fake.h b/level_3/fake/c/fake.h index 00d187d..079fec4 100644 --- a/level_3/fake/c/fake.h +++ b/level_3/fake/c/fake.h @@ -444,7 +444,7 @@ extern "C" { fake_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ 0, \ 0, \ diff --git a/level_3/fake/c/private-fake.c b/level_3/fake/c/private-fake.c index 5f6addd..1e25980 100644 --- a/level_3/fake/c/private-fake.c +++ b/level_3/fake/c/private-fake.c @@ -73,7 +73,7 @@ extern "C" { } } else { - fll_error_print(data.error, F_status_set_fine(*status), "fll_execute_program_environment", F_true); + fll_error_print(data.error, F_status_set_fine(*status), "fll_execute_program", F_true); } } diff --git a/level_3/fake/c/private-make.c b/level_3/fake/c/private-make.c index 6366946..5b5a586 100644 --- a/level_3/fake/c/private-make.c +++ b/level_3/fake/c/private-make.c @@ -3834,7 +3834,7 @@ extern "C" { } } else if (F_status_set_fine(status) != F_failure) { - fll_error_print(data_make->error, F_status_set_fine(status), "fll_execute_program_environment", F_true); + fll_error_print(data_make->error, F_status_set_fine(status), "fll_execute_program", F_true); } } diff --git a/level_3/fake/data/build/dependencies b/level_3/fake/data/build/dependencies index 015d579..61eec48 100644 --- a/level_3/fake/data/build/dependencies +++ b/level_3/fake/data/build/dependencies @@ -21,6 +21,7 @@ f_print f_signal fl_color fl_console +fl_control_group fl_conversion fl_directory fl_fss diff --git a/level_3/fake/data/build/settings b/level_3/fake/data/build/settings index 4385448..e2165c8 100644 --- a/level_3/fake/data/build/settings +++ b/level_3/fake/data/build/settings @@ -19,7 +19,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -lcap -build_libraries-individual -lfll_environment -lfll_error -lfll_execute -lfll_file -lfll_fss -lfll_path -lfll_program -lfl_color -lfl_console -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_utf -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_print -lf_signal -lf_utf +build_libraries-individual -lfll_environment -lfll_error -lfll_execute -lfll_file -lfll_fss -lfll_path -lfll_program -lfl_color -lfl_console -lfl_control_group -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_utf -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_print -lf_signal -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_sources_library fake.c private-fake.c private-clean.c private-build.c private-make.c private-print.c private-skeleton.c diff --git a/level_3/firewall/c/firewall.h b/level_3/firewall/c/firewall.h index 2e193f9..bc442de 100644 --- a/level_3/firewall/c/firewall.h +++ b/level_3/firewall/c/firewall.h @@ -285,7 +285,7 @@ extern "C" { firewall_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamics_t_initialize, \ f_string_dynamics_t_initialize, \ diff --git a/level_3/firewall/data/build/dependencies b/level_3/firewall/data/build/dependencies index 10b680a..1d6921f 100644 --- a/level_3/firewall/data/build/dependencies +++ b/level_3/firewall/data/build/dependencies @@ -5,6 +5,7 @@ f_status f_memory f_string f_utf +f_account f_capability f_color f_console @@ -18,6 +19,7 @@ f_pipe f_print fl_color fl_console +fl_control_group fl_conversion fl_fss fl_status diff --git a/level_3/firewall/data/build/settings b/level_3/firewall/data/build/settings index 185fb93..1d082a6 100644 --- a/level_3/firewall/data/build/settings +++ b/level_3/firewall/data/build/settings @@ -19,7 +19,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -lcap -build_libraries-individual -lfll_error -lfll_execute -lfll_fss -lfll_program -lfl_color -lfl_console -lfl_conversion -lfl_environment -lfl_fss -lfl_status -lfl_string -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf +build_libraries-individual -lfll_error -lfll_execute -lfll_fss -lfll_program -lfl_color -lfl_console -lfl_control_group -lfl_conversion -lfl_environment -lfl_fss -lfl_status -lfl_string -lf_account -lf_capability -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_sources_library firewall.c private-firewall.c diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.h b/level_3/fss_basic_list_read/c/fss_basic_list_read.h index f8e2782..cb96f80 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.h @@ -191,7 +191,7 @@ extern "C" { fss_basic_list_read_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamic_t_initialize, \ f_fss_objects_t_initialize, \ diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.h b/level_3/fss_basic_list_write/c/fss_basic_list_write.h index 091c452..7693551 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.h +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.h @@ -145,7 +145,7 @@ extern "C" { fss_basic_list_write_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_static_t_initialize, \ f_color_context_t_initialize, \ diff --git a/level_3/fss_basic_read/c/fss_basic_read.h b/level_3/fss_basic_read/c/fss_basic_read.h index e1df109..a5f8d36 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -191,7 +191,7 @@ extern "C" { fss_basic_read_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamic_t_initialize, \ f_fss_objects_t_initialize, \ diff --git a/level_3/fss_basic_write/c/fss_basic_write.h b/level_3/fss_basic_write/c/fss_basic_write.h index 086d6ff..1f32f26 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.h +++ b/level_3/fss_basic_write/c/fss_basic_write.h @@ -145,7 +145,7 @@ extern "C" { fss_basic_write_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_color_context_t_initialize, \ } diff --git a/level_3/fss_embedded_list_read/c/fss_embedded_list_read.h b/level_3/fss_embedded_list_read/c/fss_embedded_list_read.h index 1551fef..6970c46 100644 --- a/level_3/fss_embedded_list_read/c/fss_embedded_list_read.h +++ b/level_3/fss_embedded_list_read/c/fss_embedded_list_read.h @@ -190,7 +190,7 @@ extern "C" { fss_embedded_list_read_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamic_t_initialize, \ f_fss_nest_t_initialize, \ diff --git a/level_3/fss_embedded_list_write/c/fss_embedded_list_write.h b/level_3/fss_embedded_list_write/c/fss_embedded_list_write.h index 9e57388..3fbf1fc 100644 --- a/level_3/fss_embedded_list_write/c/fss_embedded_list_write.h +++ b/level_3/fss_embedded_list_write/c/fss_embedded_list_write.h @@ -146,7 +146,7 @@ extern "C" { fss_embedded_list_write_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_static_t_initialize, \ f_color_context_t_initialize, \ diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.h b/level_3/fss_extended_list_read/c/fss_extended_list_read.h index 79b2929..becc57d 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.h @@ -191,7 +191,7 @@ extern "C" { fss_extended_list_read_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamic_t_initialize, \ f_fss_objects_t_initialize, \ diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.h b/level_3/fss_extended_list_write/c/fss_extended_list_write.h index fc4151b..c75f3a0 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.h +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.h @@ -146,7 +146,7 @@ extern "C" { fss_extended_list_write_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_static_t_initialize, \ f_color_context_t_initialize, \ diff --git a/level_3/fss_extended_read/c/fss_extended_read.h b/level_3/fss_extended_read/c/fss_extended_read.h index c9bd1dd..261bac8 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.h +++ b/level_3/fss_extended_read/c/fss_extended_read.h @@ -191,7 +191,7 @@ extern "C" { fss_extended_read_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamic_t_initialize, \ f_fss_objects_t_initialize, \ diff --git a/level_3/fss_extended_write/c/fss_extended_write.h b/level_3/fss_extended_write/c/fss_extended_write.h index 9b94f5d..1f83dae 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.h +++ b/level_3/fss_extended_write/c/fss_extended_write.h @@ -145,7 +145,7 @@ extern "C" { fss_extended_write_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_static_t_initialize, \ f_color_context_t_initialize, \ diff --git a/level_3/fss_status_code/c/fss_status_code.h b/level_3/fss_status_code/c/fss_status_code.h index 20af567..7abe803 100644 --- a/level_3/fss_status_code/c/fss_status_code.h +++ b/level_3/fss_status_code/c/fss_status_code.h @@ -121,7 +121,7 @@ extern "C" { fss_status_code_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_color_context_t_initialize, \ } diff --git a/level_3/iki_read/c/iki_read.h b/level_3/iki_read/c/iki_read.h index 23c1a9e..f279233 100644 --- a/level_3/iki_read/c/iki_read.h +++ b/level_3/iki_read/c/iki_read.h @@ -257,7 +257,7 @@ extern "C" { iki_read_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ 0, \ 0, \ diff --git a/level_3/iki_write/c/iki_write.h b/level_3/iki_write/c/iki_write.h index 1bddce4..92ef6d5 100644 --- a/level_3/iki_write/c/iki_write.h +++ b/level_3/iki_write/c/iki_write.h @@ -136,7 +136,7 @@ extern "C" { iki_write_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_string_dynamic_t_initialize, \ f_color_context_t_initialize, \ diff --git a/level_3/init/c/init.h b/level_3/init/c/init.h index 84979cb..da14e42 100644 --- a/level_3/init/c/init.h +++ b/level_3/init/c/init.h @@ -260,7 +260,7 @@ extern "C" { { \ init_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ 0, \ f_signal_t_initialize, \ diff --git a/level_3/status_code/c/status_code.h b/level_3/status_code/c/status_code.h index ab12225..ccba53b 100644 --- a/level_3/status_code/c/status_code.h +++ b/level_3/status_code/c/status_code.h @@ -120,7 +120,7 @@ extern "C" { status_code_console_parameter_t_initialize, \ f_string_lengths_t_initialize, \ F_false, \ - f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ + f_macro_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ f_color_context_t_initialize, \ } -- 1.8.3.1