Make sure size_read and size_write are not 0.
If either is 0, then return F_data_not.
Make sure the result checks are "== -1" rather than "< 0".
Explicitly pass .generic for the address union.
This probably isn't necessary but being explicit seems safer.
The memory address of the address union, regardless of the union type being used, is cast to 'struct sockaddr' in most cases.
This makes the use of ".generic" very practical.
Add documentation comment about F_pipe being returned.
Problems with the address unions ".sin_family" must be set or unclear F_pipe errors are returned.
I may in a future commit perform this assignment during setup because the "form" parameter makes this practical and reasonable to do.
if (!socket) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- const int result = accept(socket->id, (struct sockaddr *) &socket->address, &socket->length);
+ const int result = accept(socket->id, (struct sockaddr *) &socket->address.generic, &socket->length);
if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (!socket) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- if (getpeername(socket->id, (struct sockaddr *) &socket->address, &socket->length) == -1) {
+ if (getpeername(socket->id, (struct sockaddr *) &socket->address.generic, &socket->length) == -1) {
if (errno == EBADF) return F_status_set_error(F_file_descriptor);
if (errno == EFAULT) return F_status_set_error(F_buffer);
if (errno == EINVAL) return F_status_set_error(F_parameter);
if (!buffer) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- const ssize_t result = recvfrom(socket->id_data, buffer, socket->size_read, flags, (struct sockaddr *) &socket->address, &socket->length);
+ if (!socket->size_read) return F_data_not;
- if (result < 0) {
+ const ssize_t result = recvfrom(socket->id_data, buffer, socket->size_read, flags, (struct sockaddr *) &socket->address.generic, &socket->length);
+
+ if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
if (errno == EALREADY) return F_status_set_error(F_complete_not);
if (!header) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
+ if (!socket->size_read) return F_data_not;
+
const ssize_t result = recvmsg(socket->id_data, header, flags);
- if (result < 0) {
+ if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
if (errno == EALREADY) return F_status_set_error(F_complete_not);
if (!buffer) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
+ if (!socket->size_read) return F_data_not;
+
const ssize_t result = recv(socket->id_data, buffer, socket->size_read, flags);
- if (result < 0) {
+ if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
if (errno == EALREADY) return F_status_set_error(F_complete_not);
if (!buffer) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- const ssize_t result = sendto(socket->id_data, buffer, socket->size_write, flags, (struct sockaddr *) &socket->address, socket->length);
+ if (!socket->size_write) return F_data_not;
- if (result < 0) {
+ const ssize_t result = sendto(socket->id_data, buffer, socket->size_write, flags, (struct sockaddr *) &socket->address.generic, socket->length);
+
+ if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
if (errno == EALREADY) return F_status_set_error(F_complete_not);
if (!header) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
+ if (!socket->size_write) return F_data_not;
+
const ssize_t result = sendmsg(socket->id_data, header, flags);
- if (result < 0) {
+ if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
if (errno == EALREADY) return F_status_set_error(F_complete_not);
if (!buffer) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
+ if (!socket->size_write) return F_data_not;
+
const ssize_t result = send(socket->id_data, buffer, socket->size_write, flags);
- if (result < 0) {
+ if (result == -1) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
if (errno == EALREADY) return F_status_set_error(F_complete_not);
*
* @return
* F_okay on success.
+ * F_data_not on success, but read size is 0 and so nothing was read.
*
* F_access_denied (with error bit) on access denied.
* F_complete_not (with error bit) if an existing connection is not yet complete.
*
* @return
* F_okay on success.
+ * F_data_not on success, but read size is 0 and so nothing was read.
*
* F_access_denied (with error bit) on access denied.
* F_complete_not (with error bit) if an existing connection is not yet complete.
*
* @return
* F_okay on success.
+ * F_data_not on success, but read size is 0 and so nothing was read.
*
* F_access_denied (with error bit) on access denied.
* F_complete_not (with error bit) if an existing connection is not yet complete.
*
* @return
* F_okay on success.
+ * F_data_not on success, but write size is 0 and so nothing was written.
*
* F_access_denied (with error bit) on access denied.
* F_address_not (with error bit) if no address is provided and the connection is not "connection-mode".
* F_memory_not (with error bit) if out of memory.
* F_option_not (with error bit) if a flag is not supported.
* F_parameter (with error bit) if a parameter is invalid.
- * F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received.
+ * F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received (Linux might return this isntead if F_connect_not).
* F_prohibited (with error bit) if the insufficient privileges to perform send.
* F_size (with error bit) if size of message makes atomically sending message impossible on a socket type that requires this to be atomic.
* F_socket_not (with error bit) if the ID is not a socket descriptor.
*
* @return
* F_okay on success.
+ * F_data_not on success, but write size is 0 and so nothing was written.
*
* F_access_denied (with error bit) on access denied.
* F_address_not (with error bit) if no address is provided and the connection is not "connection-mode".
* F_memory_not (with error bit) if out of memory.
* F_option_not (with error bit) if a flag is not supported.
* F_parameter (with error bit) if a parameter is invalid.
- * F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received.
+ * F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received (Linux might return this isntead if F_connect_not).
* F_prohibited (with error bit) if the insufficient privileges to perform send.
* F_size (with error bit) if size of message makes atomically sending message impossible on a socket type that requires this to be atomic.
* F_socket_not (with error bit) if the ID is not a socket descriptor.
*
* @return
* F_okay on success.
+ * F_data_not on success, but write size is 0 and so nothing was written.
*
* F_access_denied (with error bit) on access denied.
* F_address_not (with error bit) if no address is provided and the connection is not "connection-mode".
* F_memory_not (with error bit) if out of memory.
* F_option_not (with error bit) if a flag is not supported.
* F_parameter (with error bit) if a parameter is invalid.
- * F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received.
+ * F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received (Linux might return this isntead if F_connect_not).
* F_prohibited (with error bit) if the insufficient privileges to perform send.
* F_size (with error bit) if size of message makes atomically sending message impossible on a socket type that requires this to be atomic.
* F_socket_not (with error bit) if the ID is not a socket descriptor.
}
}
+void test__f_socket_read__returns_data_not(void **state) {
+
+ char * const buffer = "test";
+
+ {
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_read = 0;
+
+ const f_status_t status = f_socket_read(&socket, 0, (void *) buffer, 0);
+
+ assert_int_equal(status, F_data_not);
+ }
+
+ {
+ size_t length = 0;
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_read = 0;
+
+ const f_status_t status = f_socket_read(&socket, 0, (void *) buffer, &length);
+
+ assert_int_equal(status, F_data_not);
+ }
+}
+
void test__f_socket_read__works(void **state) {
f_socket_t socket = f_socket_t_initialize;
extern void test__f_socket_read__parameter_checking(void **state);
/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_socket_read()
+ */
+extern void test__f_socket_read__returns_data_not(void **state);
+
+/**
* Test that function works.
*
* @see f_socket_read()
}
}
+void test__f_socket_read_message__returns_data_not(void **state) {
+
+ struct msghdr header;
+
+ memset(&header, 0, sizeof(struct msghdr));
+
+ {
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_read = 0;
+
+ const f_status_t status = f_socket_read_message(&socket, 0, &header, 0);
+
+ assert_int_equal(status, F_data_not);
+ }
+
+ {
+ size_t length = 0;
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_read = 0;
+
+ const f_status_t status = f_socket_read_message(&socket, 0, &header, &length);
+
+ assert_int_equal(status, F_data_not);
+ }
+}
+
void test__f_socket_read_message__works(void **state) {
f_socket_t socket = f_socket_t_initialize;
extern void test__f_socket_read_message__parameter_checking(void **state);
/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_socket_read_message()
+ */
+extern void test__f_socket_read_message__returns_data_not(void **state);
+
+/**
* Test that function works.
*
* @see f_socket_read_message()
}
}
+void test__f_socket_read_stream__returns_data_not(void **state) {
+
+ char * const buffer = "test";
+
+ {
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_read = 0;
+
+ const f_status_t status = f_socket_read_stream(&socket, 0, (void *) buffer, 0);
+
+ assert_int_equal(status, F_data_not);
+ }
+
+ {
+ size_t length = 0;
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_read = 0;
+
+ const f_status_t status = f_socket_read_stream(&socket, 0, (void *) buffer, &length);
+
+ assert_int_equal(status, F_data_not);
+ }
+}
+
void test__f_socket_read_stream__works(void **state) {
f_socket_t socket = f_socket_t_initialize;
extern void test__f_socket_read_stream__parameter_checking(void **state);
/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_socket_read_stream()
+ */
+extern void test__f_socket_read_stream__returns_data_not(void **state);
+
+/**
* Test that function works.
*
* @see f_socket_read_stream()
}
}
+void test__f_socket_write__returns_data_not(void **state) {
+
+ char * const buffer = "test";
+
+ {
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_write = 0;
+
+ const f_status_t status = f_socket_write(&socket, 0, (void *) buffer, 0);
+
+ assert_int_equal(status, F_data_not);
+ }
+
+ {
+ size_t length = 0;
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_write = 0;
+
+ const f_status_t status = f_socket_write(&socket, 0, (void *) buffer, &length);
+
+ assert_int_equal(status, F_data_not);
+ }
+}
+
void test__f_socket_write__works(void **state) {
f_socket_t socket = f_socket_t_initialize;
extern void test__f_socket_write__parameter_checking(void **state);
/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_socket_write()
+ */
+extern void test__f_socket_write__returns_data_not(void **state);
+
+/**
* Test that function works.
*
* @see f_socket_write()
}
}
+void test__f_socket_write_message__returns_data_not(void **state) {
+
+ struct msghdr header;
+
+ memset(&header, 0, sizeof(struct msghdr));
+
+ {
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_write = 0;
+
+ const f_status_t status = f_socket_write_message(&socket, 0, &header, 0);
+
+ assert_int_equal(status, F_data_not);
+ }
+
+ {
+ size_t length = 0;
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_write = 0;
+
+ const f_status_t status = f_socket_write_message(&socket, 0, &header, &length);
+
+ assert_int_equal(status, F_data_not);
+ }
+}
+
void test__f_socket_write_message__works(void **state) {
f_socket_t socket = f_socket_t_initialize;
extern void test__f_socket_write_message__parameter_checking(void **state);
/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_socket_write_message()
+ */
+extern void test__f_socket_write_message__returns_data_not(void **state);
+
+/**
* Test that function works.
*
* @see f_socket_write_message()
}
}
+void test__f_socket_write_stream__returns_data_not(void **state) {
+
+ char * const buffer = "test";
+
+ {
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_write = 0;
+
+ const f_status_t status = f_socket_write_stream(&socket, 0, (void *) buffer, 0);
+
+ assert_int_equal(status, F_data_not);
+ }
+
+ {
+ size_t length = 0;
+ f_socket_t socket = f_socket_t_initialize;
+ socket.size_write = 0;
+
+ const f_status_t status = f_socket_write_stream(&socket, 0, (void *) buffer, &length);
+
+ assert_int_equal(status, F_data_not);
+ }
+}
+
void test__f_socket_write_stream__works(void **state) {
f_socket_t socket = f_socket_t_initialize;
extern void test__f_socket_write_stream__parameter_checking(void **state);
/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_socket_write_stream()
+ */
+extern void test__f_socket_write_stream__returns_data_not(void **state);
+
+/**
* Test that function works.
*
* @see f_socket_write_stream()
cmocka_unit_test(test__f_socket_option_set__works),
cmocka_unit_test(test__f_socket_read__fails),
+ cmocka_unit_test(test__f_socket_read__returns_data_not),
cmocka_unit_test(test__f_socket_read__works),
cmocka_unit_test(test__f_socket_read_message__fails),
+ cmocka_unit_test(test__f_socket_read_message__returns_data_not),
cmocka_unit_test(test__f_socket_read_message__works),
cmocka_unit_test(test__f_socket_read_stream__fails),
+ cmocka_unit_test(test__f_socket_read_stream__returns_data_not),
cmocka_unit_test(test__f_socket_read_stream__works),
cmocka_unit_test(test__f_socket_write__fails),
+ cmocka_unit_test(test__f_socket_write__returns_data_not),
cmocka_unit_test(test__f_socket_write__works),
cmocka_unit_test(test__f_socket_write_message__fails),
+ cmocka_unit_test(test__f_socket_write_message__returns_data_not),
cmocka_unit_test(test__f_socket_write_message__works),
cmocka_unit_test(test__f_socket_write_stream__fails),
+ cmocka_unit_test(test__f_socket_write_stream__returns_data_not),
cmocka_unit_test(test__f_socket_write_stream__works),
cmocka_unit_test(test__f_socket_addressss_destroy_callback__fails),