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.
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
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
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) {
/**
* 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.
* 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".
*
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;
}
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;
}
#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;
}
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);
}
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) {
#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.
#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
#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
* 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);
--- /dev/null
+#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
#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" {
* 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
+f_type
+f_status
+f_memory
+f_string
+f_utf
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
#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)
// 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
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);
}
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);
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);
#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
#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;
#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;
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;
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;
#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;
#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;
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;
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;
*
* @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.
*
* @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.
*
* @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.
*
* @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.
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;
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
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);
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);
// 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);
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;
}
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);
// 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);
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);
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;
}
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)) {
// 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++) {
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;
}
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)) {
// 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++) {
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);
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;
}
#define _FLL_execute_h
// libc includes
-#include <linux/limits.h> // defines PATH_MAX
#include <memory.h>
#include <signal.h>
#include <string.h>
#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>
* 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);
* 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);
* 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);
* 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);
* 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);
* 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);
* 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);
* 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);
/**
* 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
* 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()
*/
/**
* 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
* @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.
*
* 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()
*/
/**
* 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
* 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()
*/
*
* 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.
* 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()
*/
#define _PRIVATE_FLL_execute_h
// libc includes
-#include <linux/limits.h> // defines PATH_MAX
#include <memory.h>
#include <signal.h>
#include <string.h>
* 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()
* 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()
f_memory
f_string
f_environment
+f_file
+f_path
fl_string
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
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);
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;
* 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);
* 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);
* 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);
* 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);
* 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);
* 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);
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);
}
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);
}
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);
}
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);
}
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;
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);
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;
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);
* @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.
* @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.
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
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.");
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
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
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.");
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
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
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.");
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
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.");
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
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
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
#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>
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
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