Restructure the memory functions a little.
Add comments about realloc() potentially changing the pointer address.
A few of the thread type macros are missing semicolons.
Remove f_macro_thread_mutex_t_clear().
There are likely other thread types that cannot be set to 0, and they will be correct as I discover them.
Rename the thread condition block and unblock functions.
Add missing f_thread_detach() implementation.
The execute fnctio fll_execute_program() should use pid_t when returning a PID.
This is potentially different from int, so instead use a void * and cast to an int * or pid_t * as necessary.
*
* Will change all data to 0 prior to deallocation.
*
+ * The pointer address might be changed by realloc().
+ *
* @param old_length
* The total number of blocks representing the length to be resized from.
* @param new_length
*
* Will not change any of the data prior to deallocation.
*
+ * The pointer address might be changed by realloc().
+ *
* @param old_length
* The total number of blocks representing the length to be resized from.
* @param new_length
}
if (*pointer) {
- void *new_pointer = 0;
-
if (length_old) {
if (length_new < length_old) {
}
if (length_new) {
- new_pointer = realloc(*pointer, type_size * length_new);
- }
- else {
- free(*pointer);
+ void *new_pointer = realloc(*pointer, type_size * length_new);
- // assure that the pointer is always 0 after deallocation.
- *pointer = 0;
+ if (new_pointer) {
+ if (length_new > length_old) {
- return F_none;
- }
+ // uint8_t * is of a data size size of 1, casting it to bool should result in a single-length increment.
+ // this is done to avoid problems with (void *) having arithmetic issues.
+ memset(((uint8_t *) new_pointer) + (type_size * length_old), 0, type_size * (length_new - length_old));
+ }
- if (new_pointer) {
- if (length_new > length_old) {
+ if (pointer != new_pointer) {
+ *pointer = new_pointer;
+ }
- // uint8_t * is of a data size size of 1, casting it to bool should result in a single-length increment.
- // this is done to avoid problems with (void *) having arithmetic issues.
- memset(((uint8_t *) new_pointer) + (type_size * length_old), 0, type_size * (length_new - length_old));
+ return F_none;
}
+ }
+ else {
+ free(*pointer);
- *pointer = new_pointer;
+ // assure that the pointer is always 0 after deallocation.
+ *pointer = 0;
return F_none;
}
}
if (*pointer) {
- void *new_pointer = 0;
-
if (length_new) {
- new_pointer = realloc(*pointer, type_size * length_new);
- }
- else {
- free(*pointer);
+ void *new_pointer = realloc(*pointer, type_size * length_new);
- // assure that the pointer is always 0 after deallocation.
- *pointer = 0;
+ if (new_pointer) {
+ if (length_new > length_old) {
- return F_none;
- }
+ // uint8_t * is of a data size size of 1, casting it to bool should result in a single-length increment.
+ // this is done to avoid problems with (void *) having arithmetic issues.
+ memset(((uint8_t *) new_pointer) + (type_size * length_old), 0, type_size * (length_new - length_old));
+ }
- if (new_pointer) {
- if (length_new > length_old) {
+ if (pointer != new_pointer) {
+ *pointer = new_pointer;
+ }
- // uint8_t * is of a data size size of 1, casting it to bool should result in a single-length increment.
- // this is done to avoid problems with (void *) having arithmetic issues.
- memset(((uint8_t *) new_pointer) + (type_size * length_old), 0, type_size * (length_new - length_old));
+ return F_none;
}
+ }
+ else {
+ free(*pointer);
- *pointer = new_pointer;
+ // assure that the pointer is always 0 after deallocation.
+ *pointer = 0;
return F_none;
}
#define f_thread_attribute_t_initialize { 0 }
// This does not clear the thread.attributes.__size array (may need to memset() against a sizeof(pthread_attr_t)).
- #define f_macro_thread_attribute_t_clear(attribute) attribute.__align = 0
+ #define f_macro_thread_attribute_t_clear(attribute) attribute.__align = 0;
#define f_macro_thread_attribute_t_delete_simple(attribute) f_thread_attribute_delete(&attribute);
#endif // _di_f_thread_attribute_t_
#define f_thread_barrier_t_initialize { 0 }
- #define f_macro_thread_barrier_t_clear(barrier) barrier = 0
+ #define f_macro_thread_barrier_t_clear(barrier) barrier = 0;
#define f_macro_thread_barrier_t_delete_simple(barrier) f_thread_barrier_delete(&barrier);
#endif // _di_f_thread_barrier_t_
#define f_thread_barrier_attribute_t_initialize { 0 }
- #define f_macro_thread_barrier_attribute_t_clear(barrier_attribute) barrier_attribute = 0
+ #define f_macro_thread_barrier_attribute_t_clear(barrier_attribute) barrier_attribute = 0;
#define f_macro_thread_barrier_attribute_t_delete_simple(barrier_attribute) f_thread_barrier_attribute_delete(&barrier_attribute);
#endif // _di_f_thread_barrier_attribute_t_
#define f_thread_condition_t_initialize PTHREAD_COND_INITIALIZER;
- #define f_macro_thread_condition_t_clear(condition) condition = 0
+ #define f_macro_thread_condition_t_clear(condition) condition = 0;
#define f_macro_thread_condition_t_delete_simple(condition) f_thread_condition_delete(&condition);
#endif // _di_f_thread_condition_t_
#define f_thread_condition_attribute_t_initialize 0;
- #define f_macro_thread_condition_attribute_t_clear(attribute) attribute = 0
+ #define f_macro_thread_condition_attribute_t_clear(attribute) attribute = 0;
#define f_macro_thread_condition_attribute_t_delete_simple(attribute) f_thread_condition_attribute_delete(&attribute);
#endif // _di_f_thread_condition_attribute_t_
#define f_thread_key_t_initialize 0
- #define f_macro_thread_key_t_clear(key) key = 0
+ #define f_macro_thread_key_t_clear(key) key = 0;
#define f_macro_thread_key_t_delete_simple(key) f_thread_key_delete(&key);
#endif // _di_f_thread_key_t_
#define f_thread_lock_t_initialize 0
- #define f_macro_thread_lock_t_clear(lock) lock = 0
+ #define f_macro_thread_lock_t_clear(lock) lock = 0;
#endif // _di_f_thread_lock_t_
/**
#define f_thread_lock_attribute_t_initialize 0
- #define f_macro_thread_lock_attribute_t_clear(attribute) attribute = 0
+ #define f_macro_thread_lock_attribute_t_clear(attribute) attribute = 0;
#endif // _di_f_thread_lock_attribute_t_
/**
/**
* A typedef representing pthread_mutex_t.
+ *
+ * This variable cannot be cleared by setting value to 0, so there is no clear macro provided.
*/
#ifndef _di_f_thread_mutex_t_
typedef pthread_mutex_t f_thread_mutex_t;
#define f_thread_mutex_t_initialize PTHREAD_MUTEX_INITIALIZER
- #define f_macro_thread_mutex_t_clear(mutex) mutex = 0
-
#define f_macro_thread_mutex_t_delete_simple(mutex) f_thread_mutex_delete(&mutex);
#endif // _di_f_thread_mutex_t_
#define f_thread_mutex_attribute_t_initialize 0
- #define f_macro_thread_mutex_attribute_t_clear(mutex_attribute) mutex_attribute = 0
+ #define f_macro_thread_mutex_attribute_t_clear(mutex_attribute) mutex_attribute = 0;
#endif // _di_f_thread_mutex_attribute_t_
/**
#define f_thread_once_t_initialize 0
- #define f_macro_thread_once_t_clear(once) once = 0
+ #define f_macro_thread_once_t_clear(once) once = 0;
#endif // _di_f_thread_once_t_
/**
#define f_thread_spin_t_initialize PTHREAD_MUTEX_INITIALIZER
- #define f_macro_thread_spin_t_clear(spin) spin = 0
+ #define f_macro_thread_spin_t_clear(spin) spin = 0;
#define f_macro_thread_spin_t_delete_simple(spin) f_thread_spin_delete(&spin);
#endif // _di_f_thread_spin_t_
}
#endif // _di_f_thread_condition_delete_
-#ifndef _di_f_thread_condition_unblock_all_
- f_status_t f_thread_condition_unblock_all(f_thread_condition_t *condition) {
+#ifndef _di_f_thread_condition_signal_all_
+ f_status_t f_thread_condition_signal_all(f_thread_condition_t *condition) {
#ifndef _di_level_0_parameter_checking_
if (!condition) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
return F_none;
}
-#endif // _di_f_thread_condition_unblock_all_
+#endif // _di_f_thread_condition_signal_all_
-#ifndef _di_f_thread_condition_unblock_any_
- f_status_t f_thread_condition_unblock_any(f_thread_condition_t *condition) {
+#ifndef _di_f_thread_condition_signal_
+ f_status_t f_thread_condition_signal(f_thread_condition_t *condition) {
#ifndef _di_level_0_parameter_checking_
if (!condition) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
return F_none;
}
-#endif // _di_f_thread_condition_unblock_any_
+#endif // _di_f_thread_condition_signal_
#ifndef _di_f_thread_condition_wait_
f_status_t f_thread_condition_wait(f_thread_condition_t *condition, f_thread_mutex_t *mutex) {
}
#endif // _di_f_thread_create_
+#ifndef _di_f_thread_detach_
+ f_status_t f_thread_detach(const f_thread_id_t id) {
+
+ const int error = pthread_detach(id);
+
+ if (error) {
+ if (error == EINVAL) return F_status_set_error(F_parameter);
+ if (error == ESRCH) return F_status_set_error(F_found_not);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_thread_detach_
+
#ifndef _di_f_thread_exit_
f_status_t f_thread_exit(int *result) {
#ifndef _di_level_0_parameter_checking_
#endif // _di_f_thread_condition_delete_
/**
- * Unblock all threads waiting on a condition.
+ * Signal all threads waiting on a condition.
*
* @param condition
* The condition to broadcast the unblock signal to.
*
* @see pthread_cond_broadcast()
*/
-#ifndef _di_f_thread_condition_unblock_all_
- extern f_status_t f_thread_condition_unblock_all(f_thread_condition_t *condition);
-#endif // _di_f_thread_condition_unblock_all_
+#ifndef _di_f_thread_condition_signal_all_
+ extern f_status_t f_thread_condition_signal_all(f_thread_condition_t *condition);
+#endif // _di_f_thread_condition_signal_all_
/**
- * Unblock all threads waiting on a condition.
+ * Signal a thread waiting on a condition.
+ *
+ * Only a single thread waiting on this condition is signaled.
*
* @param condition
* The condition to broadcast the unblock signal to.
*
* @see pthread_cond_signal()
*/
-#ifndef _di_f_thread_condition_unblock_any_
- extern f_status_t f_thread_condition_unblock_any(f_thread_condition_t *condition);
-#endif // _di_f_thread_condition_unblock_any_
+#ifndef _di_f_thread_condition_signal_
+ extern f_status_t f_thread_condition_signal(f_thread_condition_t *condition);
+#endif // _di_f_thread_condition_signal_
/**
* Wait until condition is triggered.
* @return
* F_none on success.
*
- * F_deadlock (with error bit) if operation would cause a deadlock.ead.
* F_found_not (with error bit) if no thread by the given ID was found.
* F_parameter (with error bit) if a parameter is invalid.
- * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thr
*
*
* @see pthread_detach()
* F_deadlock (with error bit) if operation would cause a deadlock.ead.
* F_found_not (with error bit) if no thread by the given ID was found.
* F_parameter (with error bit) if a parameter is invalid.
- * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thr
+ * F_supported_not (with error bit) if the thread is not joinable or is already being joined by another thread.
*
*
* @see pthread_join()
#endif // _di_fll_execute_into_
#ifndef _di_fll_execute_program_
- f_status_t fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, int *result) {
+ f_status_t fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, void *result) {
#ifndef _di_level_2_parameter_checking_
if (!program && !arguments.used) return F_status_set_error(F_parameter);
if (!result) return F_status_set_error(F_parameter);
* @param arguments
* An array of strings representing the arguments.
* @param option
- * A bitwise set of options, such as: fl_execute_parameter_option_exit, and fl_execute_parameter_option_path.
+ * A bitwise set of options, such as: fl_execute_parameter_option_exit and fl_execute_parameter_option_path.
* If fl_execute_parameter_option_exit: this will call exit() at the end of execution (be it success or failure).
* If fl_execute_parameter_option_path: this is a program path (such as "/bin/bash"), otherwise this is a program (such as "bash").
* @param result
* @param result
* (optional) The code returned after finishing execution of program.
* When fl_execute_parameter_option_return is passed via parameter.option, then this instead stores the child process id (PID).
+ * This is should be of (int *) except when fl_execute_parameter_option_return this should instead be (pid_t *).
* Set to NULL to not use.
*
* @return
* @see fl_environment_path_explode_dynamic()
*/
#ifndef _di_fll_execute_program_
- extern f_status_t fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, int *result);
+ extern f_status_t fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, void *result);
#endif // _di_fll_execute_program_
#ifdef __cplusplus
#endif // !defined(_di_fll_execute_program_)
#if !defined(_di_fll_execute_program_)
- f_status_t private_fll_execute_fork(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, int *result) {
+ f_status_t private_fll_execute_fork(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, void *result) {
int descriptors[2] = { -1, -1 };
if (parameter && parameter->option & fl_execute_parameter_option_return) {
if (result != 0) {
- *result = id_process;
+ pid_t *r = (pid_t *) result;
+ *r = id_process;
}
return F_parent;
}
// have the parent wait for the child process to finish.
- waitpid(id_process, result, WUNTRACED | WCONTINUED);
+ waitpid(id_process, (int *) result, WUNTRACED | WCONTINUED);
// this must explicitly check for 0 (as opposed to checking (!result)).
if (result != 0) {
- if (WIFEXITED(*result)) {
+ if (WIFEXITED(*((int *) result))) {
return F_none;
}
close(descriptors[0]);
if (result) {
- *result = -1;
+ int *r = (int *) result;
+ *r = -1;
}
if (parameter && parameter->option & fl_execute_parameter_option_exit) {
// close the write pipe for the child when done.
close(descriptors[0]);
- const f_status_t status = private_fll_execute_as_child(*as, parameter, result);
+ const f_status_t status = private_fll_execute_as_child(*as, parameter, (int *) result);
if (F_status_is_error(status)) {
return status;
const int code = parameter && (parameter->option & fl_execute_parameter_option_path) ? execv(program, fixed_arguments) : execvp(program, fixed_arguments);
if (result) {
- *result = code;
+ int *r = (int *) result;
+ *r = code;
}
if (parameter && parameter->option & fl_execute_parameter_option_exit) {
#endif // !defined(_di_fll_execute_program_)
#if !defined(_di_fll_execute_program_)
- f_status_t private_fll_execute_fork_data(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, int *result) {
+ f_status_t private_fll_execute_fork_data(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, void *result) {
int descriptors[2] = { -1, -1 };
if (parameter && parameter->option & fl_execute_parameter_option_return) {
if (result != 0) {
- *result = id_process;
+ pid_t *r = (pid_t *) result;
+ *r = id_process;
}
return F_parent;
}
// have the parent wait for the child process to finish.
- waitpid(id_process, result, WUNTRACED | WCONTINUED);
+ waitpid(id_process, (int *) result, WUNTRACED | WCONTINUED);
// this must explicitly check for 0 (as opposed to checking (!result)).
if (result != 0) {
- if (WIFEXITED(*result)) {
+ if (WIFEXITED(*((int *) result))) {
return F_none;
}
close(descriptors[0]);
if (result) {
- *result = -1;
+ int *r = (int *) result;
+ *r = -1;
}
if (parameter && parameter->option & fl_execute_parameter_option_exit) {
dup2(descriptors[0], f_type_descriptor_input);
if (as) {
- const f_status_t status = private_fll_execute_as_child(*as, parameter, result);
+ const f_status_t status = private_fll_execute_as_child(*as, parameter, (int *) result);
if (F_status_is_error(status)) {
return status;
close(descriptors[0]);
if (result) {
- *result = code;
+ int *r = (int *) result;
+ *r = code;
}
if (parameter && parameter->option & fl_execute_parameter_option_exit) {
* @param result
* (optional) The code returned after finishing execution of program.
* When fl_execute_parameter_option_return is passed via parameter.option, then this instead stores the child process id (PID).
+ * This is should be of (int *) except when fl_execute_parameter_option_return this should instead be (pid_t *).
* Set to NULL to not use.
*
* @return
* @see fll_execute_program()
*/
#if !defined(_di_fll_execute_program_)
- extern f_status_t private_fll_execute_fork(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, int *result) f_gcc_attribute_visibility_internal;
+ extern f_status_t private_fll_execute_fork(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, void *result) f_gcc_attribute_visibility_internal;
#endif // !defined(_di_fll_execute_program_)
/**
* @param result
* (optional) The code returned after finishing execution of program.
* When fl_execute_parameter_option_return is passed via parameter.option, then this instead stores the child process id (PID).
+ * This is should be of (int *) except when fl_execute_parameter_option_return this should instead be (pid_t *).
* Set to NULL to not use.
*
* @return
* @see fll_execute_program()
*/
#if !defined(_di_fll_execute_program_)
- extern f_status_t private_fll_execute_fork_data(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, int *result) f_gcc_attribute_visibility_internal;
+ extern f_status_t private_fll_execute_fork_data(const f_string_t program, const f_string_t fixed_arguments[], fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, void *result) f_gcc_attribute_visibility_internal;
#endif // !defined(_di_fll_execute_program_)
/**
fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(fl_execute_parameter_option_path, &data_build.environment, &signals, 0);
- *status = fll_execute_program(path.string, arguments, ¶meter, 0, &return_code);
+ *status = fll_execute_program(path.string, arguments, ¶meter, 0, (void *) &return_code);
f_macro_string_dynamics_t_delete_simple(arguments);
fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, &environment, &signals, 0);
- *status = fll_execute_program(program.string, arguments, ¶meter, 0, &return_code);
+ *status = fll_execute_program(program.string, arguments, ¶meter, 0, (void *) &return_code);
if (fake_signal_received(data)) {
*status = F_status_set_error(F_signal);
fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(as_shell ? 0 : fl_execute_parameter_option_path, &data_make->environment, &signals, 0);
- status = fll_execute_program(program.string, arguments, ¶meter, 0, &return_code);
+ status = fll_execute_program(program.string, arguments, ¶meter, 0, (void *) &return_code);
if (status == F_status_set_error(F_signal)) {
return status;
parameters.array[4].used = 9;
parameters.array[5].used = 6;
- status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, &return_code);
+ status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
parameters.array[4].used = 9;
parameters.array[5].used = 6;
- status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, &return_code);
+ status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
parameters.array[2].used = 9;
parameters.array[3].used = 6;
- status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, &return_code);
+ status = fll_execute_program((f_string_t) firewall_tool_iptables, parameters, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
fprintf(f_type_debug, "\n");
}
- status = fll_execute_program((f_string_t) current_tool, arguments, 0, 0, &return_code);
+ status = fll_execute_program((f_string_t) current_tool, arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
fprintf(f_type_debug, "\n");
}
- status = fll_execute_program(current_tool, arguments, 0, 0, &return_code);
+ status = fll_execute_program(current_tool, arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
}
tool = firewall_program_iptables;
- status = fll_execute_program((f_string_t) firewall_tool_iptables, arguments, 0, 0, &return_code);
+ status = fll_execute_program((f_string_t) firewall_tool_iptables, arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
}
tool = firewall_program_ip6tables;
- status = fll_execute_program((f_string_t) firewall_tool_ip6tables, arguments, 0, 0, &return_code);
+ status = fll_execute_program((f_string_t) firewall_tool_ip6tables, arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
fprintf(f_type_debug, "\n");
}
- status = fll_execute_program(tools[i], arguments, 0, 0, &return_code);
+ status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
fprintf(f_type_debug, "\n");
}
- status = fll_execute_program(tools[i], arguments, 0, 0, &return_code);
+ status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {
fprintf(f_type_debug, "\n");
}
- status = fll_execute_program(tools[j], arguments, 0, 0, &return_code);
+ status = fll_execute_program(tools[j], arguments, 0, 0, (void *) &return_code);
// immediately exit child process, @todo this may require additional memory deallocation and relating changes.
if (status == F_child) {