Kevin Day [Sun, 24 Oct 2021 03:42:34 +0000 (22:42 -0500)]
Bugfix: Require is not properly triggering failure on error.
Get and handle the status code of controller_rule_wait_all().
Fix cases where "status" is being used where "status_lock" is better suited.
Remove unnecessary double assignment of status error.
In this case, only when F_lock is returned should the status be set.
This may need to be revisited and have the called function also set error on F_lock rather than handling here.
For asynchronous functions controller_rule_wait_all() is not properly handling the error.
This is happening because "required" is being incorrectly used.
For this function "required" is design to only wait for all required processes only and not limit the required validation.
Removing this fixing the problem so that when an asynchronous process that is required fails, the failure is propagated to the waiting process.
Add "require" in the htop example as a place for testing.
Add additional comments for clarifications and cleanup existing comments.
Kevin Day [Sat, 23 Oct 2021 21:45:55 +0000 (16:45 -0500)]
Update: Implement "session new" and "session same", improve documentation, update simulate and validate display.
The controller and init programs now support customizing their session as new or session as same state.
A setting global to the entry and exit files is defined as "session new" and "session same".
A setting specific to every rule item is appended to the "with" as either "session_new" or "session_same".
Update the documentation with these changes.
I noticed the documentation could use a little cleanup.
When passing both simulate and validate parameters, the entries and exits (with all related parts) are displayed.
The ordering can be more alphabetic.
It will not be fully alphabetic because there still exists logic that supersedes this, such as:
- "id", "name", and "type" values generally go first regardless of alphabetic ordering (and in that order).
- The simple data is displayed first (ones not using '{' and '}' to display), which are within themselves alphabetic.
- The complex data is displayed last, which are within themselves alphabetic.
- Within the complex data, the "item"s are displayed last.
Kevin Day [Sat, 23 Oct 2021 16:10:30 +0000 (11:10 -0500)]
Update: Improve terminal support in execute functions.
The init program calling bash results in "not a tty" error:
- "bash: cannot set terminal process group (-1): Not a tty"
- "bash: no job control in this shell"
This exposed me to the Process Group.
I have learned that I may need to set the Controlling Terminal in this case.
To that end, I have introduced FL_execute_parameter_option_session_d for setting this up.
I have also added an initial setup for FL_execute_parameter_option_terminal_d, but more investigation and research needs to be done.
I've added some basic execute terminal codes that I may or may not need.
I would rather have them now and remove them now rather than not have them and have to add them later.
The controller program needs to utilize this, at least when running as "init".
However, I believe that I should pass control over this to the user as new settings, such as "session new" and "session same".
Provide example to utilize "setsid" program for doing this same thing when directly calling bash.
Kevin Day [Thu, 21 Oct 2021 03:46:53 +0000 (22:46 -0500)]
Regression: Example bzip fakefile fails.
Empty strings end up getting passed to the programs, such as gcc.
The program gcc will throw an error claiming it cannot find file (displaying an empty sting for the filename).
This empty string doesn't show up in verbose, so the whole reason for failure is confusing because nothing is being displayed.
Fix this by not appending empty strings to the arguments.
At some point I added additional checks when loading the build settings file.
Because the fake make process uses the same function, it ends up failing because unrequired settings are now required.
Add a new variable "checks" to designate to perform these requirement checks or not.
The fake make process will then be setup to not perform these requirement checks.
In a recent commit, I added support for indexer_arguments.
It turns out I did more than necessary because this will already get loaded via the build settings loading code.
Remove the extra unnecessary processing of the indexer_arguments setting as it is already being processed later on.
The "compiler" and "indexer" should also be looked into.
Cleanup a print function.
Add a missing newline print at the end of the "print" operation.
Update the example fakefiles.
Add missing settings to the example build settings.
Kevin Day [Thu, 21 Oct 2021 00:41:31 +0000 (19:41 -0500)]
Update: Add support for indexer_arguments, update documentation, and fix printing bugs.
This is a step towards removing hardcoded defaults that I had initially added just to save time.
The indexer now has an indexer_arguments that will expect the arguments, such as "rcs".
Update the documentation, documenting this behavior, fix problems in the documentation, and do some cleanup of the documentation.
There are some places where "linker" is still used.
Replace this usage with "indexer".
Fix some cases with printing mistakes.
These mistakes are likely regressions resulting from the mass refactor to the fl_print_format() and fll_print_format().
I've noticed that there are some problems with the settings in the fakefile.
The custom settings, such as "compiler", "indexer", etc.., are being overwritten by the build settings.
It may also be a good idea to provide another iki parameter to expose some of these settings.
"flags_all" is now "flags".
"defines_all" is now "defines".
These are needed for the adding settings specific to shared or static state.
The "headers" related ones are added in case custom headers include static or shared specific code that should only be installed when using static or shared.
Note that the "headers" is for installation and is not needed in any way for compilation.
Other non-compilation related settings are not to have the "_shared" or "_static" added.
Kevin Day [Mon, 18 Oct 2021 02:04:56 +0000 (21:04 -0500)]
Refactor: Use the newer _s and _d define strategy.
This new strategy allows for the "const char *"s to be more directly the same as the "#define"s.
For example, "F_console_standard_short_dark_s" is the "#define" and "f_console_standard_short_dark_s" is the "const char *".
The use of uppercase is tolerated here as an exceptional case because F, FL, and FLL are sufficiently short enough to not be an eyesore.
No changes are made to exist "macro_*".
I will contemplate changing the "macro_XXX" to instead be "XXX_m" to match the "XXX_s" and "XXX_d" notations.
As an additional exception case, the length "#defines" that are directly coupled to a string, are of the fom "XXX_s_length" rather than "XXX_d".
This directly identifies that these only exist within direct relationship to the string "#define".
The "#define" will now have uppercase in the level 0, 1, and 2 projects.
Level 3, being programs, only conditionally follow to avoid using too many uppercase characters (ie: fss_basic_list_read_xxx vs FSS_BASIC_LIST_READ_xxx).
Kevin Day [Sun, 17 Oct 2021 03:43:57 +0000 (22:43 -0500)]
Refactor: Convert old f_file_t output strategy to the newer fl_print_t output strategy.
The "f_file_t output" should now be "fl_print_t output".
The output verbosity can now be used rather than the error verbosity for output verbosity.
This makes the code more readable and consistent.
The default fl_print_t_initialize is for normal output so also convert the error output initialization to use macro_fl_print_t_initialize_error().
Kevin Day [Sat, 16 Oct 2021 02:32:09 +0000 (21:32 -0500)]
Refactor: fll_error_print_t is now fl_print_t.
After using fll_error_print_t for a while now, I find that it is in practice superior to the regular print approach (such as with "f_file_t output;").
This made coding far easier than I imagined.
This refactor changes renames this from an error purpose print to a generic all-purpose print.
The existing "f_file_t output;" designs are not changed with this factor and will be changed in a later commit.
This refactor allows this to be moved from a level 2 project to a level 1 project.
In following with my completeness principle, I have added a "suffix" to compliment the "prefix".
I also added the "set" as a pointer to make it optional and to also not take up as much resources the full object rather than a pointer.
Having used fll_error_print_t for some time, I have found that I occasionally needed more than just the "context" and "notable".
While working on this, I realized I could improve my practice of handling "static" strings (such as fll_error_print_debug_s).
The practice is now to have the defines more closely match the names, but begin with the F_, FL_, etc.. in the same way that status codes are used.
This then allows:
| old | new |
----------------------------------------------
| fll_error_print_debug_s | fl_print_debug_s | <--- variable.
| fll_error_print_debug | FL_print_debug_s | <--- define/macro.
A future commit will convert all existing code that follows the old way.
Kevin Day [Fri, 15 Oct 2021 01:58:38 +0000 (20:58 -0500)]
Update: Execute changes and controller program changes.
Tweak some of the execute status codes.
I confused the errno parameters for what I was using F_execute_off for.
Change F_execute_off to F_execute_bad to more accurately reflect what the error code represents.
Add additional execute status codes.
Provide a F_format and F_format_not status codes.
Pass through non-negative, non-zero, exec return codes.
For negative return codes that is not -1, set the execute error code to F_execute_failure.
Improve error printing in controller program on child process failure.
Start to cleanup print functions.
There already is data being passed via the f_process_t, use those to better reduce the number of parameters passed to relevant functions.
There is much more work in this regards to do, but that is to be done at another time.
The controller program threads should exit with child code only if the child code is non-zero.
When the child code is zero, then the normal (and preferred) thread exit is allowed to perform.
Kevin Day [Wed, 13 Oct 2021 23:21:44 +0000 (18:21 -0500)]
Update: Implement "rerun" and properly get failed execute status codes.
Provide "rerun" support feature.
I discovered some problems with the execute functions after testing the "rerun" feature.
Specifically, when a child exits, the exit code is not properly propogating to the caller.
This makes it impossible to detect a failed execution.
It turns out that I need to call exit() with the appropriate failed code (which is only 8-bits).
The pthread_exit() is documented as always exit() with a value of 0.
This makes it impossible to communicate the failed state to the parent via an exit return code.
I am forced to call exit() here.
To do this, several significant changes are required.
Implement F_execute_codes enum and related functions to handle the 8-bit large status codes.
The limited set of codes are focused on possible failure states from the execute functions.
Functions to convert to and from regular status codes and these special limited execute status codes are now provided.
A union called f_execute_result_t is now provided as a way for the execute functions to return a pid_t for the parent process and an int for the child process.
The int in this case is intended to hold the special execute status codes.
An int is used rather than a more appropriate uint8_t because the standard POSIX functions use int.
Additional normal status codes F_too_large and F_too_small are now provided as generic too large and too small statuses.
Exit calls now directly use the execute status codes when calling exit().
The controller program child process now returns the exit status code either at the end of the appropraite threads or at the end of the main().
A new micro time conversion function is provided so that the deprecated usleep() can be avoided.
I may end up rewriting this to perform the sleep as well rather than just return a timespec.
Yet another htop rule is provided for testing "rerun".
Kevin Day [Mon, 11 Oct 2021 02:47:29 +0000 (21:47 -0500)]
Progress: Begin implementing re-run, fixing related problems.
To properly operate as an init (and improve the controller execution functionality), programs and services need to re-run after exiting.
A good example of this is the agetty program, which should re-run on both success and failure.
I attempted to take a simple approach with this design.
Example:
rerun start success delay 1000 reset
rerun start failure delay 5000 max 100
A "rerun" is applied to each Rule Action "start", "stop", "freeze", etc...
Each Rule Action has either a "success" or a "failure" state.
Each state may specify a delay, max, and a reset.
The delay provides how long to wait before re-running.
The max represents the maximum number of times to perform the re-run (setting to 0 results in no maximum).
The reset designates that the opposite return result (either success or failure) will have its counter reset.
That is, in the above example if failure is triggered 50 times and then success is triggered, the failure counter will be 0 again due to the reset on success.
Not specifying "rerun" will disable re-running.
This implements another array structure and the code is changed to perform the processing of the settings at an earlier point.
The previous design is a quick and simple but required additional looping before each execution.
The code now does the processing in the existing loops to avoid needing to loop later.
This requires adding new variables to the structure increasing memory footprint there but also decreases memory footprint in the actions array (and results in smaller actions array).
The "with" and "pid_file" are updated in this way as well.
The "user" and "group" have not yet been updated and need to be.
The configuration and validation of "rerun" is implemented, but the re-run functionality needs to be written.
The error checking, handling, and exiting will need to be reviewed after this work is complete.
Kevin Day [Fri, 8 Oct 2021 02:36:09 +0000 (21:36 -0500)]
Update: Implement timeout setting support, fix number handling, improve printing.
The timeout settings were never fully completed.
This implements the loading of the timeout settings but does not provide an usage of these settings.
Do some restructuring related to the timeout settings.
Fix detecting and processing of +/- as well as decimals.
Handle more errors returned by the number convert functions.
Cleanup the printing code.
Centralize some of the printing to functions, ideally reducing code size.
Add printing where it is not being done.
Fix debug vs verbose printing where debug isn't always including verbose printing messages.
Kevin Day [Thu, 7 Oct 2021 02:53:18 +0000 (21:53 -0500)]
Cleanup: The fl_conversion re-used functions should be within private files.
The practice is to maintain functional isolated even within a projects own sources.
The private sources are the method intended to re-use the functions within the same file.
Kevin Day [Thu, 7 Oct 2021 01:59:38 +0000 (20:59 -0500)]
Bugfix: The decimal '.' (0x2e) should not be considered a number.
The decimal may be a number character, but the conversion functions are for whole numbers only.
Consider the presence of decimals an error.
Use the F_number_decimal character to communicate this case.
Kevin Day [Sun, 3 Oct 2021 21:33:22 +0000 (16:33 -0500)]
Update: Support "pid" and "show" entry settings, and bug fixes.
The pid file may be created before the filesystem is ready and it may not be deleted when the system shuts down.
This then prevents the system from booting due to init failures.
Provide rule setting for fine tuning the control over how to handle the pid file.
Now, when running "as init", the pid entry setting by default designates to only utilize the pid file when "ready".
Previously, the pid file was always being checked for before the entry is even processed.
This prevented even waiting on the "ready" action because the entry is bailing out before even being processed.
There already is a "verbose" that prints the execution of programs.
This does not, however, start by default.
Provide a "show" setting for toggling this behavior to print some of the verbose messages when in "init" "show" mode.
Update the constant strings and related variables.
The ready behavior needs to be properly set.
As far as I can tell, the logic seemed odd, if not wrong.
Remove one of the ready checks and cleanup the ready check for the explicit ready action.
Update the prebuilt rules for terminals.
For now, there will be separate terminal files to execute.
There should be a variable substitution later on to not require multiple files.
For example, behavior is now:
"rule terminal one", found in rules/terminal/one.rule
"rule terminal two", found in rules/terminal/two.rule
This could better be something like:
"rule terminal tty/1", found in rules/terminal/tty.rule
"rule terminal tty/2", found in rules/terminal/tty.rule
Kevin Day [Sat, 2 Oct 2021 03:35:49 +0000 (22:35 -0500)]
Bugfix: Infinite loop on invalid entry file and related printing problems.
The loop is not properly handling the failure state and infinitely attempts to execute a rule that will always fail.
Make sure to copy over the rule failure code to the entry status.
Make sure to exit when rule execution fails when not simulating.
The related error printing bad logic in the conditionals.
Separate the simulate and related verbosity from the non-simulate and related verbosity.
Kevin Day [Wed, 29 Sep 2021 23:34:53 +0000 (18:34 -0500)]
Bugfix: Environment should only be reset when specified, even if empty.
The environment is accidentally always being reset.
This results in no environment in cases where this is unexpected.
This happens in simple things such as maintenance mode boot to bash, cannot find bash because there is no PATH environment variable.
Add example environment entry and rules for testing this.
Kevin Day [Wed, 29 Sep 2021 23:28:57 +0000 (18:28 -0500)]
Bugfix: Running as init is still not handling interruptable correctly.
I overlooked that the result was comparing against f_console_result_none rather than f_console_result_found.
This messed up my previous attempt to fix this.
Change the behavior and also explicitly assign the else case.
Kevin Day [Wed, 29 Sep 2021 00:37:51 +0000 (19:37 -0500)]
Update: Improve pid file handling logic.
I had forgotten that this is already optional.
Change the design to detect when pid file is explicitly disabled (passing an empty string to "--pid").
This avoids the need for the process_pid variable.
Kevin Day [Tue, 28 Sep 2021 03:14:48 +0000 (22:14 -0500)]
Update: Controller "init" is not always operating as expected and improve error printing.
The execute as init state needs to be run with the as init settings set.
The settings.mode needs to be set to run as a service.
(I am considering adding a new standard practice for programs to accept default objects that are passed to the appropriate function from any main().)
Cleanup the printing:
- Using "print" rather than "output" (because it is shorter and "print" is already being used in some places for this).
- Get rid of one nesting level to further simplify the code using return (and avoid an extra operation from the "!").
- When exiting due to an interrupt, do not print an error message.
Kevin Day [Tue, 28 Sep 2021 02:15:27 +0000 (21:15 -0500)]
Bugfix: Incorrectly setting interrupt failure during exit.
While processing the exit rules, the fll_extended_read is failing due to an interrupt that is not being sent.
This is the result of an incorrect value being assigned to the controller_state_interrupt_t.
Kevin Day [Sun, 26 Sep 2021 22:30:18 +0000 (17:30 -0500)]
Bugfix: Controller program print locking issues and fix delimits cache issue.
The locking as it is implemented is incomplete.
In many places, it unlocks twice.
There are some places where locking is not correctly being locked or unlocked, resulting in deadlocks.
Rewrite controller_print_unlock_flush(), and also add controller_print_lock().
I belive the problem is simply a result of many design changes in the locking and I just missed a number of places.
There are some printing where the parameters should have been printed but are not correctly printed.
Make sure controller_entry_action_parameters_print() is called in these places.
Make sure the cache delimits is cleared before calling fll_fss_extended_read().
Kevin Day [Sat, 25 Sep 2021 05:15:16 +0000 (00:15 -0500)]
Bugfix: Fix problems exposed due to testing and improve "Init".
As expected, I have found several regressions as a result of the mass conversion to fl_print_format() and similar.
There are several places where the wrong parameters or string replacements are used.
Improve the Controller to allow for "Init" to not attempt to mount the pid file (which allows Init to also manage initial mounting and device creation without depending on the existence of the filesystem structure).
The Controllerr "Init" now treats an empty string for the --pid option as disabling the pid file creation.
Do not treat exiting as a result from interrupts as an exit error.
Kevin Day [Sat, 11 Sep 2021 03:44:15 +0000 (22:44 -0500)]
Feature: Enable config.h, config.c, and config.cpp support in package generation.
There is a common practice of having a config.h for local build time changes to be applied.
Provide a skeleton structure for this by default when building the FLL packages.
These files will be empty.
The user need only populate these files as needed.
This could be done manually, but doing this by default effectively documents the proof of concept with a working/functional example.
Kevin Day [Fri, 10 Sep 2021 03:10:18 +0000 (22:10 -0500)]
Feature: Controller Program should support uninterruptable and define default behavior.
After designing the Controller to support operating directly as "init", it later occurred to me that the default behavior of uninterruptable makes sense for "init" but not for "controller".
Change the behavior to default to interruptable for the "controller" program.
This change further implies that the program needs an opposite to the "--interuptable" parameter.
Implement the "--uninterruptable" parameter for this purpose.
I also noticed that there is already an "interrupted" variable but that code is dead.
Oops.
Resurrect this variable and use it for identifying for this updated interruptable behavior.
Kevin Day [Fri, 10 Sep 2021 01:47:48 +0000 (20:47 -0500)]
Feature: Allow controller program to operate directly as "init program" by default.
The controller program already supports operating as an "init" program.
The design is generic enough to do this and a parameter exists already to explicitly set paths.
When running as "init" under normally circumstances, parameters might not be passed to it.
This is a good argument to support operating natively as an "init" without requiring the init parameter.
The design of the FLL programs allows them to be used as a library.
Take advantage of this and rewrite some of the code to save the "init" related differences in the main.c file.
The main.c file is not shared in the library and is therefore a safe candidate for holding differences.
This results in two programs "controller" and "init" which use the same library.
A stripped binary size of these two programs is each ~23K.
The stripped library shared between them is ~235K.
Having both programs on the system therefore only costs and additional ~23k.
To make this easy, provide an "as_init" mode that can be added to compile in this mode.
A compilation as "controller" might look like:
- "fake clean build -m monolithic"
A compilation as "init" might look like:
- "fake clean build -m monolithic -m as_init"
In both cases the program is built as "controller" under "build/programs/shared/controller".
When compiling "as_init", just rename this program when installing, such as:
- "cp -v build/programs/shared/controller /sbin/init".
The libraries and headers need only be installed once between the two programs.
This situation is a great example of the design principles of this project in use and working well.
Kevin Day [Tue, 7 Sep 2021 02:55:39 +0000 (21:55 -0500)]
Feature: Add support for -R/--raw parameters in FSS read programs.
The -R/--raw parameters designate that the quotes and the escapes should be preserved.
This allows for cleaning up a file and only pulling out valid FSS format and then provide that FSS in its originally escaped and quoted forms.
This further allows for maintaining quotes and escapes on Objects or Content individually.
When the static/dynamic string has used = 0 or the range.start > range.stop, then the string (or range) is empty.
The private function isn't aware of this and simply attempts to access the invalid ranges.
This will result in an invalid read.
Kevin Day [Sun, 5 Sep 2021 21:32:56 +0000 (16:32 -0500)]
Bugfix: FSS Basic and Extended List Read -a -n -l parameter fails to work as expected.
When -a, -n, and -l are used at the same time, the line position ends up being the wrong position within the file.
The -l (--line) should be relative to the --at index relative to the --name given.
This turned out to be a simple mistake where the wrong variable was being passed.
Kevin Day [Sun, 5 Sep 2021 20:49:06 +0000 (15:49 -0500)]
Bugfix: iki_read never implemented --at.
The --at parameter appears to have never been implemented or the implementation was somehow lost.
It should be possible to have the --total with the --at, however odd it may be.
The --whole, however, doesn't seem like it would be a good idea to allow supporting the --at paramter.
Add the "--" characters when displaying the error via fll_error_parameter_integer_print().
Kevin Day [Sat, 4 Sep 2021 05:03:18 +0000 (00:03 -0500)]
Security: Finish implementing string and convert changes.
The observation that some filesystems may have control characters in their names revealed a security issue in the design of this project.
There is no provided way to easily handle control characters or invalid UTF-8 sequences.
I have long been thinking about writing my own printf()/fprintf() functions but have not been willing to go that far.
With the discovery of this security issue, I finally decided to do so.
This then allows me to get rid of the rather messy f_color_print() and similar functions.
The color support and special FLL types, such as f_static_string_t, are now supported.
Due to the size of this change as well as my available time, I have broken up this process over several "Progress" commits.
This implementation is not complete.
I want to implement floating and double support, but I am not about to spend the research needed to properly handle floating and double digit processing logic.
While being similar, there are several differences between the fl_print_format() and fll_print_format() functions with the fprintf() functions.
Most notable of these is the the fl_print_format(), does not lock the file stream and fll_print_format() is a wrapper to fl_print_format() that does lock the file stream.
The format characters are significantly different, see the function documentation.
There are also improvements that need to be made.
Most notable is the digit to string conversion in which the algorithm I chose is a simple algorithm.
While the performance is acceptable for the time being, the performance can be greatly improved upon.
I need to spend time researching in order to improve this.
All of the programs (level 3) have been converted to use this and all of the many of the old ways of printing have been entirely removed.
I used safe printing where the string needs to be safely printing where I was able to identify such cases.
However, given the size of the refactoring, not to mention the work being spread out between days and weeks, I have concerns that I did not get all of the places that should be using safe printing.
Kevin Day [Thu, 2 Sep 2021 03:33:28 +0000 (22:33 -0500)]
Bugfix: Console parameter processing should handle unknown parameters with -/+ as regular parameters.
If the parameters are not found, then they should be added to the "remaining" set.
This allows unknown parameters to be used as regular parameters.
This is easily seen when using status_code or fss_status_code and attempting to pass a negative number, such as -200.
While -200 should be an out of range error for these programs, it is instead silently ignored.
Given that there is no reserved parameter with -200, then the -200 can be used normally.
There should also be a way to explicitly designate that all remaining parameters are processed as "remaining".
Add a comment by this.
There may also need to be a way to escape these parameters as an alternative.
Such changes are left to another time.
Kevin Day [Sat, 21 Aug 2021 05:21:48 +0000 (00:21 -0500)]
Progress: Continue string and convert changes, fixing bugs.
Convert the fake program.
Move the "%n" to "%in" to be consistent with how "%un" is used.
Change print string safely to ignore NULL rather than print the NULL character symbol.
This is done to be consistent with existing FLL design.
I realized printing the symbol is a problem when I test the fake build verbose setting.
Kevin Day [Tue, 17 Aug 2021 02:43:00 +0000 (21:43 -0500)]
Progress: Continue string and convert changes, fixing bugs.
The f_conversion_character_* functions should accept uint8_t instead of f_number_unsigned_t.
Implement the "/" character to designate the a partial range.
The "*_except*" string processing functions must accept an offset.
I was really hoping to avoid adding additional parameters but then I realized that I have to have a start offset.
The "except" positions and ranges are relative to the actual start and not the offset start.
The previous behavior of applying an offset to the string before passing results in the entire except positions and ranges to be invalid for any offset greater than 0.
Have F_eos (with error bit set) returned for when end of string is reached while calling fl_print_string_convert().
Rewrite the static/dynamic string argument printing logic.
Update private_fl_print_convert_number() to use bitwise operations rather than comparisons.
Convert the controller program.
Add missing "controller_string_value" and related to controller program.
Kevin Day [Sun, 8 Aug 2021 03:57:03 +0000 (22:57 -0500)]
Progress: Continue string and convert changes, fixing bugs.
Update all relevant dependencies.
Convert the error projects.
Convert control program.
Begin converting controller program.
I really wanted to get rid of those pesky mutex locks.
With the addition of explicit calls to flockfile() and funlockfile() this felt like a possibility.
Unfortunately, I still need to protect both stdout and stderr from both writing to the same destination (which is common for normal consoles).
Kevin Day [Sat, 7 Aug 2021 04:48:55 +0000 (23:48 -0500)]
Security: NULL dereferences discovered by GCC's -fanalyzer.
The socket bind is both missing the parameter check and is passing '&' when the variable is already a pointer.
The f_utf_character_to_char() is a mess.
Not sure what I was trying to do, but it is clearly wrong.
Redesign it to be more correct but I should revisit this for a more thorough review.
There are endianess situations that also need resolved so I added an @todo.
Kevin Day [Fri, 6 Aug 2021 03:45:17 +0000 (22:45 -0500)]
Progress: Continue string and convert changes, fixing bugs.
Document that the conversion operations are not ideal performance-wise.
Switch from fputc() to fwrite_unlocked() for the conversion print functions.
Use more bitwise operations rather than comparisons.
Explicitly handle binary print mode as it is easy to optimize.
(The binary optimization still uses much of the existing strategy and so likely can still be further optimized.)
Use correct digits for binary print in byte_dump.
Update the API documentation as it has fallen behind.
Preemptively update some of the API documentation where fputc/fputc_unlocked has not yet been fully updated to fwrite_unlocked.
Kevin Day [Wed, 4 Aug 2021 03:36:34 +0000 (22:36 -0500)]
Progress: Continue string and convert changes, fixing bugs.
Fix some bitwise operation comparison mistakes.
I used the wrong ASCII reference for the '@' and possibly others.
This broke octal representation.
This improves handling of Unicode characters in the safely print functions.
It seems there are Control characters with widths greater than one.
This complicates the code but what must be done, must be done.
Begin adding back some of the color print functions as f_print_color() etc...
There are still more to create.
Kevin Day [Sun, 1 Aug 2021 04:24:53 +0000 (23:24 -0500)]
Progress: Continue print development.
I've noticed that the performance can be quite poor in the custom fprintf functions.
Investigating this seems to be for several reasons:
1) No serious optimization developed into the logic as of yet.
2) The libc functions have serious optimization.
3) GCC/Clang are not properly identifying the register for unoptimized compilation.
4) I believe the libc functions are also parsing the data in a loop.
Some very basic optimizations are implemented:
1) Utilize "-O2" in every config by default to encourage the compiler to properly detect and set register (huge performance gained).
2) Use libc functions like strnlen() and fwrite() more often (more work to do in this regard).
3) Use grouping in the if..then.. logic to reduce the number of comparisons.
Fix bug where the number '11' is not being converted due to a typo.
Fix bug where an uppercase 'E' is printed when it should be a lower case 'e'.
There is no "end of enquiry".
Replace "end of enquiry" with "enquiry" because there is no "end of enquiry".
Organize print sequences and add (and utilize) a control sequence character map to avoid multiple if..then.. logic.
Re-organize the format flags, changing some entirely.
I decided not to so closely follow fprintf() functions and instead make things a little more consistent.
For example, "ul" and "ull" exist but the signed opposite is "l" and "ll".
This could instead be "ul" and "ull" as unsigned version of "il" and "ill".
Most of the FLL project is explicit about byte sizes, and so do the same with the format flags.
There is still a lot more work to do, but this is starting to stabilize a little.
Kevin Day [Fri, 30 Jul 2021 03:36:13 +0000 (22:36 -0500)]
Progress: continue string and convert changes, fixing bugs.
The byte comparison should be against 0xf and not 0x7.
As a result some numbers, such as 8, were being turned into 0.
The private convert function wasn't correctly converted when it was restructured.
Wrong parameters were used and the digits were being incorrectly set when the number is 0.
Looks like I needed a double pointer and not a single pointer.
I may redesign this to not depend on a double pointer.
The design will be to change the behavior to operate more like fprintf() in that a number of bytes printed is returned.
This would put the return type in a non-standard (non FLL standards that is) but acceptable state.
The byte_dump program had the parameters placed in the wrong location.
Another consideration is that I might implement f_print_color() (which would operate similar to the now removed f_color_print()).
This would only be for a single color for simplicity purpose and would only accept a single color set after the string.
Such as:
f_print_color("My name is %S.", main.context.set.title, main.output.stream, name);
Which is cleaner than:
f_print_string("%[My name is %S.%]", main.output.stream, main.context.set.title, name, main.context.set.title);
This is likely to cover a common case and so I believe is an acceptable compliment to f_print_string().
Kevin Day [Thu, 29 Jul 2021 03:17:12 +0000 (22:17 -0500)]
Progress: Continue working on print changes.
This begins replacing f_color code.
The byte_dump is migrated and has exposed bugs in the number processing.
For now, the number processing has been disabled solely for the purposes of this commit.
I will have to review and rethink the logic with the precision/width and number handling in printf.
Kevin Day [Wed, 28 Jul 2021 03:15:41 +0000 (22:15 -0500)]
Progress: Continue work on printing.
Use ";" and ":" for ignore_index and ignore_range.
I intend to reserve "<", ">", "(", ")", "{", and "}" for context related matters, which currently is only color context.
The handling of UTF-8 character codes with ignore indexes and ranges needs to be carefully considered and documented.
Print safely functions will need to convert, but what if the bits are being ignored?
Print raw functions should print as-is, even if invalid.
Print normally functions should validate and return error.
For now I just added some comments.
Oops! I include space as a "control" character.
I started to convert byte_dump printing as a way of testing the current state of the code.
I intend to slowly convert each level 3 project one at a time and test for problems.
This quickly convinced me to not follow the fprintf() standards practice and I moved the FILE * after the string rather than before.
Finish the trim functions.
This is done very quickly so I am confident that there is some logic bug somewhere.
This is just another reason for me to implement testing support.
There are several utf_character trim functions in fl_print.
Remove these for now.
The print is getting big and I believe that I now need an fl_utf_print and an fll_utf_print just like is done with how fl_string has fl_utf_string.
I want to get all of the bugs out of the print functions before I move to working on the utf_print functions.
This will likely get addressed during a unicode development pass.
This converts some of the fll_program print functions.
Looking at the color print functions, I now plan on merging a lot of the color printing functionality into the print functions.
Specifically, the fl_print_string() and related should support color context printing.
This will allow me to simplify some of the code.
The idea so far is that I can use "[" and "]" to accept an "f_color_set_t" and the "[" represents the "before" pointer and the "]" represents the "after" pointer.
For example the following:
fl_print_string(" %q%s%q%c", output.stream, *context.set.title.before, name, *context.set.title.after, f_string_eol_s[0]);
would be changed to:
fl_print_string(" %[%s%]%c", output.stream, context.set.title, name, context.set.title, f_string_eol_s[0]);
Kevin Day [Mon, 26 Jul 2021 03:02:20 +0000 (22:02 -0500)]
Progress: Redesign printing, redesign conversions, and some cleanup.
The print functions have been redesigned (work is incomplete as of this commit):
- Use unlocked printing where possible for all low level functions (like f_print()).
- Provide locked versions of all f_print* and fl_print* functions in newly added fll_print project.
- Redesign output variable to be at the end to be consistent with FLL practices (with an exception).
- Implement fprintf() alternative (very much incomplete, see below) and use a parameter structure to match fprintf() as an exception to the FLL practice mentioned above.
- Add *_raw() and *_safely() functions (see notes below).
The conversions are redesigned to better accommodate more flexibility as well as the newly added fprintf() alternatives (fl_print_string(), etc..).
- Provide a structure for more fine tuned control over convert process.
- Allow for literal designated of base 10 rather than making it solely the default base.
- Use bitwise operations and range comparisons more rather than switches and if then blocks for conversions.
There are some private headers being exposed to the installation (private headers should not be specified in the build_sources_headers build settings).
This commit all started with the observation that filenames could be created using control codes.
I tested using the backspace control code with the byte_dump program and found that it does perform backspace.
I consider this a security issue as I consider this undefined behavior.
To resolve this, I decided that I needed a "print safely" set of print functions.
After some consideration, I decided that providing my own fprintf() alternative is the way to go and has several advantages.
- Allow moving print locking to higher levels to avoid thread problems where multiple fprintf() like functions are called that should not be allowed for something else to print between them.
- The unlocked print functions also allow for better performance under the assumption or expectation allows for better control of the programmer to properly utilize this.
- Allow for having an unlocked fprintf() function.
- Still allow for locked versions of all unlocked print functions.
- Allow for passing FLL f_string_static_t, f_string_dynamic_t, and similar to the fprintf() alternative (which hopefully will make the code a lot cleaner and better maintainable).
- Allow for custom print options to "print safely".
- Allow for custom print options to "print rawly" (that is, allow printing NULL character and any control character as-is).
Working on this led to doing a rewrite of the conversion functions (which is needed anyway).
This also required major changes to the print functions and as per my completeness principle also requires a lot more functions to be implemented.
All of this resulted in a huge set of changes.
So big, that I am afraid of mistakes.
No, I expect there to be mistakes.
At this point, I spent enough time so I put the code in a state that compiles correctly and am saving as-is.
There are several @todos present and there are also a large number of incomplete areas of code.
Of particular note is the fprintf() compatibility.
I tried to stay as close to the fprintf() syntax as possible but I found that it is better to deviate in certain areas.
I do not plan on implementing the "type conversion" support.
I do plan on implementing the float/double support, but do to the additional complexity and my priorities, this functionality is being held off for a much later time.
I will get to documenting the fprintf() alternatives later on.
The fprintf() alternatives are being called fl_print_string() and fll_print_string() (including variations with different suffixes).
This is done to distinguish these between the normal f_print() and fll_print() type of functions.
Kevin Day [Fri, 9 Jul 2021 01:27:10 +0000 (20:27 -0500)]
Update: Add cygwin rough documentation.
I had access to a Windows box and was curious to see if I could compile my project on Windows.
To my surprise, with Cygwin and only a minor set of changes, the byte_dump program compiled and worked flawlessly.
Kevin Day [Fri, 9 Jul 2021 00:45:20 +0000 (19:45 -0500)]
Feature: Add support for specifying nano version numbers in FLL programs.
The programs display the version number and so it may be helpful for certain situations to specify nano version numbers for this project.
One such use case is if I were to release a development package for my own testing, I would like it to communicate the development status.
With this change I can now do this in one of two ways (to achieve something like "0.5.4-dev"):
1) Specify the custom nano on the command line like:
# fake clean build -d "-Dbyte_dump_nano_version_prefix=\"-\"" -d "-Dbyte_dump_nano_version=\"dev\""
2) Specify the custom nano verson in the data/buildsettings file, prepending the defines_all Object's Content like:
defines_all -Dbyte_dump_nano_version_prefix="-" -Dbyte_dump_nano_version="dev"
Kevin Day [Sat, 26 Jun 2021 03:59:54 +0000 (22:59 -0500)]
Feature: Featureless Make must support both version_target and version_file.
This separates version_target into version_target and version_file.
Previously, they were one in the same and the recent design change of version_target exposed a problem with this.
Libraries are traditionally linked (as in dynamic linker and not as in the filesystem "ln") to the major version number (such as: "-Wl,-soname,libfake.so.0") and have a file path set to the micro version (such as: libfake.so.0.5.4).
When the version_target was set to "micro", this instead results in "-Wl,-soname,libfake.so.0.5.4" and "libfake.so.0.5.4".
By breaking this up, the linker and the file can be setup appropriately.
The problem here is that they are both related to linking but in two different contexts:
1) Dynamic Linker (_wl,-soname,...).
2) System Linker (ln -vs a b).
To disambiguate these, the version_target is now used to refer to the Dynamic Linker and the version_file is used with the file name in which the system linker is used to link files against.
The Featureless Linux Library used Major.Minor.Micro such that Major.Minor could represent stable versions (for even Minor numbers).
Set this new setting to have version_target set to "minor" instead of the traditional "major" in the appropriate settings files.
When not specified in the build settings file, the defaults must always be provided which are:
1) version_target = "major"
2) version_file = "micro"
This aligns the default behavior to align with traditional practices while manually setting the build settings for all FLL projects to use different settings.
The bootstrap.sh script has been updated to be consistent with this.
The bootstrap.sh has also been updated to include the version prefixes.
Kevin Day [Fri, 25 Jun 2021 02:10:29 +0000 (21:10 -0500)]
Update: Redesign Featureless Make's -d/--define to append instead of overwrite.
The built in defines can be large and complex.
The defines passed through the program arguments should be for exceptional or situational purposes.
By using append instead of overwrite, the -d/--define better operates as an exceptional or situational process.
Kevin Day [Fri, 25 Jun 2021 00:35:30 +0000 (19:35 -0500)]
Update: Implement *_except_in* print functions, remove redundant UTF types, and have FSS read functions utilize *_except_in*.
When I wrote the *print_except* and *print_trim_except* functions I was hoping to avoid having to pass both individual positions as well as ranges for the "except" list.
Looking at how the FSS read functions are, I now realize that I must implement these.
Implement these as seperate functions where reasonable and in other cases implement the *_except_in* with the *_except* functions.
I added some of the UTF string types for consistency and completeness.
After looking at this later on I now believe the cost of the extra maintenance and resources is not worth it.
(It might, however, be worth implementing these as a define or a typedef of the string types.)
Replace f_utf_string_range_t with f_string_range_t (and related), removing all related functions.
Remove f_utf_string_quantity_t (and related), removing all related functions.
With the *_except_in* functions implemented, the relevant FSS read functions can now use them and properly not print valid comments.
Kevin Day [Wed, 23 Jun 2021 03:43:57 +0000 (22:43 -0500)]
Update: Restructure enum non-alphabetically and detect empty version for a specified version target.
If version_target is set to something, then that something should not be empty.
Detect this requirement.
In the case of the major/minor/micro/nano versioning, having the enum match the major/minor/micro/nano order makes more sense than alphabetical.
This then allows for using the enum as a relative position when detecting if one of these is required to not be empty.
Kevin Day [Wed, 23 Jun 2021 02:57:47 +0000 (21:57 -0500)]
Bugfix: Properly build version string.
The previous commit didn't properly to this.
When a version prefix is provided, the resulting name overwrites the string with the nano version at the wrong location in the string.
Kevin Day [Wed, 9 Jun 2021 02:01:29 +0000 (21:01 -0500)]
Progress: Incorrect linkage, not handling default values well, add version_nano, add version prefixes, and out of date documentation.
The documentation has version_target described as the target to build but the C source for Featureless Make is using it for the link file name.
Change this behavior to be consistent with the documentation.
Update all build settings to now be set to micro to be consistent with this change.
The default values should only be assigned if the Object is not provided at all.
This allows for the value to be set to empty (aka NULL).
The version_major, version_minor, and version_micro all are currently required to be defined and if empty will be set to 0.
Some projects use four versions and others like to add things like "-dev" or "-rc1".
Provide a way to do this by adding a version_nano as well as adding version prefixes.
For each version there is now a version_X_prefix such as version_major now has version_major_prefix.
For all version prefixes, except version_major_prefix, the prefix will be in place of the '.' in the version name.
The major version is an exception case as there is no value by default.
For example "1.2.3" would have version_major = "1", version_minor_prefix = ".", version_minor = "2", version_micro_prefix = "." version_micro = "3".
The default version continues to be a version_target of micro, such as "1.2.3".
The build settings documentation is out of date and needed some corrections to be made.
There is still more work to do in adding the prefixes and making the bootstrap.sh script and the fake program more consistent with the version numbers.
I simply ran out of time.
Kevin Day [Mon, 31 May 2021 22:43:44 +0000 (17:43 -0500)]
Update: Redesign FSS Identify to be more consistent with FSS Read and FSS Write programs.
This is not strictly required, but I believe making it as closely consistent with how FSS Read and FSS Write operate makes a lot of sense.
The FSS Identify and FSS Read/Write programs operate differently and not everything can be the same.
Summary of Redesign:
- The "name" and "type" are now renamed to "Object" and "Content".
- The parameter "-n/--name" is now "-o/--object".
- The parameter "-t/--type" is now "-c/--content".
- The parameter "-T/--total" is now "-t/--total".
- Add new parameter "-n/--name" that accepts a name to filter by (This selects an Object just like it does in FSS Read/Write).
- Add additional documentation to the "-h/--help" parameter message.
- The "-t/--total" parameter should could across all files and not the individual files/pipe (this provides a single total).
Kevin Day [Mon, 31 May 2021 05:02:58 +0000 (00:02 -0500)]
Update: Attempt to avoid libc/POSIX character array length limitations.
Define f_string_t_length to handle the special case max length.
Make the f_utf_string_t also operate in the same way (even it it might avoid the problem by being a different type than char).
The f_utf_string_t is changed in this way for consistency reasons.
Kevin Day [Mon, 31 May 2021 04:07:18 +0000 (23:07 -0500)]
Bugfix: FLL/FSS Identifier problems.
The strtol() function is being incorrectly used.
Redesign the code to accomodate the particular nature of that function.
Instead of doing math, just create a special structure that is friendly for strtol() and read str
The status is being incorrectly checked against F_false when the check should be against F_true (oops!).
Make sure the id->used is correctly calculated.
The calculation is truncating the name because the i variable is incremented in a start/stop range and not in a buffer used (start/stop ranges are inclusive and a buffer.used more akin to exclusive).
I forgot to allocate the FLL Identifiers array.
There are some cases where found_fss is not and should be tested for.
Kevin Day [Sun, 30 May 2021 18:09:51 +0000 (13:09 -0500)]
Progress: FLL/FSS related changes, populate more ASCII characters.
It occurred to me that I should follow the same practices as the FSS process where I use range for the FLL/FSS Identifier processing.
Change the behavior to do so.
It also occurred to me that I should try to avoid processing both a dynamic string's used as well as the range.
The FLL/FSS Identifier code only accepts a string for this reason.
It will likely be a good idea to change the other FSS code to accept a f_string_t instead of a f_string_static_t.
Add the initial support for FSS header processing with support for multiple FLL/FSS Identifiers.
Add and use the FSS specific default memory allocators.
Complete more of the hardcoded ASCII strings.
Unless I missed something, all that is left now is to consider adding the extended ASCII.
Kevin Day [Sun, 30 May 2021 03:22:45 +0000 (22:22 -0500)]
Update: Additional FLL Identifier changes along with type fixes.
I didn't like manually specifying the id.name[X] for all 64 X when clearing the f_fll_id_t.
Instead, take a minimalistic approach and set id.name[0] to NULL.
This is not a complete clear, but it is simple for use in macros.
Document that memset() should be used for a more complete/correct clear.
I completely forgot to implement the array and array of arrays support as is standard practice now.
While doing this I then noticed that the other type arrays and array of arrays were not fully migrated to having functions rather than be pure macros.
This further exposed some bugs being hidden by the macros.
There were some resize (or similar) macros that were using the wrong macro to initialize.
When macros were changed to expand to a function, this exposed that the wrong types were being used and there is a likelihood of incorrect allocations or deallocations.
Things may have previously worked due to the sizes potentially being coincidentally identical.
There is also a bug where some macros expanded the *_increase_by() macro to a *_increase() function.
These should instead expand to an appropriate *_increase_by() function.
Kevin Day [Sat, 29 May 2021 23:12:21 +0000 (18:12 -0500)]
Revert: Partially revert unsigned to signed change in "Bugfix: Compilation/Portability problems exposed when building against musl-libc.".
There were problems with the console parameter size, so switching that to signed seems fine.
However, switching the more general standard approach from unsigned to signed is more dangerous.
Signed operations are much more fickle when overflowing or when using bitwise operations.
In fact, the C standards leave a lot of this behavior as undefined.
Much of the logic used in operating and manipulating array lengths (as counters or with bitwise operations such as << or >>) is affected by the previous change from signed to unsigned.
Avoid these signed problems by reverting this behavario.
The console parameter length will remain as a signed.
Kevin Day [Sat, 29 May 2021 23:00:02 +0000 (18:00 -0500)]
Feature: Provide and implement f_fll_id_t and fl_string_fll_identify().
The Featureless Settings Specification identifiers are a decent format.
Make a more generalized structure for processing these for the entire project and not just FSS.
Kevin Day [Sat, 29 May 2021 16:29:49 +0000 (11:29 -0500)]
Feature: Allow controller program to run as a non-init (and then do so by default).
The controller program is written more generally.
Take one step further and make the default to run generally.
Then provide the option to operate as an init program.
This frees up the controller program's default behavior to just be a "controller" rather than an "init controller".
Furthermore, provide options to change easily override the "init controller" paths at compile time without redefining all of the other defines in the "_di_controller_defines_" block.