]> Kevux Git Server - fll/commitdiff
Update: Socket bind functions, socket address family enumeration, and rename max_backlog.
authorKevin Day <kevin@kevux.org>
Sat, 8 Jul 2023 03:36:17 +0000 (22:36 -0500)
committerKevin Day <kevin@kevux.org>
Sat, 8 Jul 2023 03:36:17 +0000 (22:36 -0500)
Change the f_socket_bind_local() bind function to not call memset() and use the new address structure.
Add f_socket_bind_inet4() and f_socket_bind_inet6() bind functions in a similar way to f_socket_bind_local().

Update the appropriate documentation.
Add the appropriate unit tests.

The name max_backlog for f_socket_listen() is better named backlog_max as per the FLL style practices.

level_0/f_socket/c/socket.c
level_0/f_socket/c/socket.h
level_0/f_socket/c/socket/common.h
level_0/f_socket/data/build/settings-tests
level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-bind_local.c
level_0/f_socket/tests/unit/c/test-socket.c
level_0/f_socket/tests/unit/c/test-socket.h

index 209556ce996971f66b4f8dd93a4b137f24566935..1d9ece3c54f9267ce10e7ec823f28b5e533b5d0c 100644 (file)
@@ -72,6 +72,68 @@ extern "C" {
   }
 #endif // _di_f_socket_bind_
 
+#ifndef _di_f_socket_bind_inet4_
+  f_status_t f_socket_bind_inet4(f_socket_t * const socket) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!socket) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (socket->domain != f_socket_protocol_family_inet4_e) return F_status_set_error(F_address_not);
+
+    socket->address.inet4.sin_family = f_socket_address_family_inet4_e;
+    socket->length = sizeof(struct sockaddr_in);
+
+    if (bind(socket->id, (struct sockaddr *) &socket->address.inet4, socket->length) == -1) {
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+      if (errno == EADDRINUSE) return F_status_set_error(F_busy_address);
+      if (errno == EADDRNOTAVAIL) return F_status_set_error(F_available_not_address);
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ELOOP) return F_status_set_error(F_loop);
+      if (errno == ENAMETOOLONG) return F_status_set_error(F_string_too_large);
+      if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+      if (errno == ENOTDIR) return F_status_set_error(F_directory_found_not);
+      if (errno == ENOTSOCK) return F_status_set_error(F_socket_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_socket_bind_inet4_
+
+#ifndef _di_f_socket_bind_inet6_
+  f_status_t f_socket_bind_inet6(f_socket_t * const socket) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!socket) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (socket->domain != f_socket_protocol_family_inet6_e) return F_status_set_error(F_address_not);
+
+    socket->address.inet6.sin6_family = f_socket_address_family_inet6_e;
+    socket->length = sizeof(struct sockaddr_in6);
+
+    if (bind(socket->id, (struct sockaddr *) &socket->address.inet6, socket->length) == -1) {
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+      if (errno == EADDRINUSE) return F_status_set_error(F_busy_address);
+      if (errno == EADDRNOTAVAIL) return F_status_set_error(F_available_not_address);
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ELOOP) return F_status_set_error(F_loop);
+      if (errno == ENAMETOOLONG) return F_status_set_error(F_string_too_large);
+      if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+      if (errno == ENOTDIR) return F_status_set_error(F_directory_found_not);
+      if (errno == ENOTSOCK) return F_status_set_error(F_socket_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // _di_f_socket_bind_inet6_
+
 #ifndef _di_f_socket_bind_local_
   f_status_t f_socket_bind_local(f_socket_t * const socket) {
     #ifndef _di_level_0_parameter_checking_
@@ -80,23 +142,18 @@ extern "C" {
 
     if (socket->domain != f_socket_protocol_family_local_e) return F_status_set_error(F_local_not);
 
-    memset((void *) &socket->address, 0, sizeof(struct sockaddr_un));
+    socket->address.local.sun_family = f_socket_address_family_local_e;
+    socket->length = sizeof(struct sockaddr_un);
 
-    {
-      struct sockaddr_un *address = (struct sockaddr_un *) &socket->address;
-
-      address->sun_family = f_socket_address_family_local_e;
-
-      if (socket->name.used && socket->name.string) {
-        strncpy(address->sun_path, socket->name.string, socket->name.used);
-        address->sun_path[socket->name.used] = 0;
-      }
-      else {
-        address->sun_path[0] = 0;
-      }
+    if (socket->name.used && socket->name.string) {
+      memcpy((void *) socket->address.local.sun_path, (void *) socket->name.string, socket->name.used);
+      socket->address.local.sun_path[socket->name.used] = 0;
+    }
+    else {
+      socket->address.local.sun_path[0] = 0;
     }
 
-    if (bind(socket->id, (struct sockaddr *) &socket->address, sizeof(struct sockaddr_un)) == -1) {
+    if (bind(socket->id, (struct sockaddr *) &socket->address.local, socket->length) == -1) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
       if (errno == EADDRINUSE) return F_status_set_error(F_busy_address);
       if (errno == EADDRNOTAVAIL) return F_status_set_error(F_available_not_address);
@@ -254,12 +311,12 @@ extern "C" {
 #endif // _di_f_socket_disconnect_
 
 #ifndef _di_f_socket_listen_
-  f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int max_backlog) {
+  f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int backlog_max) {
     #ifndef _di_level_0_parameter_checking_
       if (!socket) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (listen(socket->id, max_backlog) == -1) {
+    if (listen(socket->id, backlog_max) == -1) {
       if (errno == EADDRINUSE) return F_status_set_error(F_busy_address);
       if (errno == EBADF) return F_status_set_error(F_file_descriptor);
       if (errno == ENOTSOCK) return F_status_set_error(F_socket_not);
index f017d29ea3b5ea0c4c3e6aa50c3c2c6743cd97d3..9ff3dc3d67edeea2ab2f3d59a6c65fbcb421930f 100644 (file)
@@ -103,13 +103,12 @@ extern "C" {
 /**
  * Bind a socket to a name.
  *
- * This does not initialize or otherwise memset() the address.
- *
  * @param socket
  *   The socket structure.
- *   The socket.address may point to any valid structure, like "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in".
+ *   The socket.address may be any valid structure, like "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in".
+ *   The socket.address.*.*_family is not directly altered by this function.
  *   The caller must appropriately initialize and configure the socket.address.
- *   The socket.length must represent the full size of the address structure.
+ *   The socket.length must represent the full size of the address structure and is not altered by this function.
  *   The socket.id must refer to a valid socket file descriptor.
  *
  * @return
@@ -136,16 +135,87 @@ extern "C" {
 #endif // _di_f_socket_bind_
 
 /**
- * Bind a socket to a local (UNIX) socket file.
+ * Bind a socket to an IPv4 address.
+ *
+ * @param socket
+ *   The socket to use.
+ *
+ *   The socket.address.inet4.sin_family is directly assigned to f_socket_address_family_inet4_e.
+ *   The socket.domain (potocol family) must be assigned to f_socket_protocol_family_inet4_e.
+ *   The socket.length is updated to represent the size of "struct sockaddr_in".
+ *   The socket.type (address family) will be assigned to f_socket_address_family_inet4_e.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_address (with error bit) if address is already in use (therefore unavailable).
+ *   F_address_not (with error bit) if socket.domain is not set to f_socket_protocol_family_inet4_e.
+ *   F_available_not_address (with error bit) if address is unavailable (is non-existent).
+ *   F_buffer (with error bit) if the buffer is invalid.
+ *   F_busy_address (with error bit) if address is already in use (therefore unavailable).
+ *   F_directory_found_not (with error bit) if directory was not found.
+ *   F_file_found_not (with error bit) if file not found.
+ *   F_memory_not (with error bit) if out of memory.
+ *   F_name (with error bit) on path name error.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_socket_not (with error bit) if the id is not a socket descriptor.
+ *   F_string_too_large (with error bit) if string is too large to store in the buffer.
+ *
+ *   F_failure (with error bit) for any other error.
  *
- * This does initialize and memset() the address with the address set to a UNIX socket (struct sockaddr_un).
+ * @see bind()
+ */
+#ifndef _di_f_socket_bind_inet4_
+  extern f_status_t f_socket_bind_inet4(f_socket_t * const socket);
+#endif // _di_f_socket_bind_inet4_
+
+/**
+ * Bind a socket to an IPv6 address.
  *
  * @param socket
- *   The socket structure.
- *   The socket.address must point to a "struct sockaddr_un".
+ *   The socket to use.
+ *
+ *   The socket.address.inet6.sin_family is directly assigned to f_socket_address_family_inet6_e.
+ *   The socket.domain (potocol family) must be assigned to f_socket_protocol_family_inet6_e.
+ *   The socket.length is updated to represent the size of "struct sockaddr_in6".
+ *   The socket.type (address family) will be assigned to f_socket_address_family_inet6_e.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_address (with error bit) if address is already in use (therefore unavailable).
+ *   F_address_not (with error bit) if socket.domain is not set to f_socket_protocol_family_inet6_e.
+ *   F_available_not_address (with error bit) if address is unavailable (is non-existent).
+ *   F_buffer (with error bit) if the buffer is invalid.
+ *   F_busy_address (with error bit) if address is already in use (therefore unavailable).
+ *   F_directory_found_not (with error bit) if directory was not found.
+ *   F_file_found_not (with error bit) if file not found.
+ *   F_memory_not (with error bit) if out of memory.
+ *   F_name (with error bit) on path name error.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_socket_not (with error bit) if the id is not a socket descriptor.
+ *   F_string_too_large (with error bit) if string is too large to store in the buffer.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see bind()
+ */
+#ifndef _di_f_socket_bind_inet6_
+  extern f_status_t f_socket_bind_inet6(f_socket_t * const socket);
+#endif // _di_f_socket_bind_inet6_
+
+/**
+ * Bind a socket to a local (UNIX) socket file.
+ *
+ * @param socket
+ *   The socket to use.
+ *
+ *   The socket.address.local.sun_family is directly assigned to f_socket_address_family_local_e.
+ *   The socket.address.local.sun_path is updated with the value from socket.name.string.
  *   The socket.domain (potocol family) must be assigned to f_socket_protocol_family_local_e.
- *   The socket.type (address family) will be assigned to f_socket_address_family_local_e.
+ *   The socket.length is updated to represent the size of "struct sockaddr_un".
  *   The socket.name must be assigned to a path.
+ *   The socket.type (address family) will be assigned to f_socket_address_family_local_e.
  *
  * @return
  *   F_none on success.
@@ -156,7 +226,7 @@ extern "C" {
  *   F_busy_address (with error bit) if address is already in use (therefore unavailable).
  *   F_directory_found_not (with error bit) if directory was not found.
  *   F_file_found_not (with error bit) if file not found.
- *   F_local_not (with erro bit) if domain in not a UNIX socket.
+ *   F_local_not (with error bit) if socket.domain is not set to f_socket_protocol_family_local_e.
  *   F_memory_not (with error bit) if out of memory.
  *   F_name (with error bit) on path name error.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -166,8 +236,7 @@ extern "C" {
  *   F_failure (with error bit) for any other error.
  *
  * @see bind()
- * @see memset()
- * @see strncpy()
+ * @see memcpy()
  */
 #ifndef _di_f_socket_bind_local_
   extern f_status_t f_socket_bind_local(f_socket_t * const socket);
@@ -333,7 +402,7 @@ extern "C" {
  * @param socket
  *   The socket structure.
  *   The socket.id must represent a valid socket file descriptor.
- * @param max_backlog
+ * @param backlog_max
  *   The max length of the pending connections queue.
  *   Suggested default setting: 8.
  *
@@ -350,7 +419,7 @@ extern "C" {
  * @see listen()
  */
 #ifndef _di_f_socket_listen_
-  extern f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int max_backlog);
+  extern f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int backlog_max);
 #endif // _di_f_socket_listen_
 
 /**
index b1ddf5d505e0264cf00aec926d3f9a0403c8e530..da8ebb641a00bb2e613a131a5229542f1bf96cf3 100644 (file)
@@ -37,49 +37,49 @@ extern "C" {
  *
  * f_socket_address_family_*_e:
  *   - unspecified: No protocol family specified.
- *   - local:       Localhost, pipes, Unix sockets, or file sockets (PF_LOCAL, PF_UNIX, PF_FILE).
- *   - inet:        IP protocol family.
- *   - ax25:        Amateur Radio AX.25.
- *   - ipx:         Novell Internet Protocol.
+ *   - alg:         Algorithm sockets.
  *   - appletalk:   Appletalk DDP.
- *   - netrom:      Amateur radio NetROM.
- *   - bridge:      Multiprotocol bridge.
+ *   - ash:         Ash.
  *   - atmpvc:      ATM PVCs.
- *   - x25:         Reserved for X.25 project.
- *   - inet6:       IP version 6.
- *   - rose:        Amateur Radio X.25 PLP.
+ *   - atmsvc:      ATM SVCs.
+ *   - ax25:        Amateur Radio AX.25.
+ *   - bluetooth:   Bluetooth sockets.
+ *   - bridge:      Multiprotocol bridge.
+ *   - caif:        CAIF sockets.
+ *   - can:         Controller Area Network.
  *   - decnet:      Reserved for DECnet project.
- *   - netbeui:     Reserved for 802.2LLC project.
- *   - security:    Security callback pseudo AF.
- *   - key:         PF_KEY key management API.
- *   - netlink:     Netlink and BSD (PF_NETLINK and PF_ROUTE).
- *   - packet:      Packet family.
- *   - ash:         Ash.
  *   - econet:      Acorn Econet.
- *   - atmsvc:      ATM SVCs.
- *   - rds:         RDS sockets.
- *   - sna:         Linux SNA Project.
+ *   - ib:          Native InfiniBand address.
+ *   - ieee802154:  IEEE 802.15.4 sockets.
+ *   - inet4:       IP version 4.
+ *   - inet6:       IP version 6.
+ *   - ipx:         Novell Internet Protocol.
  *   - irda:        IRDA sockets.
- *   - pppox:       PPPoX sockets.
- *   - wanpipe:     Wanpipe API sockets.
+ *   - isdn:        mISDN sockets.
+ *   - iucb:        IUCV sockets.
+ *   - kcm:         Kernel Connection Multiplexor.
+ *   - key:         PF_KEY key management API.
  *   - llc:         Linux LLC.
- *   - ib:          Native InfiniBand address.
+ *   - local:       Localhost, pipes, Unix sockets, or file sockets (PF_LOCAL, PF_UNIX, PF_FILE).
  *   - mpls:        MPLS.
- *   - can:         Controller Area Network.
- *   - tipc:        TIPC sockets.
- *   - bluetooth:   Bluetooth sockets.
- *   - iucb:        IUCV sockets.
- *   - rxrpc:       RxRPC sockets.
- *   - isdn:        mISDN sockets.
- *   - phonet:      Phonet sockets.
- *   - ieee802154:  IEEE 802.15.4 sockets.
- *   - caif:        CAIF sockets.
- *   - alg:         Algorithm sockets.
+ *   - netbeui:     Reserved for 802.2LLC project.
+ *   - netlink:     Netlink and BSD (PF_NETLINK and PF_ROUTE).
+ *   - netrom:      Amateur radio NetROM.
  *   - nfc:         NFC sockets.
- *   - vsock:       vSockets.
- *   - kcm:         Kernel Connection Multiplexor.
+ *   - packet:      Packet family.
+ *   - phonet:      Phonet sockets.
+ *   - pppox:       PPPoX sockets.
  *   - qipcrtr:     Qualcomm IPC Router.
+ *   - rds:         RDS sockets.
+ *   - rose:        Amateur Radio X.25 PLP.
+ *   - rxrpc:       RxRPC sockets.
+ *   - security:    Security callback pseudo AF.
  *   - smc:         SMC sockets.
+ *   - sna:         Linux SNA Project.
+ *   - tipc:        TIPC sockets.
+ *   - vsock:       vSockets.
+ *   - wanpipe:     Wanpipe API sockets.
+ *   - x25:         Reserved for X.25 project.
  *   - max:         The maximum value for known protocol families (this is not a protocol family).
  */
 #ifndef _di_f_socket_address_family_e_
@@ -99,7 +99,7 @@ extern "C" {
     f_socket_address_family_econet_e      = AF_ECONET,
     f_socket_address_family_ib_e          = AF_IB,
     f_socket_address_family_ieee802154_e  = AF_IEEE802154,
-    f_socket_address_family_inet_e        = AF_INET,
+    f_socket_address_family_inet4_e       = AF_INET,
     f_socket_address_family_inet6_e       = AF_INET6,
     f_socket_address_family_ipx_e         = AF_IPX,
     f_socket_address_family_irda_e        = AF_IRDA,
@@ -543,7 +543,7 @@ extern "C" {
  *   - econet:      Acorn Econet.
  *   - ib:          Native InfiniBand address.
  *   - ieee802154:  IEEE 802.15.4 sockets.
- *   - inet:        IP protocol family.
+ *   - inet4:       IP version 4.
  *   - inet6:       IP version 6.
  *   - ipx:         Novell Internet Protocol.
  *   - irda:        IRDA sockets.
@@ -591,7 +591,7 @@ extern "C" {
     f_socket_protocol_family_econet_e      = PF_ECONET,
     f_socket_protocol_family_ib_e          = PF_IB,
     f_socket_protocol_family_ieee802154_e  = PF_IEEE802154,
-    f_socket_protocol_family_inet_e        = PF_INET,
+    f_socket_protocol_family_inet4_e       = PF_INET,
     f_socket_protocol_family_inet6_e       = PF_INET6,
     f_socket_protocol_family_ipx_e         = PF_IPX,
     f_socket_protocol_family_irda_e        = PF_IRDA,
@@ -735,13 +735,13 @@ extern "C" {
  *
  * id:       File descriptor, with a value of -1 represents a closed file.
  * domain:   The socket domain (protocol family, such as f_socket_protocol_family_local_e).
- * protocol: The socket protocol(such as f_socket_protocol_tcp_e).
+ * protocol: The socket protocol (such as f_socket_protocol_tcp_e).
  * type:     The socket type (address family, such as f_socket_address_family_local_e).
  *
  * size_read:  The default number of 1-byte characters to read at a time and is often used for the read buffer size.
  * size_write: The default number of 1-byte characters to read at a time and is often used for the write buffer size.
  *
- * address: Tthe socket address.
+ * address: The socket address.
  * length:  The length of the socket.
  *
  * name: The name of the socket, if a name is given (for UNIX sockets this represents the path) (Must be a NULL terminated string).
index 7bb2229c07087f670cfc89b0064bd00613f32a6f..1795ff7d5428a9fa0c540c553861a3304ece3eef 100644 (file)
@@ -25,7 +25,7 @@ build_language c
 build_libraries -lc -lcmocka
 build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_socket
 
-build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-name_host.c test-socket-name_peer.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-read_stream.c test-socket-write.c test-socket-write_message.c test-socket-write_stream.c
+build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_inet4.c test-socket-bind_inet6.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-name_host.c test-socket-name_peer.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-read_stream.c test-socket-write.c test-socket-write_message.c test-socket-write_stream.c
 build_sources_program test-socket-sockets_adjust.c test-socket-sockets_append.c test-socket-sockets_append_all.c test-socket-sockets_decimate_by.c test-socket-sockets_decrease_by.c test-socket-sockets_increase.c test-socket-sockets_increase_by.c test-socket-sockets_resize.c
 build_sources_program test-socket-socketss_adjust.c test-socket-socketss_append.c test-socket-socketss_append_all.c test-socket-socketss_decimate_by.c test-socket-socketss_decrease_by.c test-socket-socketss_increase.c test-socket-socketss_increase_by.c test-socket-socketss_resize.c
 
diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c b/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c
new file mode 100644 (file)
index 0000000..9df5460
--- /dev/null
@@ -0,0 +1,102 @@
+#include "test-socket.h"
+#include "test-socket-bind_inet4.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_socket_bind_inet4__fails(void **state) {
+
+  int errnos[] = {
+    EACCES,
+    EADDRINUSE,
+    EADDRNOTAVAIL,
+    EFAULT,
+    EINVAL,
+    ELOOP,
+    ENAMETOOLONG,
+    ENOENT,
+    ENOMEM,
+    ENOTDIR,
+    ENOTSOCK,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_access_denied,
+    F_busy_address,
+    F_available_not_address,
+    F_buffer,
+    F_parameter,
+    F_loop,
+    F_string_too_large,
+    F_file_found_not,
+    F_memory_not,
+    F_directory_found_not,
+    F_socket_not,
+    F_failure,
+  };
+
+  {
+    f_socket_t socket = f_socket_t_initialize;
+    socket.domain = f_socket_protocol_family_inet4_e;
+    socket.protocol = f_socket_protocol_tcp_e;
+    socket.type = f_socket_address_family_inet4_e;
+
+    for (uint8_t i = 0; i < 12; ++i) {
+
+      will_return(__wrap_bind, true);
+      will_return(__wrap_bind, errnos[i]);
+
+      const f_status_t status = f_socket_bind_inet4(&socket);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+
+  {
+    f_socket_t socket = f_socket_t_initialize;
+    socket.domain = f_socket_protocol_family_inet4_e;
+    socket.protocol = f_socket_protocol_tcp_e;
+    socket.type = f_socket_address_family_inet4_e;
+
+    for (uint8_t i = 0; i < 12; ++i) {
+
+      will_return(__wrap_bind, true);
+      will_return(__wrap_bind, errnos[i]);
+
+      const f_status_t status = f_socket_bind_inet4(&socket);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_socket_bind_inet4__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_socket_bind_inet4(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_socket_bind_inet4__works(void **state) {
+
+  {
+    f_socket_t socket = f_socket_t_initialize;
+    socket.domain = f_socket_protocol_family_inet4_e;
+    socket.protocol = f_socket_protocol_tcp_e;
+    socket.type = f_socket_address_family_inet4_e;
+
+    will_return(__wrap_bind, false);
+
+    const f_status_t status = f_socket_bind_inet4(&socket);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h b/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h
new file mode 100644 (file)
index 0000000..9c556f1
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Socket
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the socket project.
+ */
+#ifndef _TEST__F_socket_bind_inet4_h
+#define _TEST__F_socket_bind_inet4_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_socket_bind_inet4()
+ */
+extern void test__f_socket_bind_inet4__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_socket_bind_inet4()
+ */
+extern void test__f_socket_bind_inet4__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_socket_bind_inet4()
+ */
+extern void test__f_socket_bind_inet4__works(void **state);
+
+#endif // _TEST__F_socket_bind_inet4_h
diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c b/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c
new file mode 100644 (file)
index 0000000..17bf2d5
--- /dev/null
@@ -0,0 +1,102 @@
+#include "test-socket.h"
+#include "test-socket-bind_inet6.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_socket_bind_inet6__fails(void **state) {
+
+  int errnos[] = {
+    EACCES,
+    EADDRINUSE,
+    EADDRNOTAVAIL,
+    EFAULT,
+    EINVAL,
+    ELOOP,
+    ENAMETOOLONG,
+    ENOENT,
+    ENOMEM,
+    ENOTDIR,
+    ENOTSOCK,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_access_denied,
+    F_busy_address,
+    F_available_not_address,
+    F_buffer,
+    F_parameter,
+    F_loop,
+    F_string_too_large,
+    F_file_found_not,
+    F_memory_not,
+    F_directory_found_not,
+    F_socket_not,
+    F_failure,
+  };
+
+  {
+    f_socket_t socket = f_socket_t_initialize;
+    socket.domain = f_socket_protocol_family_inet6_e;
+    socket.protocol = f_socket_protocol_tcp_e;
+    socket.type = f_socket_address_family_inet6_e;
+
+    for (uint8_t i = 0; i < 12; ++i) {
+
+      will_return(__wrap_bind, true);
+      will_return(__wrap_bind, errnos[i]);
+
+      const f_status_t status = f_socket_bind_inet6(&socket);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+
+  {
+    f_socket_t socket = f_socket_t_initialize;
+    socket.domain = f_socket_protocol_family_inet6_e;
+    socket.protocol = f_socket_protocol_tcp_e;
+    socket.type = f_socket_address_family_inet6_e;
+
+    for (uint8_t i = 0; i < 12; ++i) {
+
+      will_return(__wrap_bind, true);
+      will_return(__wrap_bind, errnos[i]);
+
+      const f_status_t status = f_socket_bind_inet6(&socket);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_socket_bind_inet6__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_socket_bind_inet6(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_socket_bind_inet6__works(void **state) {
+
+  {
+    f_socket_t socket = f_socket_t_initialize;
+    socket.domain = f_socket_protocol_family_inet6_e;
+    socket.protocol = f_socket_protocol_tcp_e;
+    socket.type = f_socket_address_family_inet6_e;
+
+    will_return(__wrap_bind, false);
+
+    const f_status_t status = f_socket_bind_inet6(&socket);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h b/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h
new file mode 100644 (file)
index 0000000..95d7af3
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Socket
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the socket project.
+ */
+#ifndef _TEST__F_socket_bind_inet6_h
+#define _TEST__F_socket_bind_inet6_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_socket_bind_inet6()
+ */
+extern void test__f_socket_bind_inet6__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_socket_bind_inet6()
+ */
+extern void test__f_socket_bind_inet6__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_socket_bind_inet6()
+ */
+extern void test__f_socket_bind_inet6__works(void **state);
+
+#endif // _TEST__F_socket_bind_inet6_h
index 05c0193c9d4b54f11f4fdf0c4d65ea76e6702e29..4fa04a8ac5fef0a20617fadac4b461255c71df82 100644 (file)
@@ -42,7 +42,6 @@ void test__f_socket_bind_local__fails(void **state) {
     socket.domain = f_socket_protocol_family_local_e;
     socket.protocol = f_socket_protocol_tcp_e;
     socket.type = f_socket_address_family_local_e;
-    socket.address.local.sun_family = f_socket_address_family_local_e;
 
     for (uint8_t i = 0; i < 12; ++i) {
 
@@ -60,7 +59,6 @@ void test__f_socket_bind_local__fails(void **state) {
     socket.domain = f_socket_protocol_family_local_e;
     socket.protocol = f_socket_protocol_tcp_e;
     socket.type = f_socket_address_family_local_e;
-    socket.address.local.sun_family = f_socket_address_family_local_e;
 
     for (uint8_t i = 0; i < 12; ++i) {
 
@@ -90,7 +88,6 @@ void test__f_socket_bind_local__works(void **state) {
     socket.domain = f_socket_protocol_family_local_e;
     socket.protocol = f_socket_protocol_tcp_e;
     socket.type = f_socket_address_family_local_e;
-    socket.address.local.sun_family = f_socket_address_family_local_e;
 
     will_return(__wrap_bind, false);
 
index 9f8dcf1f2b6066616ac93b2766d5ed078bfca7ee..3c0a00a7a140cc919de64c3d27e04c011ee5ff0b 100644 (file)
@@ -25,6 +25,12 @@ int main(void) {
     cmocka_unit_test(test__f_socket_bind__fails),
     cmocka_unit_test(test__f_socket_bind__works),
 
+    cmocka_unit_test(test__f_socket_bind_inet4__fails),
+    cmocka_unit_test(test__f_socket_bind_inet4__works),
+
+    cmocka_unit_test(test__f_socket_bind_inet6__fails),
+    cmocka_unit_test(test__f_socket_bind_inet6__works),
+
     cmocka_unit_test(test__f_socket_bind_local__fails),
     cmocka_unit_test(test__f_socket_bind_local__works),
 
@@ -113,6 +119,8 @@ int main(void) {
     #ifndef _di_level_0_parameter_checking_
       cmocka_unit_test(test__f_socket_accept__parameter_checking),
       cmocka_unit_test(test__f_socket_bind__parameter_checking),
+      cmocka_unit_test(test__f_socket_bind_inet4__parameter_checking),
+      cmocka_unit_test(test__f_socket_bind_inet6__parameter_checking),
       cmocka_unit_test(test__f_socket_bind_local__parameter_checking),
       cmocka_unit_test(test__f_socket_create__parameter_checking),
       cmocka_unit_test(test__f_socket_create_pair__parameter_checking),
index 9205b8f12a14dae0c55f9a93e6d55020487e8929..681ad712cea912720f471b9717364c662561d1f5 100644 (file)
@@ -28,6 +28,8 @@
 // Test includes.
 #include "test-socket-accept.h"
 #include "test-socket-bind.h"
+#include "test-socket-bind_inet4.h"
+#include "test-socket-bind_inet6.h"
 #include "test-socket-bind_local.h"
 #include "test-socket-connect.h"
 #include "test-socket-create.h"