Restructure the kt_tacocat_socket_set_t to reduce the number of arrays.
I originally had the structure for f_polls_t.
I then got lazy and kept using the same array structure for everything.
Fix the array structure of kt_tacocat_socket_set_t and provide kt_tacocat_socket_sets_t.
The buffer string intended for a generic cache is move into the kt_tacocat_cache_t.
I am not sure if this is even being used and so this buffer string cache may be removed in the future if I fail to find a use for it.
Begin setting up the custom file name variable to resolve the fixme.
Also make preparations for only opening the file on poll and read operations.
Then close the file when done.
This keeps files from being held open for no reason.
kt_tacocat_long_send_s,
};
- kt_tacocat_socket_set_t * const sets[] = {
+ kt_tacocat_socket_sets_t * const sets[] = {
&main->setting.receive,
&main->setting.send,
};
+ f_polls_t * const polls[] = {
+ &main->setting.receive_polls,
+ &main->setting.send_polls,
+ };
+
const bool is_receive[] = {
F_true,
F_false,
};
+ const f_number_unsigned_t default_block_size[] = {
+ kt_tacocat_block_size_receive_d,
+ kt_tacocat_block_size_send_d,
+ };
+
f_number_unsigned_t j = 0;
f_number_unsigned_t k = 0;
f_number_unsigned_t p = 0;
f_number_unsigned_t index = 0;
f_number_unsigned_t length = 0;
+ f_number_unsigned_t total = 0;
f_status_t failed = F_okay;
struct hostent host;
f_network_family_ip_t family = f_network_family_ip_t_initialize;
continue;
}
- kt_tacocat_setting_load_send_receive_allocate(main, main->program.parameters.array[parameters[i]].values.used / 2, sets[i]);
+ total = main->program.parameters.array[parameters[i]].values.used / 2;
+
+ main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_poll_t), (void **) &polls[i]->array, &polls[i]->used, &polls[i]->size);
+ macro_setting_load_handle_send_receive_error_continue_1(f_memory_array_increase_by);
+
+ main->setting.state.status = f_memory_array_increase_by(total, sizeof(kt_tacocat_socket_set_t), (void **) &sets[i]->array, &sets[i]->used, &sets[i]->size);
+ macro_setting_load_handle_send_receive_error_continue_1(f_memory_array_increase_by);
- macro_setting_load_handle_send_receive_error_continue_1(kt_tacocat_setting_load_send_receive_allocate);
+ if (F_status_is_error_not(main->setting.state.status)) {
+ main->setting.state.status = F_okay;
+ }
for (p = 0; p < main->program.parameters.array[parameters[i]].values.used; p += 2) {
// First parameter value represents the network address or the socket file path.
index = main->program.parameters.array[parameters[i]].values.array[p];
- j = sets[i]->statuss.used;
-
- sets[i]->statuss.array[j] = F_okay;
- sets[i]->flags.array[j] = kt_tacocat_socket_flag_none_e;
- sets[i]->retrys.array[j] = 0;
- sets[i]->networks.array[j].used = 0;
- sets[i]->buffers.array[j].used = 0;
- sets[i]->packets.array[j].control = 0;
- sets[i]->packets.array[j].size = 0;
- sets[i]->packets.array[j].payload.start = 1;
- sets[i]->packets.array[j].payload.stop = 0;
+ j = sets[i]->used;
+
+ sets[i]->array[j].size_block = default_block_size[i];
+ sets[i]->array[j].buffer.used = 0;
+ sets[i]->array[j].client.used = 0;
+ sets[i]->array[j].flag = kt_tacocat_socket_flag_none_e;
+ sets[i]->array[j].name.used = 0;
+ sets[i]->array[j].network.used = 0;
+ sets[i]->array[j].packet.control = 0;
+ sets[i]->array[j].packet.size = 0;
+ sets[i]->array[j].packet.payload.start = 1;
+ sets[i]->array[j].packet.payload.stop = 0;
+ sets[i]->array[j].retry = 0;
+ sets[i]->array[j].status = F_okay;
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_memory_array_increase_by(main->program.parameters.arguments.array[index].used + 2, sizeof(f_char_t), (void **) &sets[i]->networks.array[j].string, &sets[i]->networks.array[j].used, &sets[i]->networks.array[j].size);
+ main->setting.state.status = f_memory_array_increase_by(main->program.parameters.arguments.array[index].used + 2, sizeof(f_char_t), (void **) &sets[i]->array[j].network.string, &sets[i]->array[j].network.used, &sets[i]->array[j].network.size);
macro_setting_load_handle_send_receive_error_continue_2(f_memory_array_increase_by);
- main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &sets[i]->networks.array[j]);
+ main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &sets[i]->array[j].network);
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.
- sets[i]->networks.array[j].string[sets[i]->networks.array[j].used] = 0;
- sets[i]->networks.array[j].string[sets[i]->networks.array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
+ sets[i]->array[j].network.string[sets[i]->array[j].network.used] = 0;
+ sets[i]->array[j].network.string[sets[i]->array[j].network.used + 1] = f_string_ascii_slash_forward_s.string[0];
if (is_receive[i]) {
- main->setting.state.status = f_file_exists(sets[i]->networks.array[j], F_true);
+ main->setting.state.status = f_file_exists(sets[i]->array[j].network, F_true);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless);
}
- sets[i]->networks.array[j].string[sets[i]->networks.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_type_stream_e;
- sets[i]->sockets.array[j].name = sets[i]->networks.array[j];
+ sets[i]->array[j].network.string[sets[i]->array[j].network.used] = 0;
+ sets[i]->array[j].socket.domain = f_socket_protocol_family_local_e;
+ sets[i]->array[j].socket.protocol = f_socket_protocol_tcp_e;
+ sets[i]->array[j].socket.type = f_socket_type_stream_e;
+ sets[i]->array[j].socket.name = sets[i]->array[j].network;
}
else if (main->setting.flag & kt_tacocat_main_flag_resolve_classic_e) {
memset(&host, 0, sizeof(struct hostent));
failed = main->setting.state.status;
}
- sets[i]->statuss.array[j] = main->setting.state.status;
+ sets[i]->array[j].status = main->setting.state.status;
continue;
}
}
if (host.h_addrtype) {
- main->setting.state.status = f_string_dynamic_append(address, &sets[i]->networks.array[j]);
+ main->setting.state.status = f_string_dynamic_append(address, &sets[i]->array[j].network);
macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append);
}
failed = main->setting.state.status;
}
- sets[i]->statuss.array[j] = main->setting.state.status;
+ sets[i]->array[j].status = main->setting.state.status;
continue;
}
- main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->networks.array[j].string, &sets[i]->networks.array[j].used, &sets[i]->networks.array[j].size);
+ main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->array[j].network.string, &sets[i]->array[j].network.used, &sets[i]->array[j].network.size);
macro_setting_load_handle_send_receive_error_continue_2(f_memory_array_increase_by);
k = 0;
}
- main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->networks.array[j].string, &sets[i]->networks.array[j].used, &sets[i]->networks.array[j].size);
+ main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->array[j].network.string, &sets[i]->array[j].network.used, &sets[i]->array[j].network.size);
macro_setting_load_handle_send_receive_error_continue_2(f_memory_array_increase_by);
family.address.v6 = *((struct in6_addr *) host.h_addr_list[k]);
}
- main->setting.state.status = f_network_to_ip_string(family, &sets[i]->networks.array[j]);
+ main->setting.state.status = f_network_to_ip_string(family, &sets[i]->array[j].network);
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;
}
- sets[i]->statuss.array[j] = main->setting.state.status;
+ sets[i]->array[j].status = main->setting.state.status;
continue;
}
- sets[i]->networks.array[j].string[sets[i]->networks.array[j].used] = 0;
+ sets[i]->array[j].network.string[sets[i]->array[j].network.used] = 0;
}
- sets[i]->sockets.array[j].protocol = f_socket_protocol_tcp_e;
- sets[i]->sockets.array[j].type = f_socket_type_stream_e;
+ sets[i]->array[j].socket.protocol = f_socket_protocol_tcp_e;
+ sets[i]->array[j].socket.type = f_socket_type_stream_e;
if (host.h_addrtype == f_socket_address_family_inet4_e) {
- sets[i]->sockets.array[j].domain = f_socket_protocol_family_inet4_e;
- sets[i]->sockets.array[j].address.inet4.sin_port = htons((in_port_t) port);
- sets[i]->sockets.array[j].address.inet4.sin_addr.s_addr = INADDR_ANY;
+ sets[i]->array[j].socket.domain = f_socket_protocol_family_inet4_e;
+ sets[i]->array[j].socket.address.inet4.sin_port = htons((in_port_t) port);
+ sets[i]->array[j].socket.address.inet4.sin_addr.s_addr = INADDR_ANY;
}
else if (host.h_addrtype == f_socket_address_family_inet6_e) {
- sets[i]->sockets.array[j].domain = f_socket_protocol_family_inet6_e;
- sets[i]->sockets.array[j].address.inet6.sin6_port = htons((in_port_t) port);
- sets[i]->sockets.array[j].address.inet6.sin6_addr = in6addr_any;
+ sets[i]->array[j].socket.domain = f_socket_protocol_family_inet6_e;
+ sets[i]->array[j].socket.address.inet6.sin6_port = htons((in_port_t) port);
+ sets[i]->array[j].socket.address.inet6.sin6_addr = in6addr_any;
}
}
else {
// @todo Kevux DNS resolution.
}
- ++sets[i]->buffers.used;
- ++sets[i]->files.used;
- ++sets[i]->flags.used;
- ++sets[i]->networks.used;
- ++sets[i]->packets.used;
- ++sets[i]->polls.used;
- ++sets[i]->sockets.used;
- ++sets[i]->statuss.used;
+ ++polls[i]->used;
+ ++sets[i]->used;
}
else {
main->setting.state.status = F_status_set_error(F_parameter);
failed = main->setting.state.status;
}
- sets[i]->statuss.array[j] = main->setting.state.status;
+ sets[i]->array[j].status = main->setting.state.status;
continue;
}
if (main->program.parameters.arguments.array[index].used) {
// Make sure the current file is closed.
- f_file_close(&sets[i]->files.array[j]);
+ f_file_close(&sets[i]->array[j].file);
+
+ sets[i]->array[j].file.flag = is_receive[i] ? F_file_flag_append_wo_d : F_file_flag_read_only_d;
+ sets[i]->array[j].file.size_read = sets[i]->array[j].size_block;
+ sets[i]->array[j].file.size_write = sets[i]->array[j].size_block;
- 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]->size_block;
- sets[i]->files.array[j].size_write = sets[i]->size_block;
+ // Associate file name via a static string.
+ sets[i]->array[j].name.string = main->program.parameters.arguments.array[index].string;
+ sets[i]->array[j].name.used = main->program.parameters.arguments.array[index].used;
+ sets[i]->array[j].name.size = 0;
- main->setting.state.status = f_file_open(main->program.parameters.arguments.array[index], F_file_mode_all_rw_d, &sets[i]->files.array[j]);
+ // @fixme only open the file when reading/writing and then close it at the end. This open is fine if it is used as a check on startup, but in this case immediately close it.
+ main->setting.state.status = f_file_open(sets[i]->array[j].name, F_file_mode_all_rw_d, &sets[i]->array[j].file);
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);
+ macro_setting_load_handle_send_receive_error_file_continue_1(f_file_open, sets[i]->array[j].name, f_file_operation_open_s, fll_error_file_type_file_e);
if (F_status_is_error_not(failed)) {
failed = main->setting.state.status;
}
- sets[i]->statuss.array[j] = main->setting.state.status;
+ sets[i]->array[j].status = main->setting.state.status;
}
}
else {
failed = main->setting.state.status;
}
- sets[i]->statuss.array[j] = main->setting.state.status;
+ sets[i]->array[j].status = main->setting.state.status;
continue;
}
}
} // for
- if (F_status_is_error(failed)) {
- main->setting.state.status = failed;
- }
+ main->setting.state.status = F_status_is_error(failed) ? failed : F_okay;
}
#endif // _di_kt_tacocat_setting_load_send_receive_
-#ifndef _di_kt_tacocat_setting_load_send_receive_allocate_
- void kt_tacocat_setting_load_send_receive_allocate(kt_tacocat_main_t * const main, const f_number_unsigned_t total, kt_tacocat_socket_set_t * const set) {
-
- if (!main) return;
-
- set->buffers.used = 0;
- set->files.used = 0;
- set->flags.used = 0;
- set->networks.used = 0;
- set->packets.used = 0;
- set->polls.used = 0;
- set->retrys.used = 0;
- set->sockets.used = 0;
- set->statuss.used = 0;
-
- if (!set) {
- main->setting.state.status = F_status_set_error(F_parameter);
-
- return;
- }
-
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_string_dynamic_t), (void **) &set->buffers.array, &set->buffers.used, &set->buffers.size);
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_file_t), (void **) &set->files.array, &set->files.used, &set->files.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(uint16_t), (void **) &set->flags.array, &set->flags.used, &set->flags.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_poll_t), (void **) &set->polls.array, &set->polls.used, &set->polls.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(uint16_t), (void **) &set->retrys.array, &set->retrys.used, &set->retrys.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_string_dynamic_t), (void **) &set->networks.array, &set->networks.used, &set->networks.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_fss_simple_packet_range_t), (void **) &set->packets.array, &set->packets.used, &set->packets.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_socket_t), (void **) &set->sockets.array, &set->sockets.used, &set->sockets.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_status_t), (void **) &set->statuss.array, &set->statuss.used, &set->statuss.size);
- }
-
- if (F_status_is_error_not(main->setting.state.status)) {
- main->setting.state.status = F_okay;
- }
- }
-#endif // _di_kt_tacocat_setting_load_send_receive_allocate_
-
#ifndef _di_kt_tacocat_setting_load_address_port_extract_
void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, f_string_static_t * const address, f_number_unsigned_t * const port, f_string_range_t * const port_range) {
#endif // _di_kt_tacocat_setting_load_send_receive_
/**
- * Perform the allocation for the standard program setting load process for the send and receive parameters.
- *
- * @param main
- * The main program and settings data.
- *
- * This alters main.setting.state.status:
- * F_okay on success.
- *
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * Errors (with error bit) from: f_memory_array_increase_by().
- * @param total
- * The total arrays to allocated.
- * @param set
- * The socket set to be allocated.
- *
- * @see f_memory_array_increase_by()
- */
-#ifndef _di_kt_tacocat_setting_load_send_receive_allocate_
- extern void kt_tacocat_setting_load_send_receive_allocate(kt_tacocat_main_t * const main, const f_number_unsigned_t total, kt_tacocat_socket_set_t * const set);
-#endif // _di_kt_tacocat_setting_load_send_receive_allocate_
-
-/**
* Process the string and extract any potential port numbers.
*
* A port number is expected to be a digit following the last ':' at the end of the string.
failed = main->setting.state.status; \
} \
\
- sets[i]->statuss.array[j] = main->setting.state.status; \
+ sets[i]->array[j].status = main->setting.state.status; \
\
continue; \
}
failed = main->setting.state.status; \
} \
\
- sets[i]->statuss.array[j] = main->setting.state.status; \
+ sets[i]->array[j].status = main->setting.state.status; \
\
continue; \
}
#define macro_kt_receive_process_handle_error_exit_1(main, method, name, status, flag, id_data) \
- if (F_status_is_error(*status)) { \
- kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, *name, *status); \
+ if (F_status_is_error(status)) { \
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, name, status); \
\
if (id_data) { \
f_file_close_id(id_data); \
}
#define macro_kt_receive_process_begin_handle_error_exit_1(main, method, name, status, flag) \
- if (F_status_is_error(*status)) { \
- kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, *name, *status); \
+ if (F_status_is_error(status)) { \
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, name, status); \
\
- *flag -= kt_tacocat_socket_flag_block_control_e; \
+ flag -= kt_tacocat_socket_flag_block_control_e; \
\
return; \
}
"fll_program_parameter_process_verbosity",
"kt_tacocat_process_socket_set_error_has",
"kt_tacocat_setting_load_address_port_extract",
- "kt_tacocat_setting_load_send_receive_allocate",
};
#endif // _di_kt_tacocat_f_a_
extern "C" {
#endif
+#ifndef _di_kt_tacocat_cache_delete_
+ void kt_tacocat_cache_delete(kt_tacocat_cache_t * const cache) {
+
+ if (!cache) return;
+
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->buffer.string, &cache->buffer.used, &cache->buffer.size);
+ }
+#endif // _di_kt_tacocat_cache_delete_
+
#ifndef _di_kt_tacocat_main_delete_
void kt_tacocat_main_delete(kt_tacocat_main_t * const main) {
if (!main) return;
fll_program_data_delete(&main->program);
- kt_tacocat_setting_delete(main->program, &main->setting);
- kt_tacocat_thread_delete(main->program, &main->thread);
+ kt_tacocat_cache_delete(&main->cache);
+ kt_tacocat_setting_delete(&main->setting);
}
#endif // _di_kt_tacocat_main_delete_
#ifndef _di_kt_tacocat_setting_delete_
- f_status_t kt_tacocat_setting_delete(const fll_program_data_t program, kt_tacocat_setting_t * const setting) {
+ void kt_tacocat_setting_delete(kt_tacocat_setting_t * const setting) {
- if (!setting) return F_status_set_error(F_parameter);
+ if (!setting) return;
- {
- f_number_unsigned_t j = 0;
+ f_memory_array_resize(0, sizeof(f_poll_t), (void **) &setting->receive_polls.array, &setting->receive_polls.used, &setting->receive_polls.size);
+ f_memory_array_resize(0, sizeof(f_poll_t), (void **) &setting->send_polls.array, &setting->send_polls.used, &setting->send_polls.size);
- kt_tacocat_socket_set_t * const sets[] = {
- &setting->receive,
- &setting->send,
- };
-
- for (uint8_t i = 0; i < 2; ++i) {
-
- for (j = 0; j < sets[i]->files.used ; ++j) {
- f_file_close(&sets[i]->files.array[j]);
- } // for
+ f_memory_arrays_resize(0, sizeof(kt_tacocat_socket_set_t), (void **) &setting->receive.array, &setting->receive.used, &setting->receive.size, &kt_tacocat_socket_sets_delete_callback);
+ f_memory_arrays_resize(0, sizeof(kt_tacocat_socket_set_t), (void **) &setting->send.array, &setting->send.used, &setting->send.size, &kt_tacocat_socket_sets_delete_callback);
+ }
+#endif // _di_kt_tacocat_setting_delete_
- for (j = 0; j < sets[i]->sockets.used ; ++j) {
+#ifndef _di_kt_tacocat_socket_sets_delete_callback_
+ f_status_t kt_tacocat_socket_sets_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) {
- f_file_close_id(&sets[i]->sockets.array[j].id_data);
+ {
+ kt_tacocat_socket_set_t * const array = (kt_tacocat_socket_set_t *) void_array;
+ f_status_t status = F_okay;
- f_socket_disconnect(&sets[i]->sockets.array[j], program.signal_received ? f_socket_close_fast_e : f_socket_close_read_write_e);
- } // for
+ for (f_number_unsigned_t i = start; i < stop; ++i) {
- f_memory_array_resize(0, sizeof(uint16_t), (void **) &sets[i]->flags.array, &sets[i]->flags.used, &sets[i]->flags.size);
- f_memory_array_resize(0, sizeof(uint16_t), (void **) &sets[i]->retrys.array, &sets[i]->retrys.used, &sets[i]->retrys.size);
- f_memory_array_resize(0, sizeof(f_file_t), (void **) &sets[i]->files.array, &sets[i]->files.used, &sets[i]->files.size);
- f_memory_array_resize(0, sizeof(f_poll_t), (void **) &sets[i]->polls.array, &sets[i]->polls.used, &sets[i]->polls.size);
- f_memory_array_resize(0, sizeof(f_socket_t), (void **) &sets[i]->sockets.array, &sets[i]->sockets.used, &sets[i]->sockets.size);
- f_memory_array_resize(0, sizeof(f_status_t), (void **) &sets[i]->statuss.array, &sets[i]->statuss.used, &sets[i]->statuss.size);
- f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &sets[i]->networks.array, &sets[i]->networks.used, &sets[i]->networks.size, &f_string_dynamics_delete_callback);
- f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &sets[i]->buffers.array, &sets[i]->buffers.used, &sets[i]->buffers.size, &f_string_dynamics_delete_callback);
- f_memory_array_resize(0, sizeof(f_fss_simple_packet_range_t), (void **) &sets[i]->packets.array, &sets[i]->packets.used, &sets[i]->packets.size);
- } // for
- }
+ f_file_close(&array[i].file);
+ f_file_close_id(&array[i].socket.id_data);
+ f_socket_disconnect(&array[i].socket, f_socket_close_fast_e);
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &setting->buffer.string, &setting->buffer.used, &setting->buffer.size);
+ if (array[i].buffer.size) {
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].buffer.string, &array[i].buffer.used, &array[i].buffer.size);
+ }
- return F_okay;
- }
-#endif // _di_kt_tacocat_setting_delete_
+ if (array[i].client.size) {
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].client.string, &array[i].client.used, &array[i].client.size);
+ }
-#ifndef _di_kt_tacocat_thread_delete_
- f_status_t kt_tacocat_thread_delete(const fll_program_data_t program, kt_tacocat_thread_t * const thread) {
+ if (array[i].name.size) {
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].name.string, &array[i].name.used, &array[i].name.size);
+ }
- if (!thread) return F_status_set_error(F_parameter);
+ if (array[i].network.size) {
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].network.string, &array[i].network.used, &array[i].network.size);
+ }
+ } // for
+ }
return F_okay;
}
-#endif // _di_kt_tacocat_thread_delete_
+#endif // _di_kt_tacocat_socket_sets_delete_callback_
#ifdef __cplusplus
} // extern "C"
#endif
/**
- * A set containing all socket related data sets.
+ * A set of all socket related properties.
*
- * size_block: The size in bytes to used to represent a block when sending or receiving packets.
- * max_buffer: The maximum size in bytes to used to represent a block when sending or receiving packets.
+ * size_block: The size in bytes to used to represent a block when sending or receiving packets.
*
- * flags: An array of flags for each socket.
- * retrys: An array of the current number of retries performed for the given network packet.
- * files: An array of files for each socket.
- * polls: An array of sockets to poll, specifically for passing to f_file_poll().
- * sockets: An array of the network sockets.
- * statuss: An array of statuses for each socket.
+ * flag: An array of flags for each socket.
+ * retry: An array of the current number of retries performed for the given network packet.
+ * file: An array of files for each socket.
+ * socket: An array of the network sockets.
+ * status: An array of statuses for each socket.
*
- * networks: An array of networks for each socket.
- * buffers: An array of buffers for sending or receiving data between clients for each socket.
- * packets: An array of simple packet ranges representing the parts of the packet for each socket for use during processing.
+ * buffer: An array of buffers for sending or receiving data between clients for each socket.
+ * client: An array representing a single client address for some network connection.
+ * name: An array of file names associated with each file in the files array.
+ * network: An array of networks for each socket.
+ * packet: An array of simple packet ranges representing the parts of the packet for each socket for use during processing.
*/
#ifndef _di_kt_tacocat_socket_set_t_
typedef struct {
f_number_unsigned_t size_block;
- f_uint16s_t flags;
- f_uint16s_t retrys;
- f_files_t files;
- f_polls_t polls;
- f_sockets_t sockets;
- f_statuss_t statuss;
+ uint16_t flag;
+ uint16_t retry;
+ f_file_t file;
+ f_socket_t socket;
+ f_status_t status;
- f_string_dynamics_t networks;
- f_string_dynamics_t buffers;
- f_fss_simple_packet_ranges_t packets;
+ f_string_dynamic_t buffer;
+ f_string_dynamic_t client;
+ f_string_dynamic_t name;
+ f_string_dynamic_t network;
+ f_fss_simple_packet_range_t packet;
} kt_tacocat_socket_set_t;
#define kt_tacocat_socket_set_t_initialize \
{ \
kt_tacocat_block_size_d, \
- f_uint16s_t_initialize, \
- f_uint16s_t_initialize, \
- f_files_t_initialize, \
- f_polls_t_initialize, \
- f_sockets_t_initialize, \
- f_statuss_t_initialize, \
- f_string_dynamics_t_initialize, \
- f_string_dynamics_t_initialize, \
- f_fss_simple_packet_ranges_t_initialize, \
+ 0, \
+ 0, \
+ f_file_t_initialize, \
+ f_socket_t_initialize, \
+ f_status_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_fss_simple_packet_range_t_initialize, \
}
- #define macro_kt_tacocat_setting_t_initialize_1(size_block) \
+ #define macro_kt_tacocat_socket_set_t_initialize_1(size_block) \
{ \
size_block, \
- f_uint16s_t_initialize, \
- f_uint16s_t_initialize, \
- f_files_t_initialize, \
- f_polls_t_initialize, \
- f_sockets_t_initialize, \
- f_statuss_t_initialize, \
- f_string_dynamics_t_initialize, \
- f_string_dynamics_t_initialize, \
- f_fss_simple_packet_ranges_t_initialize, \
+ 0, \
+ 0, \
+ f_file_t_initialize, \
+ f_poll_t_initialize, \
+ f_socket_t_initialize, \
+ f_status_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_fss_simple_packet_range_t_initialize, \
}
#endif // _di_kt_tacocat_socket_set_t_
/**
+ * An array of socket sets.
+ *
+ * array: The array of socket sets.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
+ */
+#ifndef _di_kt_tacocat_socket_sets_t_
+ typedef struct {
+ kt_tacocat_socket_set_t *array;
+
+ f_number_unsigned_t size;
+ f_number_unsigned_t used;
+ } kt_tacocat_socket_sets_t;
+
+ #define kt_tacocat_socket_sets_t_initialize { 0, 0, 0 }
+
+ #define macro_kt_tacocat_socket_sets_t_initialize_1(array, size, used) { array, size, used }
+ #define macro_kt_tacocat_socket_sets_t_initialize_2(array, length) { array, length, length }
+
+ #define macro_kt_tacocat_socket_sets_t_clear(socket_set) macro_f_string_statics_t_clear(socket_set)
+#endif // _di_kt_tacocat_socket_sets_t_
+
+/**
* The main program settings.
*
* This is passed to the program-specific main entry point to designate program settings.
*
* state: The state data used when processing data.
*
+ * receive_polls: An array of sockets to poll for receiving data, specifically for passing to f_file_poll().
+ * send_polls: An array of sockets to poll for sending data, specifically for passing to f_file_poll().
+ *
* 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.
*/
#ifndef _di_kt_tacocat_setting_t_
typedef struct {
f_state_t state;
- kt_tacocat_socket_set_t receive;
- kt_tacocat_socket_set_t send;
+ f_polls_t receive_polls;
+ f_polls_t send_polls;
- f_string_dynamic_t buffer;
+ kt_tacocat_socket_sets_t receive;
+ kt_tacocat_socket_sets_t send;
} kt_tacocat_setting_t;
#define kt_tacocat_setting_t_initialize \
F_okay, \
F_okay, \
macro_f_state_t_initialize_1(kt_tacocat_allocation_large_d, kt_tacocat_allocation_small_d, F_okay, 0, 0, &fll_program_standard_signal_handle, 0, 0, 0, 0), \
- 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, \
+ f_polls_t_initialize, \
+ f_polls_t_initialize, \
+ kt_tacocat_socket_sets_t_initialize, \
+ kt_tacocat_socket_sets_t_initialize, \
}
#endif // _di_kt_tacocat_setting_t_
* The TacocaT caches.
*
* peek: A static cache intended to be used for performing a peek on a given network stream.
+ *
+ * buffer: A string buffer used for caching purposes.
*/
#ifndef _di_kt_tacocat_cache_t_
typedef struct {
f_char_t peek[kt_tacocat_cache_size_peek_d];
+
+ f_string_dynamic_t buffer;
} kt_tacocat_cache_t;
#define kt_tacocat_cache_t_initialize \
{ \
{ 0 }, \
+ f_string_dynamic_t_initialize, \
}
#endif // _di_kt_tacocat_cache_t_
#endif // _di_kt_tacocat_main_t_
/**
+ * Delete the program main cache data.
+ *
+ * @param cache
+ * The program main cache data.
+ */
+#ifndef _di_kt_tacocat_cache_delete_
+ extern void kt_tacocat_cache_delete(kt_tacocat_cache_t * const cache);
+#endif // _di_kt_tacocat_cache_delete_
+
+/**
* Deallocate main program data.
*
- * @param setting_make
- * The make setting data.
+ * @param main
+ * The program and settings data.
*
* This does not alter main.setting.state.status.
*/
/**
* Delete the program main setting data.
*
- * @param program
- * The main program data.
* @param setting
* The program main setting data.
*
* This does not alter setting.state.status.
- *
- * @return
- * F_okay on success.
- *
- * F_parameter (with error bit) if a parameter is invalid.
*/
#ifndef _di_kt_tacocat_setting_delete_
- extern f_status_t kt_tacocat_setting_delete(const fll_program_data_t program, kt_tacocat_setting_t * const setting);
+ extern void kt_tacocat_setting_delete(kt_tacocat_setting_t * const setting);
#endif // _di_kt_tacocat_setting_delete_
/**
- * Delete the program main thread data.
+ * A callback intended to be passed to f_memory_arrays_resize() for an kt_tacocat_socket_sets_t structure.
+ *
+ * This is only called when shrinking the array and generally should perform deallocations.
*
- * @param program
- * The main program data.
- * @param thread
- * The program main thread data.
+ * This does not do parameter checking.
+ *
+ * @param start
+ * The inclusive start position in the array to start deleting.
+ * @param stop
+ * The exclusive stop position in the array to stop deleting.
+ * @param array
+ * The array structure to delete all values of.
+ * Must not be NULL.
*
* @return
* F_okay on success.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: f_memory_array_resize().
+ *
+ * @see f_memory_array_resize()
*/
-#ifndef _di_kt_tacocat_thread_delete_
- extern f_status_t kt_tacocat_thread_delete(const fll_program_data_t program, kt_tacocat_thread_t * const thread);
-#endif // _di_kt_tacocat_thread_delete_
+#ifndef _di_kt_tacocat_socket_sets_delete_callback_
+ extern f_status_t kt_tacocat_socket_sets_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array);
+#endif // _di_kt_tacocat_socket_sets_delete_callback_
#ifdef __cplusplus
} // extern "C"
}
#endif // _di_kt_tacocat_print_error_port_number_invalid_
-#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 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;
-
- f_file_stream_lock(print->to);
-
- fl_print_format("%[%QThe lengths of all%] ", print->to, print->set->error, print->prefix, print->set->error);
- fl_print_format(f_string_format_Q_single_s.string, 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, set.networks.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, 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, 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, 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);
-
- return F_okay;
- }
-#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) {
#endif // _di_kt_tacocat_print_error_port_number_invalid_
/**
- * Print error message for when an the different socket relating structure arrays do not have the same length.
- *
- * @param print
- * The output structure to print to.
- *
- * This does not alter print.custom.setting.state.status.
- * @param name
- * The name representing the socket set whose array lengths must match.
- * @param set
- * The socket set.
- *
- * @return
- * F_okay 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_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 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
}
#endif // _di_kt_tacocat_process_main_
-#ifndef _di_kt_tacocat_process_socket_set_disconnect_
- f_status_t kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
-
- if (!main || !set) return F_status_set_error(F_parameter);
-
- f_status_t status = F_okay;
-
- for (f_number_unsigned_t i = 0; i < set->sockets.used; ++i) {
-
- if (kt_tacocat_signal_check(main)) return F_status_set_error(F_interrupt);
-
- status = f_file_close_id(&set->sockets.array[i].id_data);
-
- if (F_status_is_error_not(set->statuss.array[i]) && F_status_is_error(status)) {
- set->statuss.array[i] = status;
-
- kt_tacocat_print_error_status(&main->program.error, macro_kt_tacocat_f(f_file_close_id), status);
- }
-
- 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(status)) {
- set->statuss.array[i] = status;
-
- kt_tacocat_print_error_status(&main->program.error, macro_kt_tacocat_f(f_socket_disconnect), status);
- }
- } // for
-
- return F_okay;
- }
-#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, f_status_t * const status) {
-
- if (!main || !status) return;
- if (F_status_is_error(*status)) return;
-
- *status = F_okay;
-
- 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])) {
- *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, f_status_t * const status) {
+ 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_sets_t set, f_status_t * const status) {
if (!main || !status) {
if (status) {
return F_status_set_error(F_parameter);
}
- if (set.sockets.used != set.files.used || set.sockets.used != set.files.used || set.sockets.used != set.statuss.used || set.sockets.used != set.networks.used || set.sockets.used != set.buffers.used) {
- *status = F_status_set_error(F_parameter);
-
- kt_tacocat_print_error_setting_socket_lengths_must_match(&main->program.error, parameter, set);
-
- return *status;
- }
-
return F_okay;
}
#endif // _di_kt_tacocat_process_socket_set_error_has_
int value_socket = 0;
- for (f_number_unsigned_t i = 0; i < main->setting.receive.sockets.used; ++i) {
+ for (f_number_unsigned_t i = 0; i < main->setting.receive.used; ++i) {
if (kt_tacocat_signal_check(main)) return;
- if (F_status_is_error(main->setting.receive.statuss.array[i])) continue;
+ if (F_status_is_error(main->setting.receive.array[i].status)) continue;
- main->setting.receive.sockets.array[i].id = -1;
- main->setting.receive.sockets.array[i].id_data = -1;
+ main->setting.receive.array[i].socket.id = -1;
+ main->setting.receive.array[i].socket.id_data = -1;
- main->setting.receive.statuss.array[i] = f_socket_create(&main->setting.receive.sockets.array[i]);
+ main->setting.receive.array[i].status = f_socket_create(&main->setting.receive.array[i].socket);
- if (F_status_is_error(main->setting.receive.statuss.array[i])) {
- main->setting.status_receive = main->setting.receive.statuss.array[i];
+ if (F_status_is_error(main->setting.receive.array[i].status)) {
+ main->setting.status_receive = main->setting.receive.array[i].status;
kt_tacocat_print_error_status(&main->program.error, macro_kt_tacocat_f(f_socket_create), main->setting.status_receive);
{
value_socket = 1;
- main->setting.receive.statuss.array[i] = f_socket_option_set(&main->setting.receive.sockets.array[i], SOL_SOCKET, f_socket_option_address_reuse_e | f_socket_option_port_reuse_e, &value_socket, sizeof(int));
+ main->setting.receive.array[i].status = f_socket_option_set(&main->setting.receive.array[i].socket, SOL_SOCKET, f_socket_option_address_reuse_e | f_socket_option_port_reuse_e, &value_socket, sizeof(int));
- if (F_status_is_error(main->setting.receive.statuss.array[i])) {
- main->setting.status_receive = main->setting.receive.statuss.array[i];
+ if (F_status_is_error(main->setting.receive.array[i].status)) {
+ main->setting.status_receive = main->setting.receive.array[i].status;
kt_tacocat_print_error_status(&main->program.error, macro_kt_tacocat_f(f_socket_option_set), main->setting.status_receive);
}
}
- for (main->setting.receive.retrys.array[i] = 0; main->setting.receive.retrys.array[i] < kt_tacocat_startup_retry_max_d; ++main->setting.receive.retrys.array[i]) {
+ for (main->setting.receive.array[i].retry = 0; main->setting.receive.array[i].retry < kt_tacocat_startup_retry_max_d; ++main->setting.receive.array[i].retry) {
- 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]);
+ if (main->setting.receive.array[i].socket.domain == f_socket_protocol_family_inet4_e) {
+ main->setting.receive.array[i].status = f_socket_bind_inet4(&main->setting.receive.array[i].socket);
}
- 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.receive.array[i].socket.domain == f_socket_protocol_family_inet6_e) {
+ main->setting.receive.array[i].status = f_socket_bind_inet6(&main->setting.receive.array[i].socket);
}
- 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 if (main->setting.receive.array[i].socket.domain == f_socket_protocol_family_local_e) {
+ main->setting.receive.array[i].status = f_socket_bind_local(&main->setting.receive.array[i].socket);
}
else {
main->setting.status_receive = F_status_set_error(F_parameter);
- kt_tacocat_print_error_socket_protocol_unsupported(&main->program.error, main->setting.receive.networks.array[i], main->setting.receive.sockets.array[i].domain);
+ kt_tacocat_print_error_socket_protocol_unsupported(&main->program.error, main->setting.receive.array[i].network, main->setting.receive.array[i].socket.domain);
return;
}
- if (F_status_set_fine(main->setting.receive.statuss.array[i]) == F_busy_address) {
- if (main->setting.receive.retrys.array[i] < kt_tacocat_startup_retry_max_d) {
- kt_tacocat_print_warning_on_busy(&main->program.warning, kt_tacocat_receive_s, main->setting.receive.networks.array[i], main->setting.receive.retrys.array[i] + 1);
+ if (F_status_set_fine(main->setting.receive.array[i].status) == F_busy_address) {
+ if (main->setting.receive.array[i].retry < kt_tacocat_startup_retry_max_d) {
+ kt_tacocat_print_warning_on_busy(&main->program.warning, kt_tacocat_receive_s, main->setting.receive.array[i].network, main->setting.receive.array[i].retry + 1);
struct timespec time = { 0 };
- main->setting.receive.statuss.array[i] = f_time_spec_millisecond(kt_tacocat_startup_retry_delay_second_d, kt_tacocat_startup_retry_delay_millisecond_d, &time);
+ main->setting.receive.array[i].status = f_time_spec_millisecond(kt_tacocat_startup_retry_delay_second_d, kt_tacocat_startup_retry_delay_millisecond_d, &time);
- if (F_status_is_error_not(main->setting.receive.statuss.array[i])) {
+ if (F_status_is_error_not(main->setting.receive.array[i].status)) {
nanosleep(&time, 0);
}
return;
}
- main->setting.receive.statuss.array[i] = F_status_set_error(F_busy_address);
+ main->setting.receive.array[i].status = F_status_set_error(F_busy_address);
continue;
}
break;
} // for
- if (F_status_is_error_not(main->setting.receive.statuss.array[i]) && main->setting.receive.retrys.array[i] < kt_tacocat_startup_retry_max_d) {
- main->setting.receive.statuss.array[i] = F_okay;
+ if (F_status_is_error_not(main->setting.receive.array[i].status) && main->setting.receive.array[i].retry < kt_tacocat_startup_retry_max_d) {
+ main->setting.receive.array[i].status = F_okay;
}
- main->setting.receive.retrys.array[i] = 0;
+ main->setting.receive.array[i].retry = 0;
- if (F_status_is_error(main->setting.receive.statuss.array[i])) {
- main->setting.status_receive = main->setting.receive.statuss.array[i];
+ if (F_status_is_error(main->setting.receive.array[i].status)) {
+ main->setting.status_receive = main->setting.receive.array[i].status;
if (F_status_set_fine(main->setting.status_receive) == F_busy_address) {
- kt_tacocat_print_error_on_busy(&main->program.error, kt_tacocat_receive_s, main->setting.receive.networks.array[i]);
+ kt_tacocat_print_error_on_busy(&main->program.error, kt_tacocat_receive_s, main->setting.receive.array[i].network);
}
else {
- kt_tacocat_print_error_status(&main->program.error, main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet4_e
+ kt_tacocat_print_error_status(&main->program.error, main->setting.receive.array[i].socket.domain == f_socket_protocol_family_inet4_e
? macro_kt_tacocat_f(f_socket_bind_inet4)
- : main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet6_e
+ : main->setting.receive.array[i].socket.domain == f_socket_protocol_family_inet6_e
? macro_kt_tacocat_f(f_socket_bind_inet6)
: macro_kt_tacocat_f(f_socket_bind_local),
main->setting.status_receive
continue;
}
- main->setting.receive.statuss.array[i] = f_socket_listen(&main->setting.receive.sockets.array[i], kt_tacocat_max_backlog_d);
+ main->setting.receive.array[i].status = f_socket_listen(&main->setting.receive.array[i].socket, kt_tacocat_max_backlog_d);
- if (F_status_is_error(main->setting.receive.statuss.array[i])) {
- main->setting.status_receive = main->setting.receive.statuss.array[i];
+ if (F_status_is_error(main->setting.receive.array[i].status)) {
+ main->setting.status_receive = main->setting.receive.array[i].status;
kt_tacocat_print_error_status(&main->program.error, macro_kt_tacocat_f(f_socket_listen), main->setting.status_receive);
continue;
}
- if (main->setting.receive.sockets.array[i].id == -1) {
- main->setting.receive.polls.array[i].fd = -1;
- main->setting.receive.polls.array[i].events = 0;
- main->setting.receive.polls.array[i].revents = 0;
+ if (main->setting.receive.array[i].socket.id == -1) {
+ main->setting.receive_polls.array[i].fd = -1;
+ main->setting.receive_polls.array[i].events = 0;
+ main->setting.receive_polls.array[i].revents = 0;
}
else {
- main->setting.receive.polls.array[i].fd = main->setting.receive.sockets.array[i].id;
- main->setting.receive.polls.array[i].events = f_poll_read_e | f_poll_urgent_e;
- main->setting.receive.polls.array[i].revents = 0;
+ main->setting.receive_polls.array[i].fd = main->setting.receive.array[i].socket.id;
+ main->setting.receive_polls.array[i].events = f_poll_read_e;
+ main->setting.receive_polls.array[i].revents = 0;
}
} // for
if (!main || F_status_is_error(main->setting.status_send)) return;
- for (f_number_unsigned_t i = 0; i < main->setting.send.sockets.used; ++i) {
+ for (f_number_unsigned_t i = 0; i < main->setting.send.used; ++i) {
if (kt_tacocat_signal_check(main)) return;
- if (F_status_is_error(main->setting.send.statuss.array[i])) continue;
+ if (F_status_is_error(main->setting.send.array[i].status)) continue;
- main->setting.send.statuss.array[i] = f_socket_create(&main->setting.send.sockets.array[i]);
+ main->setting.send.array[i].status = f_socket_create(&main->setting.send.array[i].socket);
- if (F_status_is_error(main->setting.send.statuss.array[i])) {
- main->setting.status_send = main->setting.send.statuss.array[i];
+ if (F_status_is_error(main->setting.send.array[i].status)) {
+ main->setting.status_send = main->setting.send.array[i].status;
kt_tacocat_print_error_status(&main->program.error, macro_kt_tacocat_f(f_socket_create), main->setting.status_send);
}
#endif // _di_kt_tacocat_process_socket_set_send_
+#ifndef _di_kt_tacocat_process_socket_sets_disconnect_
+ f_status_t kt_tacocat_process_socket_sets_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_sets_t * const sets) {
+
+ if (!main || !sets) return F_status_set_error(F_parameter);
+
+ {
+ f_status_t status = F_none;
+
+ for (f_number_unsigned_t i = 0; i < sets->used ; ++i) {
+
+ f_file_close(&sets->array[i].file);
+ f_file_close_id(&sets->array[i].socket.id_data);
+
+ status = f_socket_disconnect(&sets->array[i].socket, main->program.signal_received ? f_socket_close_fast_e : f_socket_close_read_write_e);
+
+ if (F_status_is_error(status)) {
+ f_socket_disconnect(&sets->array[i].socket, f_socket_close_read_write_e);
+ }
+ } // for
+ }
+
+ return F_okay;
+ }
+#endif // _di_kt_tacocat_process_socket_sets_disconnect_
+
+#ifndef _di_kt_tacocat_process_socket_sets_error_handle_
+ void kt_tacocat_process_socket_sets_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_sets_t sets, f_status_t * const status) {
+
+ if (!main || !status) return;
+ if (F_status_is_error(*status)) return;
+
+ *status = F_okay;
+
+ for (f_number_unsigned_t i = 0; i < sets.used; ++i) {
+
+ if (kt_tacocat_signal_check(main)) return;
+
+ if (F_status_is_error(sets.array[i].status)) {
+ *status = sets.array[i].status;
+
+ return;
+ }
+ } // for
+ }
+#endif // _di_kt_tacocat_process_socket_sets_error_handle_
+
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_kt_tacocat_process_main_
/**
- * Perform the disconnect for the socket given socket set.
- *
- * This handles errors and prints appropriate messages.
+ * Disconnect the socket set and close open file.
*
* @param main
* The main program and settings data.
*
* This does not set parameter error on success or any socket disconnect error.
* @param set
- * The socket set to disconnect all sockets of.
+ * The socket set to disconnect all parts of.
*
* @return
* F_okay on success.
*
* F_parameter (with error bit) on invalid parameter.
*/
-#ifndef _di_kt_tacocat_process_socket_set_disconnect_
- extern f_status_t 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_
+#ifndef _di_kt_tacocat_process_socket_sets_disconnect_
+ extern f_status_t kt_tacocat_process_socket_sets_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_sets_t * const sets);
+#endif // _di_kt_tacocat_process_socket_sets_disconnect_
/**
* Traverse the sockets, grabbing the first error and setting the main.setting.state.status appropriately.
* 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.
+ * @param sets
+ * The socket sets to handle the errors of.
* @param status
* The status to update with the status code from the given set.
*/
-#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, f_status_t * const status);
-#endif // _di_kt_tacocat_process_socket_set_error_handle_
+#ifndef _di_kt_tacocat_process_socket_sets_error_handle_
+ extern void kt_tacocat_process_socket_sets_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_sets_t sets, f_status_t * const status);
+#endif // _di_kt_tacocat_process_socket_sets_error_handle_
/**
* Check the socket set and handle and print error if the array lengths do not match.
* F_parameter (with error bit) if a parameter is invalid.
*/
#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, f_status_t * const status);
+ 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_sets_t set, f_status_t * const status);
#endif // _di_kt_tacocat_process_socket_set_error_has_
/**
if (F_status_is_error_not(main->setting.status_receive)) {
do {
- main->setting.status_receive = f_file_poll(main->setting.receive.polls, main->setting.interval);
+ main->setting.status_receive = f_file_poll(main->setting.receive_polls, main->setting.interval);
if (main->program.signal_received) {
main->setting.status_receive = F_status_set_error(F_interrupt);
// Skip if status is an error or is F_time_out.
if (main->setting.status_receive == F_okay) {
- for (i = 0; i < main->setting.receive.polls.used; ++i) {
+ for (i = 0; i < main->setting.receive_polls.used; ++i) {
- if (main->setting.receive.polls.array[i].fd == -1) continue;
+ if (main->setting.receive_polls.array[i].fd == -1) continue;
- if (main->setting.receive.polls.array[i].revents & (f_poll_read_e)) {
+ if (main->setting.receive_polls.array[i].revents & (f_poll_read_e)) {
kt_tacocat_receive_process(main, i);
- main->setting.receive.polls.array[i].revents = 0;
+ main->setting.receive_polls.array[i].revents = 0;
if (F_status_is_error(main->setting.state.status)) continue;
}
} while (F_status_is_error_not(main->setting.status_receive));
}
- kt_tacocat_process_socket_set_disconnect(main, &main->setting.receive);
+ kt_tacocat_process_socket_sets_disconnect(main, &main->setting.receive);
- kt_tacocat_process_socket_set_error_handle(main, main->setting.receive, &main->setting.status_receive);
+ kt_tacocat_process_socket_sets_error_handle(main, main->setting.receive, &main->setting.status_receive);
if (F_status_is_error_not(main->setting.status_receive)) {
main->setting.status_receive = F_okay;
if (!main) return;
- f_socket_t * const socket = &main->setting.receive.sockets.array[index];
- f_status_t * const status = &main->setting.receive.statuss.array[index];
- f_string_dynamic_t * const network = &main->setting.receive.networks.array[index];
- f_string_dynamic_t * const buffer = &main->setting.receive.buffers.array[index];
- f_fss_simple_packet_range_t * const packet = &main->setting.receive.packets.array[index];
+ kt_tacocat_socket_set_t * const set = &main->setting.receive.array[index];
// This is a new packet (kt_tacocat_socket_flag_none_e).
- if (!(main->setting.receive.flags.array[index])) {
- main->setting.receive.flags.array[index] = kt_tacocat_socket_flag_block_control_e;
- main->setting.receive.retrys.array[index] = 0;
- buffer->used = 0;
- socket->size_read = kt_tacocat_packet_read_d;
+ if (!(main->setting.receive.array[index].flag)) {
+ main->setting.receive.array[index].flag = kt_tacocat_socket_flag_block_control_e;
+ main->setting.receive.array[index].retry = 0;
+ set->buffer.used = 0;
+ set->socket.size_read = kt_tacocat_packet_read_d;
}
// Load the header of the new packet.
- if (main->setting.receive.flags.array[index] & kt_tacocat_socket_flag_block_control_e) {
+ if (main->setting.receive.array[index].flag & kt_tacocat_socket_flag_block_control_e) {
kt_tacocat_receive_process_control(main, index);
- if (F_status_is_error(*status) || buffer->used < kt_tacocat_packet_peek_d) {
- f_file_close_id(&socket->id_data);
+ if (F_status_is_error(set->status) || set->buffer.used < kt_tacocat_packet_peek_d) {
+ f_file_close_id(&set->socket.id_data);
return;
}
// Reset the buffer to allow for reusing and writing to the file in blocks.
- buffer->used = 0;
- socket->size_read = kt_tacocat_packet_read_d;
+ set->buffer.used = 0;
+ set->socket.size_read = kt_tacocat_packet_read_d;
// Make sure the buffer is large enough for payload processing block reads.
- *status = f_memory_array_increase_by(socket->size_read, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
- macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, network, status, main->setting.receive.flags.array[index], &socket->id_data);
+ set->status = f_memory_array_increase_by(set->socket.size_read, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
+ macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, main->setting.receive.array[index].flag, &set->socket.id_data);
}
- if (main->setting.receive.flags.array[index] & kt_tacocat_socket_flag_block_payload_e) {
+ if (main->setting.receive.array[index].flag & kt_tacocat_socket_flag_block_payload_e) {
size_t length_read = 0;
- *status = f_socket_read_stream(socket, 0, (void *) buffer->string, &length_read);
- macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, network, status, main->setting.receive.flags.array[index], &socket->id_data);
+ set->status = f_socket_read_stream(&set->socket, 0, (void *) set->buffer.string, &length_read);
+ macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, main->setting.receive.array[index].flag, &set->socket.id_data);
if (length_read) {
- buffer->used = length_read;
+ set->buffer.used = length_read;
- *status = f_file_write(main->setting.receive.files.array[index], *buffer, 0);
+ set->status = f_file_write(main->setting.receive.array[index].file, set->buffer, 0);
// Keep going on error, but in the future more advanced error handling/recovery is needed to make this more robust.
- if (F_status_is_error(*status)) {
- // @fixme The file name is not being saved, need to add the file name. For now just adding "socket->name" as a placeholder.
- kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_write), kt_tacocat_receive_s, *network, *status, socket->name);
+ if (F_status_is_error(set->status)) {
+ // @fixme The file name is not being saved, need to add the file name. For now just adding "set->socket.name" as a placeholder.
+ kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_write), kt_tacocat_receive_s, set->network, set->status, set->socket.name);
}
// Reset buffer used and increment counter.
- main->setting.receive.packets.array[index].payload.stop += buffer->used;
- buffer->used = 0;
+ set->packet.payload.stop += set->buffer.used;
+ set->buffer.used = 0;
- f_file_close_id(&socket->id_data);
+ f_file_close_id(&set->socket.id_data);
- if (main->setting.receive.packets.array[index].payload.stop < main->setting.receive.packets.array[index].size) return;
+ if (set->packet.payload.stop < set->packet.size) return;
}
- main->setting.receive.flags.array[index] -= kt_tacocat_socket_flag_block_payload_e;
+ main->setting.receive.array[index].flag -= kt_tacocat_socket_flag_block_payload_e;
}
// Done processing the Packet.
- f_file_close_id(&socket->id_data);
- main->setting.receive.flags.array[index] = 0;
+ f_file_close_id(&set->socket.id_data);
+ main->setting.receive.array[index].flag = 0;
- if (buffer->size > kt_tacocat_max_maintain_d) {
- buffer->used = 0;
+ if (set->buffer.size > kt_tacocat_max_maintain_d) {
+ set->buffer.used = 0;
- *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+ set->status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
// Report the resize error but do not fail.
- if (F_status_is_error(*status)) {
- kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *network, *status);
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, set->network, set->status);
}
}
}
if (!main) return;
- uint16_t * const flag = &main->setting.receive.flags.array[index];
- f_socket_t * const socket = &main->setting.receive.sockets.array[index];
- f_status_t * const status = &main->setting.receive.statuss.array[index];
- f_string_dynamic_t * const network = &main->setting.receive.networks.array[index];
- f_string_dynamic_t * const buffer = &main->setting.receive.buffers.array[index];
+ kt_tacocat_socket_set_t * const set = &main->setting.receive.array[index];
- const size_t size_read = socket->size_read;
+ const size_t size_read = set->socket.size_read;
size_t length_read = 0;
- *status = f_socket_accept(socket);
+ set->status = f_socket_accept(&set->socket);
// The socket failed to accept and so there is no data socket id to close.
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_accept, network, status, flag);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_accept, set->network, set->status, set->flag);
- *status = f_memory_array_increase_by(kt_tacocat_packet_peek_d + 1, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_memory_array_increase_by, network, status, flag);
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_peek_d + 1, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
- socket->size_read = kt_tacocat_packet_peek_d;
+ set->socket.size_read = kt_tacocat_packet_peek_d;
- *status = f_socket_read_stream(socket, 0, (void *) (buffer->string + buffer->used), &length_read);
+ set->status = f_socket_read_stream(&set->socket, 0, (void *) (set->buffer.string + set->buffer.used), &length_read);
- socket->size_read = size_read;
+ set->socket.size_read = size_read;
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_read_stream, network, status, flag);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->flag);
- buffer->used += length_read;
+ set->buffer.used += length_read;
// Continue if the packet header is not fully ready.
- if (buffer->used < kt_tacocat_packet_peek_d) {
+ if (set->buffer.used < kt_tacocat_packet_peek_d) {
// Peek ahead to see if the client has closed the connection (all the intended data should have been transmitted).
if (length_read) {
memset(main->cache.peek, 0, kt_tacocat_cache_size_peek_d);
- socket->size_read = kt_tacocat_cache_size_peek_d - 1;
+ set->socket.size_read = kt_tacocat_cache_size_peek_d - 1;
length_read = 0;
- *status = f_socket_read_stream(socket, f_socket_flag_peek_e | f_socket_flag_wait_not_e, (void *) main->cache.peek, &length_read);
+ set->status = f_socket_read_stream(&set->socket, f_socket_flag_peek_e | f_socket_flag_wait_not_e, (void *) main->cache.peek, &length_read);
- socket->size_read = size_read;
+ set->socket.size_read = size_read;
}
// Connection is closed when length is 0, which means the packet is too small.
if (!length_read) {
- kt_tacocat_print_error_on_packet_too_small(&main->program.error, kt_tacocat_receive_s, *network, kt_tacocat_packet_peek_d, buffer->used);
+ kt_tacocat_print_error_on_packet_too_small(&main->program.error, kt_tacocat_receive_s, set->network, kt_tacocat_packet_peek_d, set->buffer.used);
- buffer->used = 0;
- main->setting.receive.retrys.array[index] = 0;
- *status = F_status_set_error(F_packet_too_small);
- *flag = 0;
+ set->buffer.used = 0;
+ main->setting.receive.array[index].retry = 0;
+ set->status = F_status_set_error(F_packet_too_small);
+ set->flag = 0;
return;
}
- ++main->setting.receive.retrys.array[index];
+ ++main->setting.receive.array[index].retry;
return;
}
- *status = f_fss_simple_packet_extract_range(*buffer, &main->setting.receive.packets.array[index]);
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_fss_simple_packet_extract_range, network, status, flag);
+ set->status = f_fss_simple_packet_extract_range(set->buffer, &set->packet);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_fss_simple_packet_extract_range, set->network, set->status, set->flag);
- if (*status == F_packet_too_small) {
- main->setting.receive.packets.array[index].control = 0;
- main->setting.receive.packets.array[index].size = 0;
+ if (set->status == F_packet_too_small) {
+ set->packet.control = 0;
+ set->packet.size = 0;
}
- if (main->setting.receive.packets.array[index].size < F_fss_simple_packet_block_header_size_d) {
- *flag = 0;
+ if (set->packet.size < F_fss_simple_packet_block_header_size_d) {
+ set->flag = 0;
return;
}
if (main->setting.flag & kt_tacocat_main_flag_max_buffer_e) {
- if (main->setting.receive.packets.array[index].size > main->setting.max_buffer) {
- buffer->used = 0;
+ if (set->packet.size > main->setting.max_buffer) {
+ set->buffer.used = 0;
- if (buffer->size > kt_tacocat_max_maintain_d) {
- *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+ if (set->buffer.size > kt_tacocat_max_maintain_d) {
+ set->status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
// Report the resize error but do not fail.
- if (F_status_is_error(*status)) {
- kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *network, *status);
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, set->network, set->status);
}
}
- *status = F_status_set_error(F_packet_too_large);
- *flag = 0;
+ set->status = F_status_set_error(F_packet_too_large);
+ set->flag = 0;
- kt_tacocat_print_error_on_buffer_too_large(&main->program.error, kt_tacocat_receive_s, *network, main->setting.max_buffer, main->setting.receive.packets.array[index].size);
+ kt_tacocat_print_error_on_buffer_too_large(&main->program.error, kt_tacocat_receive_s, set->network, main->setting.max_buffer, set->packet.size);
return;
}
}
- *flag |= kt_tacocat_socket_flag_block_payload_e;
- *flag -= kt_tacocat_socket_flag_block_control_e;
+ set->flag |= kt_tacocat_socket_flag_block_payload_e;
+ set->flag -= kt_tacocat_socket_flag_block_control_e;
// The payload range "stop" is used to represent the total amount of bytes processed so far (uncluding the header).
- main->setting.receive.packets.array[index].payload.start = 0;
- main->setting.receive.packets.array[index].payload.stop = buffer->used - 1;
+ set->packet.payload.start = 0;
+ set->packet.payload.stop = set->buffer.used - 1;
}
#endif // _di_kt_tacocat_receive_process_control_
// @todo
}
- kt_tacocat_process_socket_set_disconnect(main, &main->setting.send);
+ kt_tacocat_process_socket_sets_disconnect(main, &main->setting.send);
- kt_tacocat_process_socket_set_error_handle(main, main->setting.send, &main->setting.status_send);
+ kt_tacocat_process_socket_sets_error_handle(main, main->setting.send, &main->setting.status_send);
if (F_status_is_error_not(main->setting.status_send)) {
main->setting.status_send = F_okay;