diff --git a/components/net/sal/socket/net_sockets.c b/components/net/sal/socket/net_sockets.c index 63de88e870..c0662b13e5 100644 --- a/components/net/sal/socket/net_sockets.c +++ b/components/net/sal/socket/net_sockets.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -16,6 +16,31 @@ #include #include +/** + * @brief Accepts an incoming connection on a listening socket. + * + * This function extracts the first connection request from the queue of pending connections for + * the listening socket specified by 's' and creates a new socket for the connection. + * + * @param s The file descriptor of the listening socket. This socket must be created with + * 'socket()', bound with 'bind()', and set to listen with 'listen()'. + * @param addr A pointer to a 'sockaddr' structure that will receive the address of the connecting entity. + * This structure is filled with the address of the client once the connection is accepted. + * Can be 'NULL' if the address is not needed. + * @param addrlen A pointer to a variable containing the size of 'addr'. When the function returns, this + * variable will hold the actual size of the address returned. Can be 'NULL' if 'addr' is 'NULL'. + * + * @return On success, returns a new file descriptor for the accepted connection. On failure, returns '-1' + * and sets errno to indicate the error. + * + * @note The original socket 's' remains open and continues to listen for additional incoming connections. + * The returned file descriptor is used for communication with the connected client. + * + * @see socket() Creates a socket for accepting connections. + * @see bind() Binds the socket to a local address. + * @see listen() Sets the socket to listen for incoming connections. + * @see close()/closesocket() Closes a socket when it is no longer needed. + */ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { int new_socket = -1; @@ -71,6 +96,27 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) } RTM_EXPORT(accept); +/** + * @brief Binds a socket to a specific local address and port. + * + * This function assigns a local address to a socket, defined by the 'name' parameter. + * The address allows the socket to receive data sent to this address. + * + * @param s The file descriptor of the socket to bind. + * @param name A pointer to a 'sockaddr' structure that specifies the address to bind to. + * The structure varies based on the address family, such as 'sockaddr_in' for IPv4. + * @param namelen The length of the 'sockaddr' structure pointed to by 'name', in bytes. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The socket must be created with 'socket()' before calling 'bind()'. + * Binding is typically used for server sockets, specifying the local IP and port to listen on. + * If the port is set to '0', the system assigns an available port automatically. + * + * @see socket() Creates a socket for binding. + * @see listen() Prepares the socket to listen for incoming connections after binding. + * @see accept() Accepts connections on a bound and listening socket. + */ int bind(int s, const struct sockaddr *name, socklen_t namelen) { int socket = dfs_net_getsocket(s); @@ -79,6 +125,30 @@ int bind(int s, const struct sockaddr *name, socklen_t namelen) } RTM_EXPORT(bind); +/** + * @brief Shuts down part of a full-duplex connection on a socket. + * + * This function disables further sends or receives on the specified socket, depending on the value + * of the 'how' parameter. It does not close the socket, which must still be closed separately using + * 'close()' or 'closesocket()'. + * + * @param s The file descriptor of the socket to shut down. + * @param how Specifies the type of shutdown to perform. The 'how' parameter can be one of the following: + * - 'SHUT_RD': Disables further reading on the socket. The socket will not receive data. + * - 'SHUT_WR': Disables further writing on the socket. The socket will not send data. + * - 'SHUT_RDWR': Disables both reading and writing on the socket. The socket will be fully shut down. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'shutdown()' function is used to gracefully close a socket in one or both directions + * (read/write). It is commonly used in scenarios like closing the write side of a TCP connection + * when a server has finished sending data but still expects to receive data. + * + * @see socket() Creates the socket used for communication. + * @see close()/closesocket() Closes the socket after the shutdown is complete. + * @see recv() Receives data on a socket. + * @see send() Sends data on a socket. + */ int shutdown(int s, int how) { int error = 0; @@ -113,6 +183,28 @@ int shutdown(int s, int how) } RTM_EXPORT(shutdown); +/** + * @brief Retrieves the address of the peer connected to a socket. + * + * This function obtains the address of the peer (remote end) connected to the socket 's'. + * It is typically used on connected sockets (e.g., TCP) to retrieve information about the peer. + * + * @param s The file descriptor of the connected socket. + * @param name A pointer to a 'sockaddr' structure that will be filled with the address of the peer. + * The structure type (e.g., 'sockaddr_in' for IPv4) depends on the address family of the socket. + * @param namelen A pointer to a variable that initially specifies the size of the 'name' structure. + * On return, it contains the actual size of the address returned. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'getpeername()' function is useful for retrieving information about the remote end of a connection, + * such as the IP address and port of a peer in a TCP connection. This function is only valid for sockets + * that are in a connected state. + * + * @see socket() Creates the socket used for the connection. + * @see connect() Connects the socket to a remote address. + * @see getsockname() Retrieves the local address of a socket. + */ int getpeername(int s, struct sockaddr *name, socklen_t *namelen) { int socket = dfs_net_getsocket(s); @@ -121,6 +213,29 @@ int getpeername(int s, struct sockaddr *name, socklen_t *namelen) } RTM_EXPORT(getpeername); +/** + * @brief Retrieves the local address of a socket. + * + * This function obtains the local address (IP address and port) associated with the socket 's'. + * It is typically used to determine the local address and port of a bound or connected socket. + * + * @param s The file descriptor of the socket. + * @param name A pointer to a 'sockaddr' structure that will be filled with the local address + * of the socket. The structure type (e.g., 'sockaddr_in' for IPv4) depends on the + * address family of the socket. + * @param namelen A pointer to a variable that initially specifies the size of the 'name' structure. + * Upon return, this variable contains the actual size of the address returned. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'getsockname()' function is useful for retrieving the local address information of a socket, + * which can be especially useful in cases where the socket was bound with an ephemeral port (port 0), + * allowing you to discover the actual port number assigned by the system. + * + * @see socket() Creates the socket for communication. + * @see bind() Binds the socket to a specific local address. + * @see getpeername() Retrieves the address of the peer connected to a socket. + */ int getsockname(int s, struct sockaddr *name, socklen_t *namelen) { int socket = dfs_net_getsocket(s); @@ -129,6 +244,34 @@ int getsockname(int s, struct sockaddr *name, socklen_t *namelen) } RTM_EXPORT(getsockname); +/** + * @brief Retrieves options for a socket. + * + * This function retrieves the current value for a specified option on a socket, identified + * by the file descriptor 's'. The option is specified by the 'level' and 'optname' parameters. + * + * @param s The file descriptor of the socket from which to retrieve the option. + * @param level The protocol level at which the option resides. Common levels include: + * - 'SOL_SOCKET': To retrieve socket-level options. + * - 'IPPROTO_IP': To retrieve IPv4 options. + * - 'IPPROTO_TCP': To retrieve TCP options. + * @param optname The name of the option to retrieve. Some common options include: + * - 'SO_REUSEADDR': Checks if address reuse is enabled. + * - 'SO_RCVBUF': Retrieves the receive buffer size. + * - 'TCP_NODELAY': Checks if Nagle's algorithm is disabled for TCP sockets. + * @param optval A pointer to a buffer where the value of the option will be stored. + * The buffer must be large enough to hold the option value. + * @param optlen A pointer to a variable that initially specifies the size of 'optval'. + * On return, it contains the actual size of the option value returned. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'getsockopt()' function is useful for inspecting socket configuration and current settings. + * It can provide information about options such as buffer sizes, timeouts, and protocol-specific features. + * + * @see socket() Creates the socket to retrieve options from. + * @see setsockopt() Sets options for the socket. + */ int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { int socket = dfs_net_getsocket(s); @@ -137,6 +280,35 @@ int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) } RTM_EXPORT(getsockopt); +/** + * @brief Sets options on a socket. + * + * This function sets the specified option for the socket referenced by the file descriptor 's'. + * Socket options affect the behavior of the socket and are specified by the 'level' and 'optname' parameters. + * + * @param s The file descriptor of the socket on which to set the option. + * @param level The protocol level at which the option resides. Common levels include: + * - 'SOL_SOCKET': To configure socket-level options. + * - 'IPPROTO_IP': To configure IPv4 options. + * - 'IPPROTO_TCP': To configure TCP options. + * @param optname The name of the option to set. Some common options include: + * - 'SO_REUSEADDR': Allows reuse of local addresses. + * - 'SO_RCVBUF': Sets the receive buffer size. + * - 'TCP_NODELAY': Disables Nagle's algorithm for TCP sockets. + * @param optval A pointer to the buffer containing the value to set for the specified option. + * The type of data in this buffer depends on the option being set. + * @param optlen The size, in bytes, of the option value pointed to by 'optval'. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'setsockopt()' function is useful for configuring various socket behaviors, such as + * setting timeouts, buffer sizes, and enabling or disabling certain protocol features. + * The changes may affect socket performance and resource usage. + * + * @see socket() Creates the socket to configure. + * @see getsockopt() Retrieves options set on the socket. + * @see bind() Binds the socket to a local address. + */ int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) { int socket = dfs_net_getsocket(s); @@ -145,6 +317,29 @@ int setsockopt(int s, int level, int optname, const void *optval, socklen_t optl } RTM_EXPORT(setsockopt); +/** + * @brief Initiates a connection on a socket. + * + * This function connects the socket specified by 's' to the server address specified by 'name'. + * The socket must have been created with 'socket()' and, for some types of sockets, may need + * to be bound to a local address with 'bind()' before calling 'connect()'. + * + * @param s The file descriptor of the socket to connect. + * @param name A pointer to a 'sockaddr' structure that specifies the address of the server to connect to. + * The specific structure (e.g., 'sockaddr_in' for IPv4) depends on the address family. + * @param namelen The length, in bytes, of the address structure pointed to by 'name'. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note 'connect()' is typically used by client sockets to establish a connection with a server. + * For connection-oriented protocols (e.g., TCP), this initiates the connection handshake. + * For connectionless protocols (e.g., UDP), it defines a fixed peer address. + * + * @see socket() Creates the socket to be connected. + * @see bind() Binds the socket to a local address (optional for client sockets). + * @see accept() Used by server sockets to accept incoming connections. + * @see close()/closesocket() Closes the socket when done. + */ int connect(int s, const struct sockaddr *name, socklen_t namelen) { int socket = dfs_net_getsocket(s); @@ -152,6 +347,26 @@ int connect(int s, const struct sockaddr *name, socklen_t namelen) } RTM_EXPORT(connect); +/** + * @brief Marks a socket as a passive socket, ready to accept incoming connections. + * + * This function prepares a socket to accept incoming connection requests. The socket + * must first be created with 'socket()' and bound to a local address with 'bind()'. + * + * @param s The file descriptor of the socket to set to listening mode. + * @param backlog The maximum number of pending connections that can be queued for acceptance. + * If more incoming connections arrive than the backlog limit, they may be rejected + * or ignored until the server accepts some of the pending connections. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note After calling 'listen()', the socket can be used with 'accept()' to handle connection requests. + * The backlog size affects how many connections can wait to be accepted before being rejected. + * + * @see socket() Creates the socket. + * @see bind() Binds the socket to a specific address. + * @see accept() Accepts a pending connection request on the listening socket. + */ int listen(int s, int backlog) { int socket = dfs_net_getsocket(s); @@ -160,6 +375,31 @@ int listen(int s, int backlog) } RTM_EXPORT(listen); +/** + * @brief Receives data from a connected socket. + * + * This function reads data from a connected socket and stores it in the specified buffer. + * It is typically used with connection-oriented protocols (e.g., TCP). + * + * @param s The file descriptor of the connected socket to receive data from. + * @param mem A pointer to the buffer where the received data will be stored. + * @param len The maximum number of bytes to read into the buffer. + * @param flags Specifies the behavior of the receive operation. Common flags include: + * - '0': Default operation. + * - 'MSG_DONTWAIT': Non-blocking operation. + * - 'MSG_PEEK': Peeks at the incoming data without removing it from the queue. + * + * @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error. + * A return value of '0' indicates that the connection has been closed by the remote peer. + * + * @note The 'recv()' function may not receive all the requested bytes in a single call. + * Multiple calls to 'recv()' may be needed to read the complete data. + * + * @see socket() Creates the socket to be used for receiving data. + * @see connect() Connects the socket to a remote address (for connection-oriented protocols). + * @see recvfrom() Receives data from a specific address, typically used with connectionless sockets. + * @see send() Sends data on a connected socket. + */ int recv(int s, void *mem, size_t len, int flags) { int socket = dfs_net_getsocket(s); @@ -168,6 +408,36 @@ int recv(int s, void *mem, size_t len, int flags) } RTM_EXPORT(recv); +/** + * @brief Sends a message on a socket. + * + * The 'sendmsg()' function sends data on the socket 's' using the structured data in the 'msghdr' + * structure. This function is commonly used for sending complex messages with multiple buffers, + * control information, or for working with datagram sockets. + * + * @param s The file descriptor of the socket to send the message on. + * @param message A pointer to an 'msghdr' structure, which contains the data, address, and control information: + * - 'msg_name': Optional destination address (used for connectionless sockets). + * - 'msg_namelen': Size of the destination address. + * - 'msg_iov': An array of 'iovec' structures that point to the data buffers to be sent. + * - 'msg_iovlen': The number of elements in the 'msg_iov' array. + * - 'msg_control': Optional ancillary data, such as file descriptors for UNIX domain sockets. + * - 'msg_controllen': The size of the ancillary data buffer. + * - 'msg_flags': Flags related to the message. + * @param flags Specifies how the message should be sent. Common flags include: + * - 'MSG_DONTWAIT': Sends the message in non-blocking mode. + * - 'MSG_EOR': Indicates the end of a record (for record-oriented sockets). + * + * @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'sendmsg()' function is useful for sending messages with multiple buffers or ancillary data, + * allowing flexible communication options such as attaching file descriptors. This function can be + * used with both connection-oriented and connectionless sockets. + * + * @see recvmsg() Receives a message from a socket. + * @see send() Sends data on a socket. + * @see socket() Creates the socket to use with 'sendmsg()'. + */ int sendmsg(int s, const struct msghdr *message, int flags) { int socket = dfs_net_getsocket(s); @@ -176,6 +446,38 @@ int sendmsg(int s, const struct msghdr *message, int flags) } RTM_EXPORT(sendmsg); +/** + * @brief Receives a message from a socket. + * + * The 'recvmsg()' function receives data from the socket 's' into the buffers described by + * the 'msghdr' structure. This function allows for complex data structures, including multiple + * data buffers and optional control information. + * + * @param s The file descriptor of the socket to receive data from. + * @param message A pointer to an 'msghdr' structure, which will be filled with the received data and + * information. The structure contains: + * - 'msg_name': A buffer for the source address (used for connectionless sockets). + * - 'msg_namelen': Specifies the size of the 'msg_name' buffer. + * - 'msg_iov': An array of 'iovec' structures that point to the buffers to store received data. + * - 'msg_iovlen': The number of elements in the 'msg_iov' array. + * - 'msg_control': A buffer for ancillary data, such as received file descriptors. + * - 'msg_controllen': The size of the ancillary data buffer. + * - 'msg_flags': Flags set by the 'recvmsg()' call to indicate the message status. + * @param flags Specifies how the message should be received. Common flags include: + * - 'MSG_DONTWAIT': Receives the message in non-blocking mode. + * - 'MSG_PEEK': Peeks at the incoming message without removing it from the queue. + * - 'MSG_WAITALL': Waits for the full amount of data to be received. + * + * @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note The 'recvmsg()' function is useful for receiving messages with multiple buffers or ancillary data. + * It can be used with both connection-oriented and connectionless sockets, making it versatile for + * different communication needs. + * + * @see sendmsg() Sends a message on a socket. + * @see recv() Receives data on a socket. + * @see socket() Creates the socket used with 'recvmsg()'. + */ int recvmsg(int s, struct msghdr *message, int flags) { int socket = dfs_net_getsocket(s); @@ -184,6 +486,36 @@ int recvmsg(int s, struct msghdr *message, int flags) } RTM_EXPORT(recvmsg); +/** + * @brief Receives data from a specific address using an unconnected socket. + * + * This function reads data from a socket and stores it in the specified buffer. It is commonly used + * with connectionless protocols (e.g., UDP) to receive data from a specific source address. + * + * @param s The file descriptor of the socket to receive data from. + * @param mem A pointer to the buffer where the received data will be stored. + * @param len The maximum number of bytes to read into the buffer. + * @param flags Specifies the behavior of the receive operation. Common flags include: + * - '0': Default operation. + * - 'MSG_DONTWAIT': Non-blocking operation. + * - 'MSG_PEEK': Peeks at the incoming data without removing it from the queue. + * @param from A pointer to a 'sockaddr' structure that will be filled with the address of the + * sending entity. This is the source address from which the data was received. + * @param fromlen A pointer to a variable that initially contains the size of the 'from' structure. + * Upon return, this variable will hold the actual size of the address returned. + * + * @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error. + * A return value of '0' indicates that the connection has been closed by the remote peer. + * + * @note The 'recvfrom()' function is useful for receiving data from an arbitrary source address, + * which makes it especially suited for connectionless protocols where the peer's address may vary. + * The 'from' parameter is filled with the sender's address, which can be useful for identifying + * the origin of the data. + * + * @see socket() Creates the socket used for receiving data. + * @see sendto() Sends data to a specific address, typically used with connectionless sockets. + * @see recv() Receives data on a connected socket. + */ int recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { @@ -193,6 +525,32 @@ int recvfrom(int s, void *mem, size_t len, int flags, } RTM_EXPORT(recvfrom); +/** + * @brief Sends data on a connected socket. + * + * This function sends data to a connected socket, specified by the file descriptor 's'. + * It is typically used with connection-oriented protocols (e.g., TCP). + * + * @param s The file descriptor of the socket to send data on. + * The socket must be connected to a remote peer. + * @param dataptr A pointer to the buffer containing the data to send. + * @param size The size, in bytes, of the data to be sent from the buffer. + * @param flags Specifies the behavior of the send operation. Common flags include: + * - '0': Default operation. + * - 'MSG_DONTWAIT': Non-blocking operation. + * - 'MSG_NOSIGNAL': Prevents the sending of 'SIGPIPE' on errors. + * + * @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error. + * If the connection is closed by the remote peer, the return value may be '0'. + * + * @note The 'send()' function does not guarantee that all data will be sent in a single call. + * If fewer bytes are sent than requested, the remaining data should be sent in subsequent calls. + * + * @see socket() Creates the socket to be used for sending data. + * @see connect() Connects the socket to a remote address (for connection-oriented protocols). + * @see sendto() Sends data to a specific address, typically used with connectionless sockets. + * @see recv() Receives data from a connected socket. + */ int send(int s, const void *dataptr, size_t size, int flags) { int socket = dfs_net_getsocket(s); @@ -201,6 +559,34 @@ int send(int s, const void *dataptr, size_t size, int flags) } RTM_EXPORT(send); +/** + * @brief Sends data to a specific address using an unconnected socket. + * + * This function is typically used with connectionless protocols (e.g., UDP) to send data + * to a specific destination address, as specified by 'to'. + * + * @param s The file descriptor of the socket to send data on. + * @param dataptr A pointer to the buffer containing the data to be sent. + * @param size The size, in bytes, of the data to be sent from the buffer. + * @param flags Specifies the behavior of the send operation. Common flags include: + * - '0': Default operation. + * - 'MSG_DONTWAIT': Non-blocking operation. + * - 'MSG_NOSIGNAL': Prevents the sending of 'SIGPIPE' on errors. + * @param to A pointer to a 'sockaddr' structure that specifies the destination address. + * The structure type (e.g., 'sockaddr_in' for IPv4) depends on the address family. + * @param tolen The length, in bytes, of the address structure pointed to by 'to'. + * + * @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note Unlike 'send()', 'sendto()' can specify a target address for each message, allowing it to be used + * for both connected and unconnected sockets. In connectionless protocols, 'sendto()' is commonly + * used without prior calls to 'connect()'. + * + * @see socket() Creates the socket used for sending data. + * @see recvfrom() Receives data from a specific address, typically used with connectionless sockets. + * @see connect() Optional for connection-oriented protocols. + * @see send() Sends data on a connected socket. + */ int sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) { @@ -210,6 +596,38 @@ int sendto(int s, const void *dataptr, size_t size, int flags, } RTM_EXPORT(sendto); +/** + * @brief Creates a network socket. + * + * This function creates a socket and returns a file descriptor that can be used for network communication. + * + * @param domain The communication protocol family (address family) that defines the socket's protocol. + * Common values include: + * - 'AF_INET': IPv4 + * - 'AF_INET6': IPv6 + * - 'AF_UNIX': Local communication (inter-process communication on the same machine) + * - 'AF_AT': AT socket + * - 'AF_WIZ': WIZnet + * @param type The type of socket, which determines the characteristics of data transmission. + * Common values include: + * - 'SOCK_STREAM': Connection-oriented byte stream communication (e.g., TCP) + * - 'SOCK_DGRAM': Connectionless datagram communication (e.g., UDP) + * - 'SOCK_RAW': Provides raw network protocol access + * @param protocol Specifies the protocol to be used with the socket. It is usually set to '0', + * which allows the system to choose the default protocol: + * - For 'SOCK_STREAM', the default is TCP. + * - For 'SOCK_DGRAM', the default is UDP. + * + * @return On success, returns a file descriptor (a non-negative integer) representing the socket. + * On failure, returns '-1' and sets errno to indicate the error. + * + * @note The created socket can be used for binding, listening, receiving, and sending data. + * + * @see bind() Used to bind the socket to a local address. + * @see listen() Used to set the socket to listen for incoming connections. + * @see accept() Used to accept incoming connection requests. + * @see connect() Used to connect to a remote host. + */ int socket(int domain, int type, int protocol) { /* create a BSD socket */ @@ -262,6 +680,25 @@ int socket(int domain, int type, int protocol) } RTM_EXPORT(socket); +/** + * @brief Closes a socket. + * + * This function closes the socket specified by the file descriptor 's'. Once closed, the socket + * can no longer be used for communication. Any pending data that has not been transmitted may be lost. + * + * @param s The file descriptor of the socket to close. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. + * + * @note After calling 'closesocket()', the socket descriptor becomes invalid. The socket cannot + * be used for further communication or operations. It is important to close sockets when they are no longer needed + * to release system resources. + * + * @see socket() Creates a socket. + * @see shutdown() Shuts down the socket for reading and/or writing, without closing it. + * @see recv() Receives data from a socket. + * @see send() Sends data on a socket. + */ int closesocket(int s) { int error = 0; @@ -305,7 +742,32 @@ int closesocket(int s) } RTM_EXPORT(closesocket); - +/** + * @brief Creates a pair of connected sockets. + * + * The 'socketpair()' function creates two connected sockets, which can be used for bidirectional + * communication between processes or threads on the same machine. This is commonly used for inter-process + * communication (IPC) in UNIX-like operating systems. + * + * @param domain The communication domain (or protocol family). Typically, 'AF_UNIX' (or 'AF_LOCAL') + * is used to create sockets for local communication. + * @param type The type of socket to be created. Common values include: + * - 'SOCK_STREAM': Provides reliable, connection-oriented communication. + * - 'SOCK_DGRAM': Provides connectionless, unreliable communication. + * @param protocol The protocol to be used with the sockets. Normally set to '0' to use the default protocol + * for the specified 'domain' and 'type'. + * @param fds An array of two integers where the file descriptors for the two connected sockets will be stored. + * After a successful call, 'fds[0]' and 'fds[1]' represent the two ends of the socket pair. + * + * @return Returns '0' on success. On failure, returns '-1' and sets 'errno' to indicate the error. + * + * @note The 'socketpair()' function is commonly used to create a communication channel between two processes + * (parent and child after 'fork()') or two threads. Data written to one socket is available for reading + * from the other. It is primarily supported on UNIX-like systems and may not be available on Windows. + * + * @see socket() Creates a single socket for network communication. + * @see pipe() Creates an unidirectional communication channel between processes. + */ int socketpair(int domain, int type, int protocol, int *fds) { rt_err_t ret = 0; @@ -342,6 +804,32 @@ int socketpair(int domain, int type, int protocol, int *fds) } RTM_EXPORT(socketpair); +/** + * @brief Controls socket I/O modes. + * + * The 'ioctlsocket()' function manipulates the I/O mode of the socket specified by the file descriptor 's'. + * It is primarily used to enable or disable non-blocking mode on a socket or to perform other socket-specific + * operations. + * + * @param s The file descriptor of the socket to control. + * @param cmd The command that specifies the operation to perform. Some common commands include: + * - 'FIONBIO': Enables or disables non-blocking mode. Setting 'arg' to a non-zero value + * enables non-blocking mode; setting it to zero disables it. + * - 'FIONREAD': Retrieves the number of bytes available to read, storing the result in 'arg'. + * @param arg A pointer to an argument for the command. The type and meaning of this argument depend on the + * specified command ('cmd'). For example, in non-blocking mode ('FIONBIO'), it points to a 'long' + * that is either non-zero (to enable) or zero (to disable) non-blocking mode. + * + * @return Returns '0' on success. On failure, returns '-1' and sets errno (or 'WSAGetLastError()' on Windows) to indicate the error. + * + * @note This function is specific to Windows environments and is a part of the Winsock API. It performs + * similar functionality to the 'fcntl()' function on UNIX-like systems. + * The 'ioctlsocket()' function allows for various socket manipulations that affect how the socket + * operates in certain conditions, such as setting it to non-blocking mode. + * + * @see socket() Creates a socket to use with 'ioctlsocket()'. + * @see fcntl() Performs similar operations on UNIX-like systems. + */ int ioctlsocket(int s, long cmd, void *arg) { int socket = dfs_net_getsocket(s);