]> Kevux Git Server - fll/commitdiff
Update: Socket size_read/size_write checks, result == -1, and explicit passing .generic.
authorKevin Day <thekevinday@gmail.com>
Mon, 11 Dec 2023 06:26:27 +0000 (00:26 -0600)
committerKevin Day <thekevinday@gmail.com>
Mon, 11 Dec 2023 06:26:27 +0000 (00:26 -0600)
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.

15 files changed:
level_0/f_socket/c/socket.c
level_0/f_socket/c/socket.h
level_0/f_socket/tests/unit/c/test-socket-read.c
level_0/f_socket/tests/unit/c/test-socket-read.h
level_0/f_socket/tests/unit/c/test-socket-read_message.c
level_0/f_socket/tests/unit/c/test-socket-read_message.h
level_0/f_socket/tests/unit/c/test-socket-read_stream.c
level_0/f_socket/tests/unit/c/test-socket-read_stream.h
level_0/f_socket/tests/unit/c/test-socket-write.c
level_0/f_socket/tests/unit/c/test-socket-write.h
level_0/f_socket/tests/unit/c/test-socket-write_message.c
level_0/f_socket/tests/unit/c/test-socket-write_message.h
level_0/f_socket/tests/unit/c/test-socket-write_stream.c
level_0/f_socket/tests/unit/c/test-socket-write_stream.h
level_0/f_socket/tests/unit/c/test-socket.c

index 8289c58979f0006884c449582e0d4c2cf06f6e90..476bc8fcd4b02788b5ca13edf67bf38adf32c823 100644 (file)
@@ -10,7 +10,7 @@ extern "C" {
       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);
@@ -495,7 +495,7 @@ extern "C" {
       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);
@@ -517,9 +517,11 @@ extern "C" {
       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);
@@ -556,9 +558,11 @@ extern "C" {
       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);
@@ -595,9 +599,11 @@ extern "C" {
       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);
@@ -634,9 +640,11 @@ extern "C" {
       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);
@@ -676,9 +684,11 @@ extern "C" {
       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);
@@ -718,9 +728,11 @@ extern "C" {
       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);
index 66febd222d6bd587c05ddbdcfeecf9d2b7b8f5ed..ce33bf07d9862acb4e0dd92bda1cf1ac361214b3 100644 (file)
@@ -538,6 +538,7 @@ extern "C" {
  *
  * @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.
@@ -587,6 +588,7 @@ extern "C" {
  *
  * @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.
@@ -640,6 +642,7 @@ extern "C" {
  *
  * @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.
@@ -693,6 +696,7 @@ extern "C" {
  *
  * @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".
@@ -709,7 +713,7 @@ extern "C" {
  *   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.
@@ -746,6 +750,7 @@ extern "C" {
  *
  * @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".
@@ -762,7 +767,7 @@ extern "C" {
  *   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.
@@ -803,6 +808,7 @@ extern "C" {
  *
  * @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".
@@ -819,7 +825,7 @@ extern "C" {
  *   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.
index 71fbfb8a41bec66e1723b974646959e2c6094942..687835045b0d29598c1f7d4483576acd8f1ce7fe 100644 (file)
@@ -91,6 +91,30 @@ void test__f_socket_read__parameter_checking(void **state) {
   }
 }
 
+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;
index 1433a0a96ca78ab93b4f7436d2f684130209a97d..0189a7c951a6900b4dc182d11687a5a0064faf1e 100644 (file)
@@ -25,6 +25,13 @@ extern void test__f_socket_read__fails(void **state);
 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()
index 1f5bfd329c35840ee0336de3c2858cf59ce173ea..fd65e0f966e8617b31e2e7df6625427a2fed2b07 100644 (file)
@@ -94,6 +94,32 @@ void test__f_socket_read_message__parameter_checking(void **state) {
   }
 }
 
+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;
index 67883e584c3c6f40c950b4ab746c837a93fe681b..3393b0a06e7a2fd7f33e800db337d0468aff0391 100644 (file)
@@ -25,6 +25,13 @@ extern void test__f_socket_read_message__fails(void **state);
 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()
index e21fb24b366c759cbd9ca486ac2532e61ac463d7..d2fa6d0e4e61cf98768c945acde785842a007d3f 100644 (file)
@@ -91,6 +91,30 @@ void test__f_socket_read_stream__parameter_checking(void **state) {
   }
 }
 
+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;
index 67c3c75e3b172a4bf5f3ac84ded5350e574cb050..1790043aa34cce92a0580377ea94a3933c6b5ae6 100644 (file)
@@ -25,6 +25,13 @@ extern void test__f_socket_read_stream__fails(void **state);
 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()
index 3b6d8c3176150deebf34ee36604253dd506c5597..ee791b0130d8481d5f137c1daf08fe896d1d2f69 100644 (file)
@@ -97,6 +97,30 @@ void test__f_socket_write__parameter_checking(void **state) {
   }
 }
 
+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;
index d87c4eaf70cf868487059d95021871b81b608c26..6a3d3448dd3ea440b81d789fce88bb381de13aa2 100644 (file)
@@ -25,6 +25,13 @@ extern void test__f_socket_write__fails(void **state);
 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()
index c300c394146207278f37fb498146f6f41c33228a..3056e8275bcdd17b9b89ae7803a7647c8a89d1d7 100644 (file)
@@ -100,6 +100,32 @@ void test__f_socket_write_message__parameter_checking(void **state) {
   }
 }
 
+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;
index b96350fdb58c45090748f3013b996f58e7ea8852..475dc4078b8d4e8f22805e06d68642ea3c3d293d 100644 (file)
@@ -25,6 +25,13 @@ extern void test__f_socket_write_message__fails(void **state);
 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()
index f3b6511ca79d00a58d9660e846d463554337e75f..744c8aabb175913e58516db18894e5795a844a50 100644 (file)
@@ -97,6 +97,30 @@ void test__f_socket_write_stream__parameter_checking(void **state) {
   }
 }
 
+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;
index 5bc28e52f2b171a5e22e16f59141a9fb2dbb151b..414146de635aa96b88c191909d0e247eaf27eba3 100644 (file)
@@ -25,6 +25,13 @@ extern void test__f_socket_write_stream__fails(void **state);
 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()
index e521eac370377c375e796728a580c832246613ff..368682bfa42bba24ade88acaa592d5a1040b8844 100644 (file)
@@ -63,21 +63,27 @@ int main(void) {
     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),