Create a socket set and move all associated arrays into it.
This allows for a receive and a send socket set to keep all of the associated properties together.
Move a lot of the processing functionality into its own functions and reduce some of the redundancy.
kt_tacocat_long_send_s,
};
- f_files_t * const files[] = {
- &main->setting.file_receives,
- &main->setting.file_sends,
- };
-
- f_sockets_t * const sockets[] = {
- &main->setting.socket_receives,
- &main->setting.socket_sends,
- };
-
- f_statuss_t * const statuss[] = {
- &main->setting.status_receives,
- &main->setting.status_sends,
- };
-
- f_string_dynamics_t * const strings[] = {
- &main->setting.receives,
- &main->setting.sends,
+ kt_tacocat_socket_set_t * const sets[] = {
+ &main->setting.receive,
+ &main->setting.send,
};
const bool const is_receive[] = {
continue;
}
- strings[i]->used = 0;
+ sets[i]->names.used = 0;
+ sets[i]->buffers.used = 0;
- main->setting.state.status = f_string_dynamics_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, strings[i]);
+ main->setting.state.status = f_string_dynamics_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, &sets[i]->names);
macro_setting_load_handle_send_receive_error_continue_1(f_string_dynamics_increase_by);
- main->setting.state.status = f_files_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, files[i]);
+ main->setting.state.status = f_string_dynamics_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, &sets[i]->buffers);
+
+ macro_setting_load_handle_send_receive_error_continue_1(f_string_dynamics_increase_by);
+
+ main->setting.state.status = f_files_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, &sets[i]->files);
macro_setting_load_handle_send_receive_error_continue_1(f_files_increase_by);
- main->setting.state.status = f_sockets_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, sockets[i]);
+ main->setting.state.status = f_sockets_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, &sets[i]->sockets);
macro_setting_load_handle_send_receive_error_continue_1(f_sockets_increase_by);
- main->setting.state.status = f_statuss_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, statuss[i]);
+ main->setting.state.status = f_statuss_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, &sets[i]->statuss);
macro_setting_load_handle_send_receive_error_continue_1(f_statuss_increase_by);
// First parameter value represents the network address or the socket file path.
index = main->program.parameters.array[parameters[i]].values.array[j];
- statuss[i]->array[j] = F_none;
- strings[i]->array[j].used = 0;
+ sets[i]->statuss.array[j] = F_none;
+ sets[i]->names.array[j].used = 0;
+ sets[i]->buffers.array[j].used = 0;
if (main->program.parameters.arguments.array[index].used) {
if (f_path_is_absolute(main->program.parameters.arguments.array[index]) == F_true || f_path_is_relative_current(main->program.parameters.arguments.array[index]) == F_true) {
- main->setting.state.status = f_string_dynamic_increase_by(main->program.parameters.arguments.array[index].used + 2, &strings[i]->array[j]);
+ main->setting.state.status = f_string_dynamic_increase_by(main->program.parameters.arguments.array[index].used + 2, &sets[i]->names.array[j]);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_increase_by);
- main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &strings[i]->array[j]);
+ main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &sets[i]->names.array[j]);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless);
// Designate this as a socket file by appending after the terminating NULL, past the used length.
- strings[i]->array[j].string[strings[i]->array[j].used] = 0;
- strings[i]->array[j].string[strings[i]->array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
+ sets[i]->names.array[j].string[sets[i]->names.array[j].used] = 0;
+ sets[i]->names.array[j].string[sets[i]->names.array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
if (is_receive[i]) {
- main->setting.state.status = f_file_exists(strings[i]->array[j], F_true);
+ main->setting.state.status = f_file_exists(sets[i]->names.array[j], F_true);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless);
}
- strings[i]->array[j].string[strings[i]->array[j].used] = 0;
- sockets[i]->array[j].domain = f_socket_protocol_family_local_e;
- sockets[i]->array[j].protocol = f_socket_protocol_tcp_e;
- sockets[i]->array[j].type = f_socket_address_family_local_e;
- sockets[i]->array[j].name = strings[i]->array[j];
+ sets[i]->names.array[j].string[sets[i]->names.array[j].used] = 0;
+ sets[i]->sockets.array[j].domain = f_socket_protocol_family_local_e;
+ sets[i]->sockets.array[j].protocol = f_socket_protocol_tcp_e;
+ sets[i]->sockets.array[j].type = f_socket_address_family_local_e;
+ sets[i]->sockets.array[j].name = sets[i]->names.array[j];
}
else if (main->setting.flag & kt_tacocat_main_flag_resolve_classic_e) {
memset(&host, 0, sizeof(struct hostent));
}
if (host.h_addrtype) {
- main->setting.state.status = f_string_dynamic_append(address, &strings[i]->array[j]);
+ main->setting.state.status = f_string_dynamic_append(address, &sets[i]->names.array[j]);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append);
}
failed = main->setting.state.status;
}
- statuss[i]->array[j] = main->setting.state.status;
+ sets[i]->statuss.array[j] = main->setting.state.status;
continue;
}
- main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &strings[i]->array[j]);
+ main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &sets[i]->names.array[j]);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_increase_by);
k = 0;
}
- main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &strings[i]->array[j]);
+ main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &sets[i]->names.array[j]);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_increase_by);
family.address.v6 = *((struct in6_addr *) host.h_addr_list[k]);
}
- main->setting.state.status = f_network_to_ip_string(family, &strings[i]->array[j]);
+ main->setting.state.status = f_network_to_ip_string(family, &sets[i]->names.array[j]);
if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) {
main->setting.state.status = F_status_set_error(F_parameter);
failed = main->setting.state.status;
}
- statuss[i]->array[j] = main->setting.state.status;
+ sets[i]->statuss.array[j] = main->setting.state.status;
continue;
}
- strings[i]->array[j].string[strings[i]->array[j].used] = 0;
+ sets[i]->names.array[j].string[sets[i]->names.array[j].used] = 0;
}
- sockets[i]->array[j].protocol = f_socket_protocol_tcp_e;
- sockets[i]->array[j].type = host.h_addrtype;
+ sets[i]->sockets.array[j].protocol = f_socket_protocol_tcp_e;
+ sets[i]->sockets.array[j].type = host.h_addrtype;
if (host.h_addrtype == f_socket_address_family_inet4_e) {
- sockets[i]->array[j].domain = f_socket_protocol_family_inet4_e;
- sockets[i]->array[j].address.inet4.sin_port = (in_port_t) port;
- sockets[i]->array[j].address.inet4.sin_addr.s_addr = INADDR_ANY;
+ sets[i]->sockets.array[j].domain = f_socket_protocol_family_inet4_e;
+ sets[i]->sockets.array[j].address.inet4.sin_port = (in_port_t) port;
+ sets[i]->sockets.array[j].address.inet4.sin_addr.s_addr = INADDR_ANY;
}
else if (host.h_addrtype == f_socket_address_family_inet6_e) {
- sockets[i]->array[j].domain = f_socket_protocol_family_inet6_e;
- sockets[i]->array[j].address.inet6.sin6_port = (in_port_t) port;
- sockets[i]->array[j].address.inet6.sin6_addr = in6addr_any;
+ sets[i]->sockets.array[j].domain = f_socket_protocol_family_inet6_e;
+ sets[i]->sockets.array[j].address.inet6.sin6_port = (in_port_t) port;
+ sets[i]->sockets.array[j].address.inet6.sin6_addr = in6addr_any;
}
}
else {
// @todo Kevux DNS resolution.
}
- ++files[i]->used;
- ++sockets[i]->used;
- ++statuss[i]->used;
- ++strings[i]->used;
+ ++sets[i]->files.used;
+ ++sets[i]->sockets.used;
+ ++sets[i]->statuss.used;
+ ++sets[i]->names.used;
+ ++sets[i]->buffers.used;
}
else {
main->setting.state.status = F_status_set_error(F_parameter);
failed = main->setting.state.status;
}
- statuss[i]->array[j] = main->setting.state.status;
+ sets[i]->statuss.array[j] = main->setting.state.status;
continue;
}
if (main->program.parameters.arguments.array[index].used) {
// Make sure the current file is closed.
- f_file_close(&files[i]->array[j]);
+ f_file_close(&sets[i]->files.array[j]);
- if (is_receive[i]) {
- files[i]->array[j].flag = F_file_flag_append_wo_d;
- files[i]->array[j].size_read = main->setting.block_size_send;
- files[i]->array[j].size_write = main->setting.block_size_send;
- }
- else {
- files[i]->array[j].flag = F_file_flag_read_only_d;
- files[i]->array[j].size_read = main->setting.block_size_receive;
- files[i]->array[j].size_write = main->setting.block_size_receive;
- }
+ sets[i]->files.array[j].flag = is_receive[i] ? F_file_flag_append_wo_d : F_file_flag_read_only_d;
+ sets[i]->files.array[j].size_read = sets[i]->block_size;
+ sets[i]->files.array[j].size_write = sets[i]->block_size;
- main->setting.state.status = f_file_open(main->program.parameters.arguments.array[index], F_file_mode_all_rw_d, &files[i]->array[j]);
+ main->setting.state.status = f_file_open(main->program.parameters.arguments.array[index], F_file_mode_all_rw_d, &sets[i]->files.array[j]);
if (F_status_is_error(main->setting.state.status)) {
macro_setting_load_handle_send_receive_error_file_continue_1(f_file_open, main->program.parameters.arguments.array[index], f_file_operation_open_s, fll_error_file_type_file_e);
failed = main->setting.state.status;
}
- statuss[i]->array[j] = main->setting.state.status;
+ sets[i]->statuss.array[j] = main->setting.state.status;
}
}
else {
failed = main->setting.state.status;
}
- statuss[i]->array[j] = main->setting.state.status;
+ sets[i]->statuss.array[j] = main->setting.state.status;
continue;
}
* @param main
* The main program and settings data.
*
- * This alters setting.status:
+ * This alters setting.state.status:
* F_none on success.
*
* F_parameter (with error bit) on parameter error.
* kt_tacocat_backlog_*_d:
* - max: The max backlog size to use.
*
- * kt_tacocat_block_size_*_d:
- * - receive: The block size in bytes to use when sending packets.
- * - send: The block size in bytes to use when receiving packets.
+ * kt_tacocat_block_*_d:
+ * - size: The block size in bytes to use for either sending or receiving.
+ * - size_receive: The block size in bytes to use when sending packets.
+ * - size_send: The block size in bytes to use when receiving packets.
*
* kt_tacocat_signal_*_d:
* - check: When not using threads, this is how often to perform the check (lower numbers incur more kernel I/O).
#define kt_tacocat_backlog_max_d 1024
- #define kt_tacocat_block_size_receive_d 65535
- #define kt_tacocat_block_size_send_d 65535
+ #define kt_tacocat_block_size_d 65535
+ #define kt_tacocat_block_size_receive_d kt_tacocat_block_size_d
+ #define kt_tacocat_block_size_send_d kt_tacocat_block_size_d
#define kt_tacocat_signal_check_d 20000
#define kt_tacocat_signal_check_failsafe_d 20000
failed = main->setting.state.status; \
} \
\
- statuss[i]->array[j] = main->setting.state.status; \
+ sets[i]->statuss.array[j] = main->setting.state.status; \
\
continue; \
}
failed = main->setting.state.status; \
} \
\
- statuss[i]->array[j] = main->setting.state.status; \
+ sets[i]->statuss.array[j] = main->setting.state.status; \
\
continue; \
}
"f_thread_create",
"fll_program_parameter_process_context",
"fll_program_parameter_process_verbosity",
+ "kt_tacocat_process_socket_set_error_has",
"kt_tacocat_setting_load_address_port_extract",
};
#endif // _di_kt_tacocat_f_a_
kt_tacocat_f_f_thread_create_e,
kt_tacocat_f_fll_program_parameter_process_context_e,
kt_tacocat_f_fll_program_parameter_process_verbosity_e,
+ kt_tacocat_f_kt_tacocat_process_socket_set_error_has_e,
kt_tacocat_f_kt_tacocat_setting_load_address_port_extract_e,
}; // enum
#endif // _di_kt_tacocat_f_e_
* The main program parameters.
*/
#ifndef _di_kt_tacocat_parameter_s_
- #define KT_TACOCAT_short_receive_s "r"
- #define KT_TACOCAT_short_resolve_s "R"
- #define KT_TACOCAT_short_send_s "s"
+ #define KT_TACOCAT_short_receive_s "r"
+ #define KT_TACOCAT_short_resolve_s "R"
+ #define KT_TACOCAT_short_send_s "s"
- #define KT_TACOCAT_long_receive_s "receive"
- #define KT_TACOCAT_long_resolve_s "resolve"
- #define KT_TACOCAT_long_send_s "send"
+ #define KT_TACOCAT_long_receive_s "receive"
+ #define KT_TACOCAT_long_resolve_s "resolve"
+ #define KT_TACOCAT_long_send_s "send"
- #define KT_TACOCAT_short_receive_s_length 1
- #define KT_TACOCAT_short_resolve_s_length 1
- #define KT_TACOCAT_short_send_s_length 1
+ #define KT_TACOCAT_short_receive_s_length 1
+ #define KT_TACOCAT_short_resolve_s_length 1
+ #define KT_TACOCAT_short_send_s_length 1
- #define KT_TACOCAT_long_receive_s_length 7
- #define KT_TACOCAT_long_resolve_s_length 7
- #define KT_TACOCAT_long_send_s_length 4
+ #define KT_TACOCAT_long_receive_s_length 7
+ #define KT_TACOCAT_long_resolve_s_length 7
+ #define KT_TACOCAT_long_send_s_length 4
extern const f_string_static_t kt_tacocat_short_receive_s;
extern const f_string_static_t kt_tacocat_short_resolve_s;
if (!setting) return F_status_set_error(F_parameter);
- f_number_unsigned_t i = 0;
+ {
+ f_number_unsigned_t j = 0;
- for (; i < setting->file_receives.used ; ++i) {
- f_file_close(&setting->file_receives.array[i]);
- } // for
+ kt_tacocat_socket_set_t * const sets[] = {
+ &setting->receive,
+ &setting->send,
+ };
- for (; i < setting->file_sends.used ; ++i) {
- f_file_close(&setting->file_sends.array[i]);
- } // for
+ for (uint8_t i = 0; i < 2; ++i) {
- for (; i < setting->socket_receives.used ; ++i) {
- f_socket_disconnect(&setting->socket_receives.array[i], program.signal_received ? f_socket_close_fast_e : f_socket_close_read_write_e);
- } // for
+ for (; j < sets[i]->files.used ; ++j) {
+ f_file_close(&sets[i]->files.array[j]);
+ } // for
- for (; i < setting->socket_sends.used ; ++i) {
- f_socket_disconnect(&setting->socket_sends.array[i], program.signal_received ? f_socket_close_fast_e : f_socket_close_read_write_e);
- } // for
+ for (; j < sets[i]->sockets.used ; ++j) {
+ f_socket_disconnect(&sets[i]->sockets.array[j], program.signal_received ? f_socket_close_fast_e : f_socket_close_read_write_e);
+ } // for
- f_files_resize(0, &setting->file_receives);
- f_files_resize(0, &setting->file_sends);
+ f_files_resize(0, &sets[i]->files);
+ f_sockets_resize(0, &sets[i]->sockets);
+ f_statuss_resize(0, &sets[i]->statuss);
- f_sockets_resize(0, &setting->socket_receives);
- f_sockets_resize(0, &setting->socket_sends);
-
- f_statuss_resize(0, &setting->status_receives);
- f_statuss_resize(0, &setting->status_sends);
-
- f_string_dynamics_resize(0, &setting->receives);
- f_string_dynamics_resize(0, &setting->sends);
+ f_string_dynamics_resize(0, &sets[i]->names);
+ f_string_dynamics_resize(0, &sets[i]->buffers);
+ } // for
+ }
f_string_dynamic_resize(0, &setting->buffer);
#endif
/**
+ * A set containing all socket related data sets.
+ *
+ * block_size: The size in bytes to used to represent a block when sending or receiving packets.
+ *
+ * files: An array of files for each socket.
+ * sockets: An array of the network sockets.
+ * statuss: An array of statuses for each socket.
+ * names: An array of names for each socket.
+ * buffers: An array of buffers for sending or receiving data between clients for each socket.
+ */
+#ifndef _di_kt_tacocat_socket_set_t_
+ typedef struct {
+ f_number_unsigned_t block_size;
+
+ f_files_t files;
+ f_sockets_t sockets;
+ f_statuss_t statuss;
+ f_string_dynamics_t names;
+ f_string_dynamics_t buffers;
+ } kt_tacocat_socket_set_t;
+
+ #define kt_tacocat_socket_set_t_initialize \
+ { \
+ kt_tacocat_block_size_d, \
+ f_files_t_initialize, \
+ f_sockets_t_initialize, \
+ f_statuss_t_initialize, \
+ f_string_dynamics_t_initialize, \
+ f_string_dynamics_t_initialize, \
+ }
+
+ #define macro_kt_tacocat_setting_t_initialize_1(block_size) \
+ { \
+ block_size, \
+ f_files_t_initialize, \
+ f_sockets_t_initialize, \
+ f_statuss_t_initialize, \
+ f_string_dynamics_t_initialize, \
+ f_string_dynamics_t_initialize, \
+ }
+#endif // _di_kt_tacocat_socket_set_t_
+
+/**
* The main program settings.
*
* This is passed to the program-specific main entry point to designate program settings.
*
* flag: Flags passed to the main function.
*
- * block_size_receive: The size in bytes to used to represent a block when receiving packets.
- * block_size_send: The size in bytes to used to represent a block when sending packets.
- *
* status_thread: A status used eclusively by the threaded signal handler.
* state: The state data used when processing data.
*
- * file_receives: An array of files for receiving.
- * file_sends: An array of files for sending.
- *
- * socket_receives: An array of the network sockets for receiving.
- * socket_sends: An array of the network sockets for sending.
- *
- * status_receives: An array of statuses for receiving.
- * status_sends: An array of statuses for sending.
- *
- * receives: An array of buffers for receiving data receive clients.
- * sends: An array of buffers for sending data send clients.
+ * receive: The socket set for receiving data receive clients.
+ * send: The socket set for sending data send clients.
*
* buffer: A string buffer used for caching purposes.
*/
typedef struct {
uint64_t flag;
- f_number_unsigned_t block_size_receive;
- f_number_unsigned_t block_size_send;
-
f_status_t status_thread;
f_state_t state;
- f_files_t file_receives;
- f_files_t file_sends;
-
- f_sockets_t socket_receives;
- f_sockets_t socket_sends;
-
- f_statuss_t status_receives;
- f_statuss_t status_sends;
-
- f_string_dynamics_t receives;
- f_string_dynamics_t sends;
+ kt_tacocat_socket_set_t receive;
+ kt_tacocat_socket_set_t send;
f_string_dynamic_t buffer;
} kt_tacocat_setting_t;
#define kt_tacocat_setting_t_initialize \
{ \
kt_tacocat_main_flag_none_e, \
- kt_tacocat_block_size_receive_d, \
- kt_tacocat_block_size_send_d, \
F_none, \
macro_f_state_t_initialize_1(kt_tacocat_allocation_large_d, kt_tacocat_allocation_small_d, F_none, 0, 0, &fll_program_standard_signal_handle, 0, 0, 0, 0), \
- f_files_t_initialize, \
- f_files_t_initialize, \
- f_sockets_t_initialize, \
- f_sockets_t_initialize, \
- f_statuss_t_initialize, \
- f_statuss_t_initialize, \
- f_string_dynamics_t_initialize, \
- f_string_dynamics_t_initialize, \
+ macro_kt_tacocat_setting_t_initialize_1(kt_tacocat_block_size_receive_d), \
+ macro_kt_tacocat_setting_t_initialize_1(kt_tacocat_block_size_send_d), \
f_string_dynamic_t_initialize, \
}
#endif // _di_kt_tacocat_setting_t_
#endif // _di_kt_tacocat_print_error_parameter_value_resolve_unknown_
#ifndef _di_kt_tacocat_print_error_setting_socket_lengths_must_match_
- f_status_t kt_tacocat_print_error_setting_socket_lengths_must_match(fl_print_t * const print, const f_string_dynamic_t name, const f_number_unsigned_t names, const f_number_unsigned_t files, const f_number_unsigned_t sockets, const f_number_unsigned_t statuss) {
+ f_status_t kt_tacocat_print_error_setting_socket_lengths_must_match(fl_print_t * const print, const f_string_dynamic_t name, const kt_tacocat_socket_set_t set) {
if (!print || !print->custom) return F_status_set_error(F_output_not);
if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
fl_print_format("%[%QThe lengths of all%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format("%[%Q%]", print->to, print->set->notable, name, print->set->notable);
fl_print_format(" %[arrays do not have the same length, name array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
- fl_print_format("%[%ul%]", print->to, print->set->notable, names, print->set->notable);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, set.names.used, print->set->notable);
+ fl_print_format("%', the buffer array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, set.buffers.used, print->set->notable);
fl_print_format("%', the file array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
- fl_print_format("%[%ul%]", print->to, print->set->notable, files, print->set->notable);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, set.files.used, print->set->notable);
fl_print_format(" %[', the socket array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
- fl_print_format("%[%ul%]", print->to, print->set->notable, sockets, print->set->notable);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, set.sockets.used, print->set->notable);
fl_print_format(" %[', and the status array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
- fl_print_format("%[%ul%]", print->to, print->set->notable, statuss, print->set->notable);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, set.statuss.used, print->set->notable);
fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
f_file_stream_unlock(print->to);
}
#endif // _di_kt_tacocat_print_error_setting_socket_lengths_must_match_
+#ifndef _di_kt_tacocat_print_error_socket_protocol_unsupported_
+ f_status_t kt_tacocat_print_error_socket_protocol_unsupported(fl_print_t * const print, const f_string_dynamic_t name, const f_number_unsigned_t protocol) {
+
+ if (!print || !print->custom) return F_status_set_error(F_output_not);
+ if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+ f_file_stream_lock(print->to);
+
+ fl_print_format("%[%QUnsupported protocol%] ", print->to, print->set->error, print->prefix, print->set->error);
+ fl_print_format("%[%lu%]", print->to, print->set->notable, protocol, print->set->notable);
+ fl_print_format(" %[while processing '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[%Q%]", print->to, print->set->notable, name, print->set->notable);
+ fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
+
+ f_file_stream_unlock(print->to);
+
+ return F_none;
+ }
+#endif // _di_kt_tacocat_print_error_socket_protocol_unsupported_
+
#ifdef __cplusplus
} // extern "C"
#endif
*
* This does not alter print.custom.setting.state.status.
* @param name
- * The name of the set of arrays that must have the same length.
- * @param names
- * The length of the names array.
- * @param files
- * The length of the files array.
- * @param sockets
- * The length of the sockets array.
- * @param statuss
- * The length of the statuss array.
+ * The name representing the socket set whose array lengths must match.
+ * @param set
+ * The socket set.
*
* @return
* F_none on success.
* @see fll_error_file_print()
*/
#ifndef _di_kt_tacocat_print_error_setting_socket_lengths_must_match_
- extern f_status_t kt_tacocat_print_error_setting_socket_lengths_must_match(fl_print_t * const print, const f_string_dynamic_t name, const f_number_unsigned_t names, const f_number_unsigned_t files, const f_number_unsigned_t sockets, const f_number_unsigned_t statuss);
+ extern f_status_t kt_tacocat_print_error_setting_socket_lengths_must_match(fl_print_t * const print, const f_string_dynamic_t name, const kt_tacocat_socket_set_t set);
#endif // _di_kt_tacocat_print_error_setting_socket_lengths_must_match_
+/**
+ * Print error message for when an unsupported protocol is used.
+ *
+ * @param print
+ * The output structure to print to.
+ *
+ * This does not alter print.custom.setting.state.status.
+ * @param name
+ * The file or network name associated with the unsupported protocol.
+ * @param protocol
+ * The protocol number representing the unsupported protocol
+ *
+ * @return
+ * F_none on success.
+ * F_output_not on success, but no printing is performed.
+ *
+ * F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_kt_tacocat_print_error_socket_protocol_unsupported_
+ extern f_status_t kt_tacocat_print_error_socket_protocol_unsupported(fl_print_t * const print, const f_string_dynamic_t name, const f_number_unsigned_t protocol);
+#endif // _di_kt_tacocat_print_error_socket_protocol_unsupported_
+
#ifdef __cplusplus
} // extern "C"
#endif
void kt_tacocat_process_main(kt_tacocat_main_t * const main) {
if (!main) return;
+ if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_receive_s, main->setting.receive))) return;
+ if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_send_s, main->setting.send))) return;
- if (main->setting.socket_receives.used != main->setting.file_receives.used && main->setting.socket_receives.used != main->setting.receives.used && main->setting.socket_receives.used != main->setting.status_receives.used) {
- main->setting.state.status = F_status_set_error(F_parameter);
+ // @todo Make this threaded, if threading is enabled (if threading is disabled then fork).
+ // TacocaT is intended to be simple, so be lazy and create a thread/fork for every single receive and send.
+
+ kt_tacocat_process_socket_set_receive(main);
+ kt_tacocat_process_socket_set_send(main);
+
+ // domain
+ // PF_INET = ipv4
+ // PF_INET6 = ipv6
+ // type
+ // SOCK_STREAM
+ // SOCK_DGRAM
+ // "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in"
+ // protocol
+ // f_socket_protocol_tcp
+ // f_socket_protocol_udp
- kt_tacocat_print_error_setting_socket_lengths_must_match(&main->program.error, kt_tacocat_long_receive_s, main->setting.receives.used, main->setting.file_receives.used, main->setting.socket_receives.used, main->setting.status_receives.used);
+ //f_socket_connect
+
+ // @todo:
+ // 1: Establish connections.
+ // 2: read / write from files.
+ // 3: work or wait until told to terminate.
+ // 4: terminate.
+
+ kt_tacocat_process_socket_set_disconnect(main, &main->setting.receive);
+ kt_tacocat_process_socket_set_disconnect(main, &main->setting.send);
+
+ kt_tacocat_process_socket_set_error_handle(main, main->setting.receive);
+ kt_tacocat_process_socket_set_error_handle(main, main->setting.send);
+ }
+#endif // _di_kt_tacocat_process_main_
+
+#ifndef _di_kt_tacocat_process_socket_set_disconnect_
+ void kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main) return;
+
+ if (!set) {
+ main->setting.state.status = F_status_set_error(F_parameter);
return;
}
- if (main->setting.socket_sends.used != main->setting.file_sends.used && main->setting.socket_sends.used != main->setting.sends.used && main->setting.socket_sends.used != main->setting.status_sends.used) {
+ f_status_t status = F_none;
+
+ for (f_number_unsigned_t i = 0; i < set->sockets.used; ++i) {
+
+ if (kt_tacocat_signal_check(main)) return;
+
+ status = f_socket_disconnect(&set->sockets.array[i], f_socket_close_read_write_e);
+
+ if (F_status_is_error_not(set->statuss.array[i]) && F_status_is_error(main->setting.state.status)) {
+ set->statuss.array[i] = status;
+
+ kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_disconnect));
+ }
+ } // for
+ }
+#endif // _di_kt_tacocat_process_socket_set_disconnect_
+
+#ifndef _di_kt_tacocat_process_socket_set_error_handle_
+ void kt_tacocat_process_socket_set_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_set_t set) {
+
+ if (!main) return;
+ if (F_status_is_error(main->setting.state.status)) return;
+
+ main->setting.state.status = F_none;
+
+ for (f_number_unsigned_t i = 0; i < set.statuss.used; ++i) {
+
+ if (kt_tacocat_signal_check(main)) return;
+
+ if (F_status_is_error(set.statuss.array[i])) {
+ main->setting.state.status = set.statuss.array[i];
+
+ return;
+ }
+ } // for
+ }
+#endif // _di_kt_tacocat_process_socket_set_error_handle_
+
+#ifndef _di_kt_tacocat_process_socket_set_error_has_
+ f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_set_t set) {
+
+ if (!main) {
main->setting.state.status = F_status_set_error(F_parameter);
- kt_tacocat_print_error_setting_socket_lengths_must_match(&main->program.error, kt_tacocat_long_send_s, main->setting.sends.used, main->setting.file_sends.used, main->setting.socket_sends.used, main->setting.status_sends.used);
+ kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(kt_tacocat_process_socket_set_error_has));
- return;
+ return main->setting.state.status;
}
- f_number_unsigned_t i = 0;
+ if (set.sockets.used != set.files.used || set.sockets.used != set.files.used || set.sockets.used != set.statuss.used || set.sockets.used != set.names.used || set.sockets.used != set.buffers.used) {
+ main->setting.state.status = F_status_set_error(F_parameter);
- // @todo Make this threaded, if threading is enabled (if threading is disabled then fork).
- // TacocaT is intended to be simple, so be lazy and create a thread/fork for every single receive and send.
+ kt_tacocat_print_error_setting_socket_lengths_must_match(&main->program.error, parameter, set);
+
+ return main->setting.state.status;
+ }
+
+ return F_none;
+ }
+#endif // _di_kt_tacocat_process_socket_set_error_has_
+
+#ifndef _di_kt_tacocat_process_socket_set_receive_
+ void kt_tacocat_process_socket_set_receive(kt_tacocat_main_t * const main) {
+
+ if (!main) return;
// Create, bind, and listen to the socket.
- for (; i < main->setting.socket_receives.used; ++i) {
+ for (f_number_unsigned_t i = 0; i < main->setting.receive.sockets.used; ++i) {
if (kt_tacocat_signal_check(main)) return;
- if (F_status_is_error(main->setting.status_receives.array[i])) continue;
+ if (F_status_is_error(main->setting.receive.statuss.array[i])) continue;
- main->setting.status_receives.array[i] = f_socket_create(&main->setting.socket_receives.array[i]);
+ main->setting.receive.statuss.array[i] = f_socket_create(&main->setting.receive.sockets.array[i]);
- if (F_status_is_error(main->setting.status_receives.array[i])) {
- main->setting.state.status = main->setting.status_receives.array[i];
+ if (F_status_is_error(main->setting.receive.statuss.array[i])) {
+ main->setting.state.status = main->setting.receive.statuss.array[i];
kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_create));
continue;
}
- if (main->setting.socket_receives.array[i].domain == f_socket_protocol_family_inet4_e) {
- main->setting.status_receives.array[i] = f_socket_bind_inet4(&main->setting.socket_receives.array[i]);
+ if (main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet4_e) {
+ main->setting.receive.statuss.array[i] = f_socket_bind_inet4(&main->setting.receive.sockets.array[i]);
}
- else if (main->setting.socket_receives.array[i].domain == f_socket_protocol_family_inet6_e) {
- main->setting.status_receives.array[i] = f_socket_bind_inet6(&main->setting.socket_receives.array[i]);
+ else if (main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet6_e) {
+ main->setting.receive.statuss.array[i] = f_socket_bind_inet6(&main->setting.receive.sockets.array[i]);
}
- else if (main->setting.socket_receives.array[i].domain == f_socket_protocol_family_local_e) {
- main->setting.status_receives.array[i] = f_socket_bind_local(&main->setting.socket_receives.array[i]);
+ else if (main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_local_e) {
+ main->setting.receive.statuss.array[i] = f_socket_bind_local(&main->setting.receive.sockets.array[i]);
}
else {
- // @todo error, not supported.
+ main->setting.state.status = F_status_set_error(F_parameter);
+
+ kt_tacocat_print_error_socket_protocol_unsupported(&main->program.error, main->setting.receive.names.array[i], main->setting.receive.sockets.array[i].domain);
+
+ return;
}
- if (F_status_is_error(main->setting.status_receives.array[i])) {
- main->setting.state.status = main->setting.status_receives.array[i];
+ if (F_status_is_error(main->setting.receive.statuss.array[i])) {
+ main->setting.state.status = main->setting.receive.statuss.array[i];
- kt_tacocat_print_error(&main->program.error, main->setting.socket_receives.array[i].domain == f_socket_protocol_family_inet4_e
+ kt_tacocat_print_error(&main->program.error, main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet4_e
? macro_kt_tacocat_f(f_socket_bind_inet4)
- : main->setting.socket_receives.array[i].domain == f_socket_protocol_family_inet6_e
+ : main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet6_e
? macro_kt_tacocat_f(f_socket_bind_inet6)
: macro_kt_tacocat_f(f_socket_bind_local)
);
continue;
}
- main->setting.status_receives.array[i] = f_socket_listen(&main->setting.socket_receives.array[i], kt_tacocat_backlog_max_d);
+ main->setting.receive.statuss.array[i] = f_socket_listen(&main->setting.receive.sockets.array[i], kt_tacocat_backlog_max_d);
- if (F_status_is_error(main->setting.status_receives.array[i])) {
- main->setting.state.status = main->setting.status_receives.array[i];
+ if (F_status_is_error(main->setting.receive.statuss.array[i])) {
+ main->setting.state.status = main->setting.receive.statuss.array[i];
kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_listen));
}
} // for
- for (i = 0; i < main->setting.socket_sends.used; ++i) {
+ if (F_status_is_error_not(main->setting.state.status)) {
+ main->setting.state.status = F_none;
+ }
+ }
+#endif // _di_kt_tacocat_process_socket_set_receive_
- if (kt_tacocat_signal_check(main)) return;
- if (F_status_is_error(main->setting.status_sends.array[i])) continue;
+#ifndef _di_kt_tacocat_process_socket_set_send_
+ void kt_tacocat_process_socket_set_send(kt_tacocat_main_t * const main) {
+
+ if (!main) return;
+
+ for (f_number_unsigned_t i = 0; i < main->setting.send.sockets.used; ++i) {
- // @todo check to see if connection is one of "local", "inet" (ipv4), or "inet6" (ipv6) and configure socket appropriately.
+ if (kt_tacocat_signal_check(main)) return;
+ if (F_status_is_error(main->setting.send.statuss.array[i])) continue;
- main->setting.status_sends.array[i] = f_socket_create(&main->setting.socket_sends.array[i]);
+ main->setting.send.statuss.array[i] = f_socket_create(&main->setting.send.sockets.array[i]);
- if (F_status_is_error(main->setting.status_sends.array[i])) {
- main->setting.state.status = main->setting.status_sends.array[i];
+ if (F_status_is_error(main->setting.send.statuss.array[i])) {
+ main->setting.state.status = main->setting.send.statuss.array[i];
kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_create));
// @todo f_socket_bind().
} // for
- // domain
- // PF_INET = ipv4
- // PF_INET6 = ipv6
- // type
- // SOCK_STREAM
- // SOCK_DGRAM
- // "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in"
- // protocol
- // f_socket_protocol_tcp
- // f_socket_protocol_udp
-
- //f_socket_connect
-
- // @todo:
- // 1: Establish connections.
- // 2: read / write from files.
- // 3: work or wait until told to terminate.
- // 4: terminate.
-
- // Disconnect.
- for (; i < main->setting.socket_receives.used; ++i) {
-
- if (kt_tacocat_signal_check(main)) return;
-
- main->setting.status_receives.array[i] = f_socket_disconnect(&main->setting.socket_receives.array[i], f_socket_close_read_write_e);
-
- if (F_status_is_error(main->setting.status_receives.array[i])) {
- main->setting.state.status = main->setting.status_receives.array[i];
-
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_disconnect));
- }
- } // for
-
- for (i = 0; i < main->setting.socket_sends.used; ++i) {
-
- if (kt_tacocat_signal_check(main)) return;
-
- main->setting.status_sends.array[i] = f_socket_disconnect(&main->setting.socket_sends.array[i], f_socket_close_read_write_e);
-
- if (F_status_is_error(main->setting.status_sends.array[i])) {
- main->setting.state.status = main->setting.status_sends.array[i];
-
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_disconnect));
- }
- } // for
-
- // Handle returning errors.
if (F_status_is_error_not(main->setting.state.status)) {
main->setting.state.status = F_none;
-
- for (i = 0; i < main->setting.socket_receives.used; ++i) {
-
- if (kt_tacocat_signal_check(main)) return;
-
- if (F_status_is_error(main->setting.status_receives.array[i])) {
- main->setting.state.status = main->setting.status_receives.array[i];
- }
- } // for
-
- for (i = 0; i < main->setting.socket_sends.used; ++i) {
-
- if (kt_tacocat_signal_check(main)) return;
-
- if (F_status_is_error(main->setting.status_sends.array[i])) {
- main->setting.state.status = main->setting.status_sends.array[i];
- }
- } // for
}
}
-#endif // _di_kt_tacocat_process_main_
+#endif // _di_kt_tacocat_process_socket_set_send_
#ifdef __cplusplus
} // extern "C"
extern void kt_tacocat_process_main(kt_tacocat_main_t * const main);
#endif // _di_kt_tacocat_process_main_
+/**
+ * Perform the disconnect for the socket given socket set.
+ *
+ * This handles errors and prints appropriate messages.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.setting.state.status:
+ * F_parameter (with error bit) on invalid parameter.
+ *
+ * This does not set parameter error on success or any socket disconnect error.
+ * @param set
+ * The socket set to disconnect all sockets of.
+ */
+#ifndef _di_kt_tacocat_process_socket_set_disconnect_
+ extern void kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_process_socket_set_disconnect_
+
+/**
+ * Traverse the sockets, grabbing the first error and setting the main.setting.state.status appropriately.
+ *
+ * This does not print messages.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.setting.state.status:
+ * F_none on success and no error is found.
+ *
+ * An status with error bit set from any socket that has a status failure.
+ *
+ * If this already has the error bit set, then no changes are performed.
+ * @param set
+ * The socket set to handle the errors of.
+ */
+#ifndef _di_kt_tacocat_process_socket_set_error_handle_
+ extern void kt_tacocat_process_socket_set_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_set_t set);
+#endif // _di_kt_tacocat_process_socket_set_error_handle_
+
+/**
+ * Check the socket set and handle and print error if the array lengths do not match.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.setting.state.status:
+ * F_parameter (with error bit) on parameter error.
+ *
+ * This is not altered on success.
+ * @param parameter
+ * The parameter long name to use when printing errors.
+ * @param set
+ * The socket set to handle the errors of.
+ *
+ * @return
+ * F_none on no error.
+ *
+ * F_parameter (with error bit) on parameter error.
+ */
+#ifndef _di_kt_tacocat_process_socket_set_error_has_
+ extern f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_set_t set);
+#endif // _di_kt_tacocat_process_socket_set_error_has_
+
+/**
+ * Process the receive socket set.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.setting.state.status:
+ * F_none on success.
+ */
+#ifndef _di_kt_tacocat_process_socket_set_receive_
+ extern void kt_tacocat_process_socket_set_receive(kt_tacocat_main_t * const main);
+#endif // _di_kt_tacocat_process_socket_set_receive_
+
+/**
+ * Process the send socket set.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.setting.state.status:
+ * F_none on success.
+ */
+#ifndef _di_kt_tacocat_process_socket_set_send_
+ extern void kt_tacocat_process_socket_set_send(kt_tacocat_main_t * const main);
+#endif // _di_kt_tacocat_process_socket_set_send_
+
#ifdef __cplusplus
} // extern "C"
#endif