From: Kevin Day <thekevinday@gmail.com>
Date: Sun, 17 May 2020 02:56:52 +0000 (-0500)
Subject: Update: numerous changes, most notably path and vfork to fork changes
X-Git-Tag: 0.5.0~253
X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=65c180baf81cae13ccb2af4b19e18eb4f38c4169;p=fll

Update: numerous changes, most notably path and vfork to fork changes

Replace vfork() calls with fork().
- I have determined that vfork() is not safe.
- When calling clearenv() inside a vfork() child process, the parent process' environment ends up getting cleared as well!
- The child can alter the parents memory according to manpages, so stop using vfork() entirely.

Add path processing functions and related defines.

Enable path processing to allow for execvpe()-like behavior can be implemented.
- The execvpe() function is not used because it is not POSIX.
- Manually process the PATH environment to determine what to execute, even when PATH enviornment gets cleared.

Some consistency improvements in defines, such as f_console_max_size to f_console_length_size.

Fix mistake in memcpy usage, dynamic strings use char * for their string so passing & is incorrect.

The f_file_exists() is using access().
- This is misleading and incorect.
- Use stat() to determine if file exists because it doesn't require access to the file (aside from directory access) to check existence.
- Add a new function f_file_access() as the old implementation of f_file_exists().

The fll_execute programs now support additional functions for clearing environment variables.
- This effectively sandboxes the environment variables before calling the program.
---

diff --git a/build/level_0/settings b/build/level_0/settings
index 1cd482d..5756b24 100644
--- a/build/level_0/settings
+++ b/build/level_0/settings
@@ -12,7 +12,7 @@ build_linker ar
 build_libraries -lc
 build_libraries_fll
 build_libraries_fll-level
-build_sources_library console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c memory.c pipe.c print.c utf.c private-utf.c
+build_sources_library console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c memory.c path.c pipe.c print.c utf.c private-utf.c
 build_sources_program
 build_sources_headers color.h console.h conversion.h directory.h environment.h file.h fss.h memory.h path_fll.h path_filesystem.h path.h pipe.h print.h serialized.h socket.h status.h string.h type.h type_array.h utf.h
 build_shared yes
diff --git a/build/monolithic/settings b/build/monolithic/settings
index 614c23b..ac2e5fc 100644
--- a/build/monolithic/settings
+++ b/build/monolithic/settings
@@ -11,7 +11,7 @@ build_compiler gcc
 build_linker ar
 build_libraries -lc
 build_libraries_fll
-build_sources_library 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/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/print.c level_1/serialized.c level_1/private-serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_2/directory.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
+build_sources_library 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/memory.c level_0/path.c level_0/pipe.c level_0/print.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/print.c level_1/serialized.c level_1/private-serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_2/directory.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
 build_sources_program
 build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/environment.h level_0/file.h level_0/fss.h level_0/memory.h level_0/path_fll.h level_0/path_filesystem.h level_0/path.h level_0/pipe.h level_0/print.h level_0/serialized.h level_0/socket.h level_0/status.h level_0/string.h level_0/type.h level_0/type_array.h level_0/utf.h level_1/color.h level_1/console.h level_1/file.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_status.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/print.h level_1/serialized.h level_1/socket.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/directory.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_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/program.h level_2/status.h
 build_sources_bash
diff --git a/level_0/f_console/c/console.c b/level_0/f_console/c/console.c
index a535802..5e27093 100644
--- a/level_0/f_console/c/console.c
+++ b/level_0/f_console/c/console.c
@@ -104,7 +104,7 @@ extern "C" {
 
       f_console_identify(arguments.argv[location], &result);
 
-      string_length = strnlen(arguments.argv[location], f_console_max_size);
+      string_length = strnlen(arguments.argv[location], f_console_length_size);
 
       // process the current parameter.
       if (result == f_console_short_enable || result == f_console_short_disable) {
diff --git a/level_0/f_console/c/console.h b/level_0/f_console/c/console.h
index 374e4de..f5b81d2 100644
--- a/level_0/f_console/c/console.h
+++ b/level_0/f_console/c/console.h
@@ -137,9 +137,9 @@ extern "C" {
 /**
  * The maximum size for a single parameter.
  */
-#ifndef _di_f_console_max_size_
-  #define f_console_max_size f_string_max_size
-#endif // _di_f_console_max_size_
+#ifndef _di_f_console_length_size_
+  #define f_console_length_size f_string_length_size
+#endif // _di_f_console_length_size_
 
 /**
  * Provide a default allocation step.
@@ -305,13 +305,13 @@ extern "C" {
  * Long parameters are processed as follows:
  * - Begin with either '--' or '++'.
  * - "Empty" parameters are allow, such that '--' or '++' are valid parameters.
- * - Are any length long so long as it is less than f_console_max_size.
+ * - Are any length long so long as it is less than f_console_length_size.
  * - May not be grouped and must be separated from any subsequent parameter, such as: "tar --extract --create --file".
  * - Additional parameters must immediately follow the parameter, such as "tar --extract --file file.tar.gz --create".
  *
  * Other parameters are processed as follows:
  * - Anything that does not begin with '-', '+', '--', or '++'.
- * - Are any length long so long as it is less than f_console_max_size.
+ * - Are any length long so long as it is less than f_console_length_size.
  * - May not be grouped and must be separated from any subsequent parameter, such as: "tar extract create file".
  * - Additional parameters must immediately follow the parameter, such as "tar extract file file.tar.gz create".
  *
diff --git a/level_0/f_environment/c/private-environment.c b/level_0/f_environment/c/private-environment.c
index 67bb510..de49359 100644
--- a/level_0/f_environment/c/private-environment.c
+++ b/level_0/f_environment/c/private-environment.c
@@ -30,7 +30,7 @@ extern "C" {
         if (f_status_is_error(status)) return status;
       }
 
-      memcpy(&value->string + value->used, result, value->used + size);
+      memcpy(value->string + value->used, result, value->used + size);
       value->used = size;
     }
 
diff --git a/level_0/f_file/c/file.c b/level_0/f_file/c/file.c
index 1a84d99..78f520b 100644
--- a/level_0/f_file/c/file.c
+++ b/level_0/f_file/c/file.c
@@ -14,6 +14,43 @@
 extern "C" {
 #endif
 
+#ifndef _di_f_file_access_
+  f_return_status f_file_access(const f_string path) {
+    #ifndef _di_level_0_parameter_checking_
+      if (path == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (access(path, F_OK)) {
+      if (errno == ENOENT) {
+        return f_false;
+      }
+
+      if (errno == ENAMETOOLONG || errno == EFAULT) {
+        return f_status_set_error(f_invalid_name);
+      }
+      else if (errno == ENOMEM) {
+        return f_status_set_error(f_out_of_memory);
+      }
+      else if (errno == EOVERFLOW) {
+        return f_status_set_error(f_number_overflow);
+      }
+      else if (errno == ENOTDIR) {
+        return f_status_set_error(f_invalid_directory);
+      }
+      else if (errno == EACCES) {
+        return f_status_set_error(f_access_denied);
+      }
+      else if (errno == ELOOP) {
+        return f_status_set_error(f_loop);
+      }
+
+      return f_status_set_error(f_false);
+    }
+
+    return f_true;
+  }
+#endif // _di_f_file_access_
+
 #ifndef _di_f_file_create_
   f_return_status f_file_create(f_string path, const mode_t mode, const bool exclusive) {
     int flags = O_CLOEXEC | O_CREAT | O_WRONLY;
@@ -103,13 +140,14 @@ extern "C" {
   }
 #endif // _di_f_file_close_
 
-#ifndef _di_f_file_exists_
-  f_return_status f_file_exists(const f_string path) {
+#ifndef _di_f_file_exists_at_
+  f_return_status f_file_exists_at(const int directory_file_descriptor, const f_string path, const int flags) {
     #ifndef _di_level_0_parameter_checking_
+      if (directory_file_descriptor == 0) return f_status_set_error(f_invalid_parameter);
       if (path == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (access(path, F_OK)) {
+    if (faccessat(directory_file_descriptor, path, F_OK, flags)) {
       if (errno == ENOENT) {
         return f_false;
       }
@@ -132,26 +170,41 @@ extern "C" {
       else if (errno == ELOOP) {
         return f_status_set_error(f_loop);
       }
+      else if (errno == EBADF) {
+        return f_status_set_error(f_invalid_descriptor);
+      }
+      else if (errno == EINVAL) {
+        return f_status_set_error(f_invalid_parameter);
+      }
 
       return f_status_set_error(f_false);
     }
 
     return f_true;
   }
-#endif // _di_f_file_exists_
+#endif // _di_f_file_exists_at_
 
-#ifndef _di_f_file_exists_at_
-  f_return_status f_file_exists_at(const int directory_file_descriptor, const f_string path, const int flags) {
+#ifndef _di_f_file_flush_
+  f_return_status f_file_flush(f_file *file) {
     #ifndef _di_level_0_parameter_checking_
-      if (directory_file_descriptor == 0) return f_status_set_error(f_invalid_parameter);
-      if (path == 0) return f_status_set_error(f_invalid_parameter);
+      if (file == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (faccessat(directory_file_descriptor, path, F_OK, flags)) {
-      if (errno == ENOENT) {
-        return f_false;
-      }
+    if (file->address == 0) return f_status_set_error(f_file_not_open);
 
+    if (fflush(file->address) == 0) return f_none;
+
+    return f_status_set_error(f_file_error_flush);
+  }
+#endif // _di_f_file_flush_
+
+#ifndef _di_f_file_exists_
+  f_return_status f_file_exists(const f_string path) {
+    struct stat file_stat;
+
+    memset(&file_stat, 0, sizeof(file_stat));
+
+    if (stat(path, &file_stat) < 0) {
       if (errno == ENAMETOOLONG || errno == EFAULT) {
         return f_status_set_error(f_invalid_name);
       }
@@ -164,39 +217,22 @@ extern "C" {
       else if (errno == ENOTDIR) {
         return f_status_set_error(f_invalid_directory);
       }
+      else if (errno == ENOENT) {
+        return f_false;
+      }
       else if (errno == EACCES) {
         return f_status_set_error(f_access_denied);
       }
       else if (errno == ELOOP) {
         return f_status_set_error(f_loop);
       }
-      else if (errno == EBADF) {
-        return f_status_set_error(f_invalid_descriptor);
-      }
-      else if (errno == EINVAL) {
-        return f_status_set_error(f_invalid_parameter);
-      }
 
-      return f_status_set_error(f_false);
+      return f_status_set_error(f_file_error_stat);
     }
 
     return f_true;
   }
-#endif // _di_f_file_exists_at_
-
-#ifndef _di_f_file_flush_
-  f_return_status f_file_flush(f_file *file) {
-    #ifndef _di_level_0_parameter_checking_
-      if (file == 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_0_parameter_checking_
-
-    if (file->address == 0) return f_status_set_error(f_file_not_open);
-
-    if (fflush(file->address) == 0) return f_none;
-
-    return f_status_set_error(f_file_error_flush);
-  }
-#endif // _di_f_file_flush_
+#endif // _di_f_file_exists_
 
 #ifndef _di_f_file_is_
   f_return_status f_file_is(const f_string path, const int type) {
diff --git a/level_0/f_file/c/file.h b/level_0/f_file/c/file.h
index f05e031..49e82f3 100644
--- a/level_0/f_file/c/file.h
+++ b/level_0/f_file/c/file.h
@@ -285,6 +285,30 @@ extern "C" {
 #endif // _di_f_macro_file_reset_position_
 
 /**
+ * Check if a file can be accessed.
+ *
+ * @param path
+ *   The path file name.
+ *
+ * @return
+ *   f_true if file exists.
+ *   f_false if file does not exist.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_name (with error bit) if the filename is too long.
+ *   f_out_of_memory (with error bit) if out of memory.
+ *   f_number_overflow (with error bit) on overflow error.
+ *   f_invalid_directory (with error bit) on invalid directory.
+ *   f_access_denied (with error bit) on access denied.
+ *   f_loop (with error bit) on loop error.
+ *   f_false (with error bit) on unknown/unhandled errors.
+ *
+ * @see access()
+ */
+#ifndef _di_f_file_access_
+  extern f_return_status f_file_access(const f_string path);
+#endif // _di_f_file_access_
+
+/**
  * Create a file based on the given path and file mode.
  *
  * The file will not be open after calling this.
@@ -347,28 +371,6 @@ extern "C" {
 #endif // _di_f_file_close_
 
 /**
- * Check if a file exists.
- *
- * @param path
- *   The path file name.
- *
- * @return
- *   f_true if file exists.
- *   f_false if file does not exist.
- *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_invalid_name (with error bit) if the filename is too long.
- *   f_out_of_memory (with error bit) if out of memory.
- *   f_number_overflow (with error bit) on overflow error.
- *   f_invalid_directory (with error bit) on invalid directory.
- *   f_access_denied (with error bit) on access denied.
- *   f_loop (with error bit) on loop error.
- *   f_false (with error bit) on unknown/unhandled errors.
- */
-#ifndef _di_f_file_exists_
-  extern f_return_status f_file_exists(const f_string path);
-#endif // _di_f_file_exists_
-
-/**
  * Check if a file exists at a given directory.
  *
  * @param directory_file_descriptor
@@ -415,8 +417,37 @@ extern "C" {
 #endif // _di_f_file_flush_
 
 /**
+ * Identify whether or not a file exists at the given path.
+ *
+ * This does not require access on the file itself.
+ * This only requires access via the parent directories in the path.
+ *
+ * @param path
+ *   The path file name.
+ *
+ * @return
+ *   t_true if path was found.
+ *   f_false if path was not found.
+ *   f_invalid_name (with error bit) if the name is somehow invalid.
+ *   f_out_of_memory (with error bit) if out of memory.
+ *   f_number_overflow (with error bit) on overflow error.
+ *   f_invalid_directory (with error bit) on invalid directory.
+ *   f_access_denied (with error bit) if access to the file was denied.
+ *   f_loop (with error bit) if a loop occurred.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see stat()
+ */
+#ifndef _di_f_file_exists_
+  extern f_return_status f_file_exists(const f_string path);
+#endif // _di_f_file_exists_
+
+/**
  * Identify whether or not a file exists at the given path and if that file is a specific type.
  *
+ * This does not require access on the file itself.
+ * This only requires access via the parent directories in the path.
+ *
  * @param path
  *   The path file name.
  * @param type
@@ -434,7 +465,7 @@ extern "C" {
  *   f_loop (with error bit) if a loop occurred.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *
- * @see fstat()
+ * @see stat()
  */
 #ifndef _di_f_file_is_
   extern f_return_status f_file_is(const f_string path, const int type);
diff --git a/level_0/f_path/c/path.c b/level_0/f_path/c/path.c
new file mode 100644
index 0000000..c5aae1c
--- /dev/null
+++ b/level_0/f_path/c/path.c
@@ -0,0 +1,244 @@
+#include <level_0/path.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_f_path_explode_
+  f_return_status f_path_explode(const f_string path, f_string_dynamics *paths) {
+    #ifndef _di_level_0_parameter_checking_
+      if (paths == 0) return f_status_set_error(f_invalid_parameter);
+      if (paths->used > paths->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    f_status status = f_none;
+    const f_string_length length = strnlen(path, PATH_MAX);
+
+    if (length == 0) {
+      // When PATH is "", this is actually a valid search path for CWD.
+      // Therefore append an equivalent representation of CWD (string used length is 0).
+      if (paths->used + 1 > paths->size) {
+        if (paths->size + f_memory_default_allocation_step > f_array_length_size) {
+          if (paths->size + 1 > f_array_length_size) {
+            return f_status_set_error(f_buffer_too_large);
+          }
+
+          f_macro_string_dynamics_resize(status, (*paths), paths->used + 1);
+          if (f_status_is_error(status)) return status;
+        }
+        else {
+          f_macro_string_dynamics_resize(status, (*paths), paths->used + f_memory_default_allocation_step);
+          if (f_status_is_error(status)) return status;
+        }
+      }
+
+      paths->array[paths->used].string = 0;
+      paths->array[paths->used].used = 0;
+      paths->array[paths->used].size = 0;
+      paths->used++;
+
+      return f_none;
+    }
+
+    f_string_length i = length;
+    f_string_length j = length;
+    f_string_length last = length;
+    f_string_length total = 0;
+
+    for (; i > 0; i--) {
+      j--;
+
+      if (j == 0 || path[j] == f_path_separator_variable[0]) {
+        if (paths->used + 1 > paths->size) {
+          if (paths->size + f_memory_default_allocation_step > f_array_length_size) {
+            if (paths->size + 1 > f_array_length_size) {
+              return f_status_set_error(f_buffer_too_large);
+            }
+
+            f_macro_string_dynamics_resize(status, (*paths), paths->used + 1);
+            if (f_status_is_error(status)) return status;
+          }
+          else {
+            f_macro_string_dynamics_resize(status, (*paths), paths->used + f_memory_default_allocation_step);
+            if (f_status_is_error(status)) return status;
+          }
+        }
+
+        f_string_dynamic part = f_string_dynamic_initialize;
+
+        if (path[j] == f_path_separator_variable[0]) {
+          total = last - i;
+
+          if (total > 0) {
+            if (path[j + total] == f_path_separator[0]) {
+              f_macro_string_dynamic_new(status, part, total);
+              if (f_status_is_error(status)) return status;
+
+              part.used = total;
+            }
+            else {
+              f_macro_string_dynamic_new(status, part, total + 1);
+              if (f_status_is_error(status)) return status;
+
+              part.string[total] = f_path_separator[0];
+              part.used = total + 1;
+            }
+
+            memcpy(part.string, path + i, total);
+          }
+
+          last = j;
+        }
+        else if (j == 0) {
+          // when j = 0, the total is actually the entire length to max.
+          total = last - j;
+
+          if (total > 0) {
+            if (path[last - 1] == f_path_separator[0]) {
+              f_macro_string_dynamic_new(status, part, total);
+              if (f_status_is_error(status)) return status;
+
+              part.used = total;
+            }
+            else {
+              f_macro_string_dynamic_new(status, part, total + 1);
+              if (f_status_is_error(status)) return status;
+
+              part.used = total + 1;
+              part.string[total] = f_path_separator[0];
+            }
+
+            memcpy(part.string, path, total);
+          }
+        }
+
+        paths->array[paths->used].string = part.string;
+        paths->array[paths->used].used = part.used;
+        paths->array[paths->used].size = part.size;
+        paths->used++;
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_f_path_explode_
+
+#ifndef _di_f_path_explode_dynamic_
+  f_return_status f_path_explode_dynamic(const f_string_static path, f_string_dynamics *paths) {
+    #ifndef _di_level_0_parameter_checking_
+      if (path.used > path.size) return f_status_set_error(f_invalid_parameter);
+      if (paths == 0) return f_status_set_error(f_invalid_parameter);
+      if (paths->used > paths->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    f_status status = f_none;
+
+    if (path.used == 0) {
+      // When PATH is "", this is actually a valid search path for CWD.
+      // Therefore append an equivalent representation of CWD (string used length is 0).
+      if (paths->used + 1 > paths->size) {
+        if (paths->size + f_memory_default_allocation_step > f_array_length_size) {
+          if (paths->size + 1 > f_array_length_size) {
+            return f_status_set_error(f_buffer_too_large);
+          }
+
+          f_macro_string_dynamics_resize(status, (*paths), paths->used + 1);
+          if (f_status_is_error(status)) return status;
+        }
+        else {
+          f_macro_string_dynamics_resize(status, (*paths), paths->used + f_memory_default_allocation_step);
+          if (f_status_is_error(status)) return status;
+        }
+      }
+
+      paths->array[paths->used].string = 0;
+      paths->array[paths->used].used = 0;
+      paths->array[paths->used].size = 0;
+      paths->used++;
+
+      return f_none;
+    }
+
+    f_string_length i = path.used;
+    f_string_length j = path.used;
+    f_string_length k = 0;
+    f_string_length last = path.used;
+    f_string_length total = 0;
+
+    for (; i > 0; i--) {
+      j--;
+
+      if (j == 0 || path.string[j] == f_path_separator_variable[0]) {
+        if (paths->used + 1 > paths->size) {
+          if (paths->size + f_memory_default_allocation_step > f_array_length_size) {
+            if (paths->size + 1 > f_array_length_size) {
+              return f_status_set_error(f_buffer_too_large);
+            }
+
+            f_macro_string_dynamics_resize(status, (*paths), paths->used + 1);
+            if (f_status_is_error(status)) return status;
+          }
+          else {
+            f_macro_string_dynamics_resize(status, (*paths), paths->used + f_memory_default_allocation_step);
+            if (f_status_is_error(status)) return status;
+          }
+        }
+
+        f_string_dynamic part = f_string_dynamic_initialize;
+
+        if (path.string[j] == f_path_separator_variable[0]) {
+          total = last - i;
+
+          if (total > 0) {
+            f_macro_string_dynamic_new(status, part, total + 1);
+            if (f_status_is_error(status)) return status;
+
+            for (k = 0; k < total; k++) {
+              if (path.string[i + k] == 0) continue;
+
+              part.string[part.used] = path.string[i + k];
+              part.used++;
+            } // for
+
+            if (part.string[part.used - 1] != f_path_separator[0]) {
+              part.string[part.used] = f_path_separator[0];
+              part.used++;
+            }
+          }
+
+          last = j;
+        }
+        else if (j == 0) {
+          // when j = 0, the total is actually the entire length to max.
+          total = last - j;
+
+          f_macro_string_dynamic_new(status, part, total + 1);
+          if (f_status_is_error(status)) return status;
+
+          for (k = 0; k < total; k++) {
+            if (path.string[i + k] == 0) continue;
+
+            part.string[part.used] = path.string[i + k];
+            part.used++;
+          } // for
+
+          if (part.string[part.used - 1] != f_path_separator[0]) {
+            part.string[part.used - 1] = f_path_separator[0];
+            part.used++;
+          }
+        }
+
+        paths->array[paths->used].string = part.string;
+        paths->array[paths->used].used = part.used;
+        paths->array[paths->used].size = part.size;
+        paths->used++;
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_f_path_explode_dynamic_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_path/c/path.h b/level_0/f_path/c/path.h
index a4a11cd..149a91a 100644
--- a/level_0/f_path/c/path.h
+++ b/level_0/f_path/c/path.h
@@ -10,7 +10,16 @@
 #ifndef _F_path_h
 #define _F_path_h
 
+// libc includes
+#include <linux/limits.h> // defines PATH_MAX
+#include <string.h>
+
 // fll-0 includes
+#include <level_0/status.h>
+#include <level_0/memory.h>
+#include <level_0/string.h>
+#include <level_0/type.h>
+#include <level_0/utf.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -20,15 +29,77 @@ extern "C" {
  * Standard path defines.
  *
  * The path separator, intended to be represented as a single character.
+ * The path separator length must be a 1-byte wide character.
  *
- * The length is intended to provide a UTF-8 compatible width and therefore represents bytes and not characters.
- * A length of 1 = 1-byte wide character, a length of 4 = 4-byte wide character.
+ * The path variable separator is intended to represent the path separator used in the PATH environment variable.
+ * PATH="/bin:/usr/bin", the path variable separator is ':'.
+ * The path variable separator must be a 1-byte wide character.
  */
 #ifndef _di_f_path_defines_
-  #define f_path_separator "/"
-  #define f_path_separator_length 1
+  #define f_path_separator          "/"
+  #define f_path_separator_variable ":"
+
+  #define f_path_environment         "PATH"
+  #define f_path_home_wildcard       "~"
+  #define f_path_present_working     "PWD"
+  #define f_path_present_working_old "OLDPWD"
+
+  #define f_path_environment_length         4
+  #define f_path_home_wildcard_length       1
+  #define f_path_present_working_length     3
+  #define f_path_present_working_old_length 6
+
+  #define f_path_max PATH_MAX
 #endif // _di_f_path_defines_
 
+/**
+ * Separate a given PATH-style string into multiple separate paths.
+ *
+ * @param path
+ *   The string to process that is expected to follow the traditional Linux standard PATH environment variable.
+ *   Each seperate path is separated by a single ':'.
+ *   Must not contain NULLs except for the terminating NULL.
+ *   Must be NULL terminated.
+ * @param paths
+ *   All of the strings exploded from PATH.
+ *   Each exploded path, when not empty, is guaranteed to have a trailing '/'.
+ *   Each exploded path is not NULL terminated.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_buffer_too_large (with error bit) if paths array is too large for further addressing.
+ */
+#ifndef _di_f_path_explode_
+  extern f_return_status f_path_explode(const f_string path, f_string_dynamics *paths);
+#endif // _di_f_path_explode_
+
+/**
+ * Separate a given PATH-style string into multiple separate paths.
+ *
+ * @param path
+ *   The string to process that is expected to follow the traditional Linux standard PATH environment variable.
+ *   Each seperate path is separated by a single ':'.
+ *   Need not be NULL terminated.
+ *   NULLs are ignored and are not copied into the exploded paths.
+ * @param paths
+ *   All of the strings exploded from PATH.
+ *   Each exploded path, when not empty, is guaranteed to have a trailing '/'.
+ *   Each exploded path is not NULL terminated.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_buffer_too_large (with error bit) if paths array is too large for further addressing.
+ */
+#ifndef _di_f_path_explode_dynamic_
+  extern f_return_status f_path_explode_dynamic(const f_string_static path, f_string_dynamics *paths);
+#endif // _di_f_path_explode_dynamic_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/level_0/f_path/data/build/dependencies b/level_0/f_path/data/build/dependencies
index e69de29..13b45c7 100644
--- a/level_0/f_path/data/build/dependencies
+++ b/level_0/f_path/data/build/dependencies
@@ -0,0 +1,5 @@
+f_type
+f_status
+f_memory
+f_string
+f_utf
diff --git a/level_0/f_path/data/build/settings b/level_0/f_path/data/build/settings
index e57e32e..fde4046 100644
--- a/level_0/f_path/data/build/settings
+++ b/level_0/f_path/data/build/settings
@@ -9,10 +9,10 @@ version_micro 0
 
 build_compiler gcc
 build_linker ar
-build_libraries 
-build_libraries_fll
-build_sources_library 
-build_sources_program 
+build_libraries -lc
+build_libraries_fll -lf_utf -lf_memory
+build_sources_library
+build_sources_program path.c
 build_sources_headers path_fll.h path_filesystem.h path.h
 build_sources_bash
 build_sources_settings
diff --git a/level_0/f_string/c/string.h b/level_0/f_string/c/string.h
index da96a44..2b2afc3 100644
--- a/level_0/f_string/c/string.h
+++ b/level_0/f_string/c/string.h
@@ -75,7 +75,6 @@ extern "C" {
 #ifndef _di_f_string_
   typedef char *f_string;
 
-  #define f_string_max_size   f_type_number_size_unsigned
   #define f_string_initialize 0
 
   #define f_macro_string_new(status, string, length)     status = f_memory_new((void **) & string, sizeof(f_string), length)
@@ -97,7 +96,7 @@ extern "C" {
 
   // string size is set to (size - 4) to compensate for UTF-8 4-byte character such that it can easily act as a (size - 1) regardless of UTF-8.
   #define f_string_length_size     0xfffffffffffffffb
-  #define f_string_length_size_max f_type_size_max_64_positive
+  #define f_string_length_size_max f_type_number_size_max_unsigned
 
   #define f_string_length_printf string_format_long_integer
 
diff --git a/level_1/fl_file/c/file.c b/level_1/fl_file/c/file.c
index 241d114..50340c2 100644
--- a/level_1/fl_file/c/file.c
+++ b/level_1/fl_file/c/file.c
@@ -22,7 +22,7 @@ extern "C" {
 
     for (;;) {
       if (buffer->used + bytes_total > buffer->size) {
-        if (buffer->used + bytes_total > f_string_max_size) return f_status_set_error(f_string_too_large);
+        if (buffer->used + bytes_total > f_string_length_size) return f_status_set_error(f_string_too_large);
 
         f_macro_string_dynamic_resize(status, (*buffer), buffer->used + bytes_total);
 
@@ -65,7 +65,7 @@ extern "C" {
     }
 
     if (buffer->used + bytes_total > buffer->size) {
-      if (buffer->used + bytes_total > f_string_max_size) return f_status_set_error(f_string_too_large);
+      if (buffer->used + bytes_total > f_string_length_size) return f_status_set_error(f_string_too_large);
 
       f_macro_string_dynamic_resize(status, (*buffer), buffer->used + bytes_total);
 
@@ -79,7 +79,7 @@ extern "C" {
 
     while (infinite) {
       if (buffer->used + bytes_total > buffer->size) {
-        if (buffer->used + bytes_total > f_string_max_size) return f_status_set_error(f_string_too_large);
+        if (buffer->used + bytes_total > f_string_length_size) return f_status_set_error(f_string_too_large);
 
         f_macro_string_dynamic_resize(status, (*buffer), buffer->used + bytes_total);
 
diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h
index 938f0b8..40d5338 100644
--- a/level_1/fl_status/c/status.h
+++ b/level_1/fl_status/c/status.h
@@ -600,9 +600,6 @@ extern "C" {
     #define fl_status_string_file_found "f_file_found"
     #define fl_status_string_file_found_length 12
 
-    #define fl_status_string_file_is "f_file_is"
-    #define fl_status_string_file_is_length 9
-
     #define fl_status_string_file_is_empty "f_file_is_empty"
     #define fl_status_string_file_is_empty_length 15
 
diff --git a/level_1/fl_string/c/private-string.c b/level_1/fl_string/c/private-string.c
index 03d6c50..b1ed1ab 100644
--- a/level_1/fl_string/c/private-string.c
+++ b/level_1/fl_string/c/private-string.c
@@ -7,7 +7,7 @@ extern "C" {
 
 #if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_)
   f_return_status private_fl_string_append(const f_string source, const f_string_length length, f_string_dynamic *destination) {
-    if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large);
+    if (destination->used + length > f_string_length_size) return f_status_set_error(f_string_too_large);
 
     f_status status = f_none;
 
@@ -27,7 +27,7 @@ extern "C" {
 
 #if !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_)
   f_return_status private_fl_string_append_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination) {
-    if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large);
+    if (destination->used + length > f_string_length_size) return f_status_set_error(f_string_too_large);
 
     f_status status = f_none;
 
@@ -38,7 +38,7 @@ extern "C" {
         if (i > first) {
           f_string_length size = i - first;
 
-          if (destination->used + size > f_string_max_size) return f_status_set_error(f_string_too_large);
+          if (destination->used + size > f_string_length_size) return f_status_set_error(f_string_too_large);
 
           f_string_length total = destination->used + size;
 
@@ -59,7 +59,7 @@ extern "C" {
           if (i > first) {
             f_string_length size = i - first;
 
-            if (destination->used + size > f_string_max_size) return f_status_set_error(f_string_too_large);
+            if (destination->used + size > f_string_length_size) return f_status_set_error(f_string_too_large);
 
             f_string_length total = destination->used + size;
 
@@ -249,7 +249,7 @@ extern "C" {
 
 #if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_)
   f_return_status private_fl_string_prepend(const f_string source, const f_string_length length, f_string_dynamic *destination) {
-    if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large);
+    if (destination->used + length > f_string_length_size) return f_status_set_error(f_string_too_large);
 
     f_status status = f_none;
 
@@ -275,7 +275,7 @@ extern "C" {
 
 #if !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_)
   f_return_status private_fl_string_prepend_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination) {
-    if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large);
+    if (destination->used + length > f_string_length_size) return f_status_set_error(f_string_too_large);
 
     f_status status = f_none;
 
@@ -287,7 +287,7 @@ extern "C" {
         if (i > first) {
           f_string_length size = i - first;
 
-          if (destination->used + size > f_string_max_size) return f_status_set_error(f_string_too_large);
+          if (destination->used + size > f_string_length_size) return f_status_set_error(f_string_too_large);
 
           f_string_length total = destination->used + size;
 
@@ -311,7 +311,7 @@ extern "C" {
           if (i > first) {
             f_string_length size = i - first;
 
-            if (destination->used + size > f_string_max_size) return f_status_set_error(f_string_too_large);
+            if (destination->used + size > f_string_length_size) return f_status_set_error(f_string_too_large);
 
             f_string_length total = destination->used + size;
 
diff --git a/level_1/fl_string/c/private-string.h b/level_1/fl_string/c/private-string.h
index 2d80ddf..2b7ed7d 100644
--- a/level_1/fl_string/c/private-string.h
+++ b/level_1/fl_string/c/private-string.h
@@ -33,7 +33,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -61,7 +61,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -151,7 +151,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -177,7 +177,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
diff --git a/level_1/fl_string/c/string.c b/level_1/fl_string/c/string.c
index 6164cb5..e2ee4f7 100644
--- a/level_1/fl_string/c/string.c
+++ b/level_1/fl_string/c/string.c
@@ -1044,7 +1044,7 @@ extern "C" {
 
     if (destination->used > 0 && destination->string[destination->used - 1] == 0) return f_none;
 
-    if (destination->used + 1 > f_string_max_size) return f_status_set_error(f_string_too_large);
+    if (destination->used + 1 > f_string_length_size) return f_status_set_error(f_string_too_large);
 
     const f_string_length total = destination->used + 1;
 
diff --git a/level_1/fl_string/c/string.h b/level_1/fl_string/c/string.h
index 2b64c98..a8fb523 100644
--- a/level_1/fl_string/c/string.h
+++ b/level_1/fl_string/c/string.h
@@ -47,7 +47,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -73,7 +73,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -100,7 +100,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -126,7 +126,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -207,7 +207,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -229,7 +229,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -253,7 +253,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -277,7 +277,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -356,7 +356,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -386,7 +386,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -414,7 +414,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -444,7 +444,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -468,7 +468,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -494,7 +494,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -522,7 +522,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -548,7 +548,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -637,7 +637,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -669,7 +669,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -699,7 +699,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -731,7 +731,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -757,7 +757,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -785,7 +785,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -813,7 +813,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -839,7 +839,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -863,7 +863,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -889,7 +889,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -915,7 +915,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -939,7 +939,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1209,7 +1209,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1241,7 +1241,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1271,7 +1271,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1303,7 +1303,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1329,7 +1329,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1357,7 +1357,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1386,7 +1386,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1415,7 +1415,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
diff --git a/level_1/fl_utf/c/private-utf.h b/level_1/fl_utf/c/private-utf.h
index fec7055..70b1cec 100644
--- a/level_1/fl_utf/c/private-utf.h
+++ b/level_1/fl_utf/c/private-utf.h
@@ -31,7 +31,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -59,7 +59,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -149,7 +149,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -175,7 +175,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
diff --git a/level_1/fl_utf/c/utf.h b/level_1/fl_utf/c/utf.h
index 253940f..a59fb21 100644
--- a/level_1/fl_utf/c/utf.h
+++ b/level_1/fl_utf/c/utf.h
@@ -49,7 +49,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -77,7 +77,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -105,7 +105,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -134,7 +134,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -217,7 +217,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -241,7 +241,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -266,7 +266,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -290,7 +290,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -371,7 +371,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -402,7 +402,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -431,7 +431,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -462,7 +462,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -487,7 +487,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -511,7 +511,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -538,7 +538,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -565,7 +565,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -656,7 +656,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -688,7 +688,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -718,7 +718,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -750,7 +750,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -776,7 +776,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -804,7 +804,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -832,7 +832,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -858,7 +858,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 or range is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -882,7 +882,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -908,7 +908,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -934,7 +934,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -958,7 +958,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1244,7 +1244,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1278,7 +1278,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1310,7 +1310,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1344,7 +1344,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1372,7 +1372,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1402,7 +1402,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1433,7 +1433,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -1463,7 +1463,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if source length is 0 (start > stop).
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
diff --git a/level_1/fl_utf_file/c/utf_file.c b/level_1/fl_utf_file/c/utf_file.c
index b8e4e49..d3205aa 100644
--- a/level_1/fl_utf_file/c/utf_file.c
+++ b/level_1/fl_utf_file/c/utf_file.c
@@ -124,7 +124,7 @@ extern "C" {
 
     do {
       if (buffer->used + bytes_total > buffer->size) {
-        if (buffer->used + bytes_total > f_string_max_size) return f_status_set_error(f_string_too_large);
+        if (buffer->used + bytes_total > f_string_length_size) return f_status_set_error(f_string_too_large);
 
         f_macro_string_dynamic_resize(status, (*buffer), buffer->used + bytes_total);
 
diff --git a/level_2/fll_execute/c/execute.c b/level_2/fll_execute/c/execute.c
index ef93975..8eb5a24 100644
--- a/level_2/fll_execute/c/execute.c
+++ b/level_2/fll_execute/c/execute.c
@@ -207,7 +207,7 @@ extern "C" {
     last_slash = strrchr(program_path, '/');
 
     if (last_slash != 0) {
-      name_size = strnlen(last_slash, PATH_MAX);
+      name_size = strnlen(last_slash, f_path_max);
 
       if (name_size > 1) {
         f_macro_string_new(status, program_name, name_size + 1);
@@ -249,10 +249,17 @@ extern "C" {
     // insert the required array terminated
     fixed_arguments[arguments.used + 2] = 0;
 
-    // @todo validate that the file at program_path actually exists before attempting to fork and execute
-    int process_id = 0;
+    status = f_file_exists(program_path);
+    if (f_status_is_error(status)) {
+      return status;
+    }
+    else if (status == f_false) {
+      return f_status_set_error(f_file_not_found);
+    }
+
+    pid_t process_id = 0;
 
-    process_id = vfork();
+    process_id = fork();
 
     if (process_id < 0) {
       if (name_size > 0) f_macro_string_delete_simple(program_name, name_size);
@@ -281,7 +288,7 @@ extern "C" {
       f_macro_string_delete_simple(fixed_arguments[i + 1], arguments.array[i].used + 1);
     } // for
 
-    if (*result != 0) return f_status_set_error(f_failure);
+    if (result != 0 && *result != 0) return f_status_set_error(f_failure);
 
     return f_none;
   }
@@ -312,7 +319,7 @@ extern "C" {
     last_slash = strrchr(program_path, '/');
 
     if (last_slash != 0) {
-      name_size = strnlen(last_slash, PATH_MAX);
+      name_size = strnlen(last_slash, f_path_max);
 
       if (name_size > 1) {
         f_macro_string_new(status, program_name, name_size + 1);
@@ -354,10 +361,17 @@ extern "C" {
     // insert the required array terminated
     fixed_arguments[arguments.used + 2] = 0;
 
-    // @todo validate that the file at program_path actually exists before attempting to fork and execute
-    int process_id = 0;
+    status = f_file_exists(program_path);
+    if (f_status_is_error(status)) {
+      return status;
+    }
+    else if (status == f_false) {
+      return f_status_set_error(f_file_not_found);
+    }
+
+    pid_t process_id = 0;
 
-    process_id = vfork();
+    process_id = fork();
 
     if (process_id < 0) {
       if (name_size > 0) f_macro_string_delete_simple(program_name, name_size);
@@ -375,7 +389,7 @@ extern "C" {
 
       for (f_array_length i = 0; i < names.used; i++) {
         f_environment_set_dynamic(names.array[i], values.array[i], true);
-      }
+      } // for
 
       execv(program_path, fixed_arguments);
 
@@ -392,7 +406,7 @@ extern "C" {
       f_macro_string_delete_simple(fixed_arguments[i + 1], arguments.array[i].used + 1);
     } // for
 
-    if (*result != 0) return f_status_set_error(f_failure);
+    if (result != 0 && *result != 0) return f_status_set_error(f_failure);
 
     return f_none;
   }
@@ -412,8 +426,9 @@ extern "C" {
     fixed_arguments[0] = program_name;
 
     f_status status = f_none;
+    f_string_length i = 0;
 
-    for (f_string_length i = 0; i < arguments.used; i++) {
+    for (; i < arguments.used; i++) {
       f_macro_string_new(status, fixed_arguments[i + 1], arguments.array[i].used + 1);
 
       if (f_status_is_error(status)) {
@@ -431,10 +446,9 @@ extern "C" {
     // insert the required array terminated
     fixed_arguments[arguments.used + 2] = 0;
 
-    // @todo validate that the file at program_path actually exists before attempting to fork and execute
-    int process_id = 0;
+    pid_t process_id = 0;
 
-    process_id = vfork();
+    process_id = fork();
 
     if (process_id < 0) {
       for (f_string_length i = 0; i < arguments.used; i++) {
@@ -459,7 +473,7 @@ extern "C" {
       f_macro_string_delete_simple(fixed_arguments[i + 1], arguments.array[i].used + 1);
     } // for
 
-    if (*result != 0) return f_status_set_error(f_failure);
+    if (result != 0 && *result != 0) return f_status_set_error(f_failure);
 
     return f_none;
   }
@@ -482,8 +496,9 @@ extern "C" {
     fixed_arguments[0] = program_name;
 
     f_status status = f_none;
+    f_string_length i = 0;
 
-    for (f_string_length i = 0; i < arguments.used; i++) {
+    for (; i < arguments.used; i++) {
       f_macro_string_new(status, fixed_arguments[i + 1], arguments.array[i].used + 1);
 
       if (f_status_is_error(status)) {
@@ -501,10 +516,90 @@ extern "C" {
     // insert the required array terminated
     fixed_arguments[arguments.used + 2] = 0;
 
-    // @todo validate that the file at program_path actually exists before attempting to fork and execute
-    int process_id = 0;
+    f_string_dynamic path = f_string_dynamic_initialize;
+    f_string_dynamics paths = f_string_dynamics_initialize;
+
+    status = f_environment_get("PATH", &path);
+
+    if (f_status_is_error(status)) {
+      // Do not consider PATH is not available (or valid?) to be an error.
+      if (f_status_set_fine(status) == f_invalid || f_status_set_fine(status) == f_failure) {
+        status = f_none;
+      }
+    }
+    else {
+      status = f_path_explode_dynamic(path, &paths);
+    }
+
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(path);
+      f_macro_string_dynamics_delete_simple(paths);
+      return status;
+    }
+
+    f_macro_string_dynamic_delete(status, path);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamics_delete_simple(paths);
+      return status;
+    }
 
-    process_id = vfork();
+    const f_string_length program_name_length = strnlen(program_name, f_path_max);
+    f_string_dynamic *found = 0;
+
+    for (i = 0; i < paths.used; i++) {
+      status = fl_string_append(program_name, program_name_length, &paths.array[i]);
+
+      if (!f_status_is_error(status)) {
+        status = fl_string_dynamic_terminate(&paths.array[i]);
+      }
+
+      if (!f_status_is_error(status)) {
+        status = f_file_exists(paths.array[i].string);
+
+        if (status == f_true) {
+          found = &paths.array[i];
+          break;
+        }
+
+        if (f_status_is_error(status)) {
+          status = f_status_set_fine(status);
+
+          // don't consider bad/non-accessible paths an error, just ignore them.
+          if (status == f_invalid_name) {
+            continue;
+          }
+          else if (status == f_invalid_directory) {
+            continue;
+          }
+          else if (status == f_access_denied) {
+            continue;
+          }
+        }
+      }
+
+      if (f_status_is_error(status)) {
+        f_macro_string_dynamics_delete_simple(paths);
+        return status;
+      }
+    } // for
+
+    if (found == 0) {
+      f_macro_string_dynamics_delete_simple(paths);
+      return f_status_set_error(f_file_not_found);
+    }
+
+    char program_path[found->used];
+
+    memcpy(&program_path, found->string, found->used);
+
+    f_macro_string_dynamics_delete(status, paths);
+    if (f_status_is_error(status)) {
+      return status;
+    }
+
+    pid_t process_id = 0;
+
+    process_id = fork();
 
     if (process_id < 0) {
       for (f_string_length i = 0; i < arguments.used; i++) {
@@ -522,7 +617,7 @@ extern "C" {
         f_environment_set_dynamic(names.array[i], values.array[i], true);
       }
 
-      execvp(program_name, fixed_arguments);
+      execvp(program_path, fixed_arguments);
 
       // according to manpages, calling _exit() is safer and should be called here instead of exit()
       _exit(-1);
@@ -535,7 +630,7 @@ extern "C" {
       f_macro_string_delete_simple(fixed_arguments[i + 1], arguments.array[i].used + 1);
     } // for
 
-    if (*result != 0) return f_status_set_error(f_failure);
+    if (result != 0 && *result != 0) return f_status_set_error(f_failure);
 
     return f_none;
   }
diff --git a/level_2/fll_execute/c/execute.h b/level_2/fll_execute/c/execute.h
index 6d1e6e1..3da6b74 100644
--- a/level_2/fll_execute/c/execute.h
+++ b/level_2/fll_execute/c/execute.h
@@ -11,7 +11,6 @@
 #define _FLL_execute_h
 
 // libc includes
-#include <linux/limits.h> // defines PATH_MAX
 #include <memory.h>
 #include <signal.h>
 #include <string.h>
@@ -24,6 +23,8 @@
 #include <level_0/string.h>
 #include <level_0/type.h>
 #include <level_0/environment.h>
+#include <level_0/file.h>
+#include <level_0/path.h>
 
 // fll-1 includes
 #include <level_1/string.h>
@@ -51,7 +52,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_add_
   extern f_return_status fll_execute_arguments_add(const f_string source, const f_string_length length, f_string_dynamics *arguments);
@@ -89,7 +90,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_add_parameter_
   extern f_return_status fll_execute_arguments_add_parameter(const f_string prefix, const f_string_length prefix_length, const f_string name, const f_string_length name_length, const f_string value, const f_string_length value_length, f_string_dynamics *arguments);
@@ -130,7 +131,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_add_parameter_set_
   extern f_return_status fll_execute_arguments_add_parameter_set(const f_string prefix[], const f_string_length prefix_length[], const f_string name[], const f_string_length name_length[], const f_string value[], const f_string_length value_length[], const f_array_length size, f_string_dynamics *arguments);
@@ -157,7 +158,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_add_set_
   extern f_return_status fll_execute_arguments_add_set(const f_string source[], const f_string_length length[], const f_array_length size, f_string_dynamics *arguments);
@@ -180,7 +181,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_dynamic_add_
   extern f_return_status fll_execute_arguments_dynamic_add(const f_string_static source, f_string_dynamics *arguments);
@@ -213,7 +214,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_dynamic_add_parameter_
   extern f_return_status fll_execute_arguments_dynamic_add_parameter(const f_string_static prefix, const f_string_static name, const f_string_static value, f_string_dynamics *arguments);
@@ -248,7 +249,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_dynamic_add_parameter_set_
   extern f_return_status fll_execute_arguments_dynamic_add_parameter_set(const f_string_static prefix[], const f_string_static name[], const f_string_static value[], const f_array_length size, f_string_dynamics *arguments);
@@ -273,7 +274,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  */
 #ifndef _di_fll_execute_arguments_dynamic_add_set_
   extern f_return_status fll_execute_arguments_dynamic_add_set(const f_string_static source[], const f_array_length size, f_string_dynamics *arguments);
@@ -282,6 +283,8 @@ extern "C" {
 /**
  * Execute a program given some path + program name (such as "/bin/bash").
  *
+ * This does validate that the program path exists.
+ *
  * @param program_path
  *   The entire path to the program.
  * @param arguments
@@ -295,6 +298,14 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_file_not_found (with error bit) if file does not exist at the program_path.
+ *   f_invalid_name (with error bit) if the program_path is too long.
+ *   f_out_of_memory (with error bit) if out of memory.
+ *   f_number_overflow (with error bit) on overflow error.
+ *   f_invalid_directory (with error bit) on invalid directory in program_path.
+ *   f_access_denied (with error bit) on access denied for program_path.
+ *   f_loop (with error bit) on loop error while checking the program_path.
+ *   f_file_error_stat (with error bit) on stat error while checking the program_path.
  *
  * @see execv()
  */
@@ -305,6 +316,8 @@ extern "C" {
 /**
  * Execute a program given some path + program name (such as "/bin/bash").
  *
+ * This does validate that the program path exists.
+ *
  * The environment is defined by the names and values pair.
  *
  * @param program_path
@@ -318,7 +331,7 @@ extern "C" {
  * @param values
  *   An array of strings representing the environment variable names.
  *   The values.used must be of at least names.used.
- *   Set individual strings.used to 0 for empty/null values.
+ *   Set individual strings.used to 0 for empty/NULL values.
  * @param result
  *   The code returned after finishing execution of program_path.
  *
@@ -328,6 +341,14 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_file_not_found (with error bit) if file does not exist at the program_path.
+ *   f_invalid_name (with error bit) if the program_path is too long.
+ *   f_out_of_memory (with error bit) if out of memory.
+ *   f_number_overflow (with error bit) on overflow error.
+ *   f_invalid_directory (with error bit) on invalid directory in program_path.
+ *   f_access_denied (with error bit) on access denied for program_path.
+ *   f_loop (with error bit) on loop error while checking the program_path.
+ *   f_file_error_stat (with error bit) on stat error while checking the program_path.
  *
  * @see execv()
  */
@@ -338,6 +359,8 @@ extern "C" {
 /**
  * Execute a program given by name found in the PATH environment (such as "bash").
  *
+ * This does not validate the path to the program.
+ *
  * @param program_name
  *   The name of the program.
  * @param arguments
@@ -352,6 +375,8 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_file_not_found (with error bit) if file does not exist at the program_path.
+ *   f_string_length_size (with error bit) if the combined string (generated from PATH) is too large.
  *
  * @see execvp()
  */
@@ -364,7 +389,9 @@ extern "C" {
  *
  * Uses the provided environment array to designate the environment for the called program.
  *
- * @todo this probably needs special work to find the program from PATH when PATH environment variable gets cleared before execution.
+ * This does validate the path to the program because it completes the path to the program.
+ * This is done because the PATH environment will get cleared or may be set differently.
+ * Execution of program_name is done using the PATH environment prior to clearing and reassigning the environment variables.
  *
  * @param program_name
  *   The name of the program.
@@ -388,6 +415,15 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_file_not_found (with error bit) if file does not exist at the program_path.
+ *   f_invalid_name (with error bit) if the program_path is too long.
+ *   f_out_of_memory (with error bit) if out of memory.
+ *   f_number_overflow (with error bit) on overflow error.
+ *   f_invalid_directory (with error bit) on invalid directory in program_path.
+ *   f_access_denied (with error bit) on access denied for program_path.
+ *   f_loop (with error bit) on loop error while checking the program_path.
+ *   f_buffer_too_large (with error bit) if paths array (generated from PATH) is too large for further addressing.
+ *   f_string_length_size (with error bit) if the combined string (generated from PATH) is too large.
  *
  * @see execvpe()
  */
diff --git a/level_2/fll_execute/c/private-execute.h b/level_2/fll_execute/c/private-execute.h
index 1d959a3..9fb5458 100644
--- a/level_2/fll_execute/c/private-execute.h
+++ b/level_2/fll_execute/c/private-execute.h
@@ -12,7 +12,6 @@
 #define _PRIVATE_FLL_execute_h
 
 // libc includes
-#include <linux/limits.h> // defines PATH_MAX
 #include <memory.h>
 #include <signal.h>
 #include <string.h>
@@ -49,7 +48,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  *
  * @see fll_execute_arguments_add()
  * @see fll_execute_arguments_add_set()
@@ -86,7 +85,7 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on allocation error.
  *   f_error_reallocation (with error bit) on reallocation error.
- *   f_buffer_too_large (with error bit) if arguments array is too larger for further allocation.
+ *   f_buffer_too_large (with error bit) if arguments array is too large for further allocation.
  *
  * @see fll_execute_arguments_add_parameter()
  * @see fll_execute_arguments_add_parameter_set()
diff --git a/level_2/fll_execute/data/build/dependencies b/level_2/fll_execute/data/build/dependencies
index c33a8e4..fad9ef5 100644
--- a/level_2/fll_execute/data/build/dependencies
+++ b/level_2/fll_execute/data/build/dependencies
@@ -3,4 +3,6 @@ f_status
 f_memory
 f_string
 f_environment
+f_file
+f_path
 fl_string
diff --git a/level_2/fll_execute/data/build/settings b/level_2/fll_execute/data/build/settings
index e9f161e..211a37f 100644
--- a/level_2/fll_execute/data/build/settings
+++ b/level_2/fll_execute/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfl_string -lf_environment -lf_memory
+build_libraries_fll -lfl_string -lf_environment -lf_file -lf_path -lf_memory
 build_sources_library execute.c private-execute.c
 build_sources_program
 build_sources_headers execute.h
diff --git a/level_2/fll_fss/c/fss.c b/level_2/fll_fss/c/fss.c
index 54e8482..16a98fb 100644
--- a/level_2/fll_fss/c/fss.c
+++ b/level_2/fll_fss/c/fss.c
@@ -70,7 +70,7 @@ extern "C" {
         if (f_status_is_error(status)) return status;
         if (status == f_not_equal_to) continue;
 
-        if (values[j]->used + contents.array[i].used > f_string_max_size) return f_status_set_error(f_buffer_too_large);
+        if (values[j]->used + contents.array[i].used > f_string_length_size) return f_status_set_error(f_buffer_too_large);
 
         if (values[j]->used + contents.array[i].used > values[j]->used) {
           f_macro_string_dynamics_resize(status, (*values[j]), values[j]->used + contents.array[i].used);
@@ -195,8 +195,8 @@ extern "C" {
         if (f_status_is_error(status)) return status;
         if (status == f_not_equal_to) continue;
 
-        if (values[j]->used + f_fss_default_allocation_step > f_string_max_size) {
-          if (values[j]->used + 1 > f_string_max_size) return f_status_set_error(f_buffer_too_large);
+        if (values[j]->used + f_fss_default_allocation_step > f_string_length_size) {
+          if (values[j]->used + 1 > f_string_length_size) return f_status_set_error(f_buffer_too_large);
 
           f_macro_string_dynamics_resize(status, (*values[j]), values[j]->used + 1);
           if (f_status_is_error(status)) return status;
diff --git a/level_2/fll_fss/c/fss.h b/level_2/fll_fss/c/fss.h
index c0d11d6..1dde4da 100644
--- a/level_2/fll_fss/c/fss.h
+++ b/level_2/fll_fss/c/fss.h
@@ -63,7 +63,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ *   f_string_length_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_
   extern f_return_status fll_fss_snatch(const f_string_static buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size);
@@ -102,7 +102,7 @@ extern "C" {
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_buffer_too_large (with error bit) on maximum buffer limit reached when processing values.
- *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ *   f_string_length_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_apart_
   extern f_return_status fll_fss_snatch_apart(const f_string_static buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamics *values[], const f_string_length size);
@@ -140,7 +140,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ *   f_string_length_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_together_
   extern f_return_status fll_fss_snatch_together(const f_string_static buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size);
@@ -183,7 +183,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ *   f_string_length_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_mash_
   extern f_return_status fll_fss_snatch_mash(const f_string_static buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size, const f_string glue, const f_string_length glue_length);
@@ -225,7 +225,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ *   f_string_length_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_mash_apart_
   extern f_return_status fll_fss_snatch_mash_apart(const f_string_static buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamics *values[], const f_string_length size, const f_string glue, const f_string_length glue_length);
@@ -267,7 +267,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ *   f_string_length_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_mash_together_
   extern f_return_status fll_fss_snatch_mash_together(const f_string_static buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size, const f_string glue, const f_string_length glue_length);
diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c
index d1f506a..24a9108 100644
--- a/level_2/fll_fss/c/fss_basic.c
+++ b/level_2/fll_fss/c/fss_basic.c
@@ -136,7 +136,7 @@ extern "C" {
 
       objects->used++;
       contents->used++;
-    } while (range->start < f_string_max_size);
+    } while (range->start < f_string_length_size);
 
     return f_status_is_error(f_number_overflow);
   }
diff --git a/level_2/fll_fss/c/fss_basic_list.c b/level_2/fll_fss/c/fss_basic_list.c
index 1d199ab..03768ce 100644
--- a/level_2/fll_fss/c/fss_basic_list.c
+++ b/level_2/fll_fss/c/fss_basic_list.c
@@ -136,7 +136,7 @@ extern "C" {
 
       objects->used++;
       contents->used++;
-    } while (location->start < f_string_max_size);
+    } while (location->start < f_string_length_size);
 
     return f_status_is_error(f_number_overflow);
   }
diff --git a/level_2/fll_fss/c/fss_extended.c b/level_2/fll_fss/c/fss_extended.c
index 20cdef0..abbbbbd 100644
--- a/level_2/fll_fss/c/fss_extended.c
+++ b/level_2/fll_fss/c/fss_extended.c
@@ -136,7 +136,7 @@ extern "C" {
 
       objects->used++;
       contents->used++;
-    } while (location->start < f_string_max_size);
+    } while (location->start < f_string_length_size);
 
     return f_status_is_error(f_number_overflow);
   }
diff --git a/level_2/fll_fss/c/fss_extended_list.c b/level_2/fll_fss/c/fss_extended_list.c
index 96971c6..dcfeaa8 100644
--- a/level_2/fll_fss/c/fss_extended_list.c
+++ b/level_2/fll_fss/c/fss_extended_list.c
@@ -105,7 +105,7 @@ extern "C" {
 
         return f_none_on_stop;
       }
-    } while (location->start < f_string_max_size);
+    } while (location->start < f_string_length_size);
 
     return f_status_is_error(f_number_overflow);
   }
diff --git a/level_2/fll_program/c/program.c b/level_2/fll_program/c/program.c
index becbde0..3baaea3 100644
--- a/level_2/fll_program/c/program.c
+++ b/level_2/fll_program/c/program.c
@@ -238,7 +238,7 @@ extern "C" {
     f_string_length start = destination->used;
 
     for (f_string_length i = 0; i < additional.used; i++) {
-      length = strnlen(argv[additional.array[i]], f_console_max_size);
+      length = strnlen(argv[additional.array[i]], f_console_length_size);
 
       if (length > 0) {
         f_string_dynamic ripped = f_string_dynamic_initialize;
@@ -285,7 +285,7 @@ extern "C" {
     f_string_length start = destination->used;
 
     for (f_string_length i = 0; i < additional.used; i++) {
-      length = strnlen(argv[additional.array[i]], f_console_max_size);
+      length = strnlen(argv[additional.array[i]], f_console_length_size);
 
       if (length > 0) {
         status = fl_string_mash(glue, glue_length, argv[additional.array[i]], length, destination);
@@ -314,7 +314,7 @@ extern "C" {
     f_string_length start = destination->used;
 
     for (f_string_length i = 0; i < additional.used; i++) {
-      length = strnlen(argv[additional.array[i]], f_console_max_size);
+      length = strnlen(argv[additional.array[i]], f_console_length_size);
 
       if (length > 0) {
         f_string_dynamic ripped = f_string_dynamic_initialize;
@@ -362,7 +362,7 @@ extern "C" {
     f_string_dynamic ripped = f_string_dynamic_initialize;
 
     for (f_string_length i = 0; i < additional.used; i++) {
-      length = strnlen(argv[additional.array[i]], f_console_max_size);
+      length = strnlen(argv[additional.array[i]], f_console_length_size);
 
       if (length > 0) {
         status = fl_string_rip(argv[additional.array[i]], length, &ripped);
diff --git a/level_2/fll_program/c/program.h b/level_2/fll_program/c/program.h
index 5494f44..8c390a1 100644
--- a/level_2/fll_program/c/program.h
+++ b/level_2/fll_program/c/program.h
@@ -231,7 +231,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if nothing to rip, no allocations or reallocations are performed.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
@@ -283,7 +283,7 @@ extern "C" {
  * @return
  *   f_none on success.
  *   f_no_data if nothing to rip, no allocations or reallocations are performed.
- *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_string_length_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
  *   f_error_reallocation (with error bit) on memory reallocation error.
diff --git a/level_3/firewall/data/build/settings b/level_3/firewall/data/build/settings
index 056c458..c824b5a 100644
--- a/level_3/firewall/data/build/settings
+++ b/level_3/firewall/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_console -lfl_color -lf_file -lf_utf -lf_print -lf_pipe -lf_directory -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_console -lfl_color -lf_file -lf_utf -lf_print -lf_pipe -lf_path -lf_directory -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library firewall.c private-firewall.c
diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c
index 2f9af8b..5e93978 100644
--- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c
+++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c
@@ -175,7 +175,7 @@ extern "C" {
             if (status_code == f_error_allocation || status_code == f_error_reallocation) {
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory.");
             }
-            else if (status_code == f_string_max_size) {
+            else if (status_code == f_string_length_size) {
               fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to process '");
               fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_trim);
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' because the maximum buffer size was reached.");
diff --git a/level_3/fss_basic_list_read/data/build/settings b/level_3/fss_basic_list_read/data/build/settings
index 792b21f..d741f4e 100644
--- a/level_3/fss_basic_list_read/data/build/settings
+++ b/level_3/fss_basic_list_read/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_list_read.c private-fss_basic_list_read.c
diff --git a/level_3/fss_basic_list_write/data/build/settings b/level_3/fss_basic_list_write/data/build/settings
index 0113ee4..d11305e 100644
--- a/level_3/fss_basic_list_write/data/build/settings
+++ b/level_3/fss_basic_list_write/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lfl_color -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lfl_color -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_list_write.c
diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-fss_basic_read.c
index 66610a3..c824663 100644
--- a/level_3/fss_basic_read/c/private-fss_basic_read.c
+++ b/level_3/fss_basic_read/c/private-fss_basic_read.c
@@ -175,7 +175,7 @@ extern "C" {
             if (status_code == f_error_allocation || status_code == f_error_reallocation) {
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory.");
             }
-            else if (status_code == f_string_max_size) {
+            else if (status_code == f_string_length_size) {
               fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to process '");
               fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_trim);
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' because the maximum buffer size was reached.");
diff --git a/level_3/fss_basic_read/data/build/settings b/level_3/fss_basic_read/data/build/settings
index fa1a568..2b1825e 100644
--- a/level_3/fss_basic_read/data/build/settings
+++ b/level_3/fss_basic_read/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_read.c private-fss_basic_read.c
diff --git a/level_3/fss_basic_write/data/build/settings b/level_3/fss_basic_write/data/build/settings
index edf47ab..b13e264 100644
--- a/level_3/fss_basic_write/data/build/settings
+++ b/level_3/fss_basic_write/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lfl_color -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lfl_color -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_write.c
diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c
index bc50bcd..2dba501 100644
--- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c
+++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c
@@ -175,7 +175,7 @@ extern "C" {
             if (status_code == f_error_allocation || status_code == f_error_reallocation) {
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory.");
             }
-            else if (status_code == f_string_max_size) {
+            else if (status_code == f_string_length_size) {
               fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to process '");
               fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_trim);
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' because the maximum buffer size was reached.");
diff --git a/level_3/fss_extended_list_read/data/build/settings b/level_3/fss_extended_list_read/data/build/settings
index 1dad99f..912fa86 100644
--- a/level_3/fss_extended_list_read/data/build/settings
+++ b/level_3/fss_extended_list_read/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_extended_list_read.c private-fss_extended_list_read.c
diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-fss_extended_read.c
index 0149f38..2b2166f 100644
--- a/level_3/fss_extended_read/c/private-fss_extended_read.c
+++ b/level_3/fss_extended_read/c/private-fss_extended_read.c
@@ -175,7 +175,7 @@ extern "C" {
             if (status_code == f_error_allocation || status_code == f_error_reallocation) {
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory.");
             }
-            else if (status_code == f_string_max_size) {
+            else if (status_code == f_string_length_size) {
               fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to process '");
               fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_trim);
               fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' because the maximum buffer size was reached.");
diff --git a/level_3/fss_extended_read/data/build/settings b/level_3/fss_extended_read/data/build/settings
index bf9b43c..e2687c5 100644
--- a/level_3/fss_extended_read/data/build/settings
+++ b/level_3/fss_extended_read/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_color -lfl_console -lf_conversion -lfl_directory -lfl_file -lfl_fss -lfl_print -lfl_status -lfl_string -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_extended_read.c private-fss_extended_read.c
diff --git a/level_3/fss_extended_write/data/build/settings b/level_3/fss_extended_write/data/build/settings
index c55032e..d906f7c 100644
--- a/level_3/fss_extended_write/data/build/settings
+++ b/level_3/fss_extended_write/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_color -lf_utf -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_color -lf_utf -lf_file -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_extended_write.c
diff --git a/level_3/fss_status_code/data/build/settings b/level_3/fss_status_code/data/build/settings
index adacf39..2b18744 100644
--- a/level_3/fss_status_code/data/build/settings
+++ b/level_3/fss_status_code/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfll_status -lfl_utf -lfl_string -lfl_status -lfl_fss -lfl_file -lfl_directory -lfl_console -lfl_color -lf_utf -lf_print -lf_pipe -lf_file -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_file -lfll_fss -lfll_execute -lfll_status -lfl_utf -lfl_string -lfl_status -lfl_fss -lfl_file -lfl_directory -lfl_console -lfl_color -lf_utf -lf_print -lf_pipe -lf_path -lf_file -lf_conversion -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library fss_status_code.c private-fss_status_code.c
diff --git a/level_3/init/c/init.h b/level_3/init/c/init.h
index d855ba0..f724e8c 100644
--- a/level_3/init/c/init.h
+++ b/level_3/init/c/init.h
@@ -52,7 +52,6 @@
 #include <string.h>
 #include <dirent.h>
 #include <unistd.h>
-#include <linux/limits.h> // defines PATH_MAX
 #include <sys/mount.h>
 #include <sys/types.h>
 #include <regex.h>
diff --git a/level_3/init/data/build/settings b/level_3/init/data/build/settings
index 6153265..193a4e1 100644
--- a/level_3/init/data/build/settings
+++ b/level_3/init/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_program -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lfl_color -lf_file -lf_utf -lf_print -lf_pipe -lf_console -lf_memory
+build_libraries_fll -lfll_program -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lfl_color -lf_file -lf_utf -lf_print -lf_pipe -lf_path -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library init.c private-init.c
diff --git a/level_3/status_code/data/build/settings b/level_3/status_code/data/build/settings
index 6409f98..c95eac8 100644
--- a/level_3/status_code/data/build/settings
+++ b/level_3/status_code/data/build/settings
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_status -lfll_program -lfl_utf -lfl_string -lfl_status -lfl_file -lfl_console -lfl_color -lf_utf -lf_print -lf_pipe -lf_file -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_status -lfll_program -lfl_utf -lfl_string -lfl_status -lfl_file -lfl_console -lfl_color -lf_utf -lf_print -lf_pipe -lf_path -lf_file -lf_conversion -lf_console -lf_memory
 build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 build_libraries_fll-monolithic -lfll
 build_sources_library status_code.c private-status_code.c