Change in libosmocore[master]: socket: add function to wait until a socket becomes writeable

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

dexter gerrit-no-reply at lists.osmocom.org
Thu May 27 19:46:32 UTC 2021


dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/24435 )


Change subject: socket: add function to wait until a socket becomes writeable
......................................................................

socket: add function to wait until a socket becomes writeable

In cases where a socket is created using the option OSMO_SOCK_F_NONBLOCK
it is not possible to detect a connection error because
osmo_sock_init() will return early while the connection is still in
progress.

One way to make sure that the socket is connected is to use select to
wait until the socket becomes writeable and to use getsockopt to check
SO_ERROR.

The function osmo_sock_wait() waits until the socket becomes writeable.
From the error code the API user can determine whether the connection
was successful or not.

Change-Id: I1c68185120fa2a6c9b6cb8aa2a25232a44ff5508
Related: SYS#4971
---
M include/osmocom/core/socket.h
M src/socket.c
2 files changed, 53 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/35/24435/1

diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index a053391..ce6ee3c 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -113,7 +113,6 @@
 int osmo_sock_get_remote_ip(int fd, char *host, size_t len);
 int osmo_sock_get_remote_ip_port(int fd, char *port, size_t len);
 
-
 int osmo_sock_mcast_loop_set(int fd, bool enable);
 int osmo_sock_mcast_ttl_set(int fd, uint8_t ttl);
 int osmo_sock_mcast_all_set(int fd, bool enable);
@@ -134,5 +133,7 @@
 int osmo_sock_set_dscp(int fd, uint8_t dscp);
 int osmo_sock_set_priority(int fd, int prio);
 
+int osmo_sock_wait(int fd, time_t timeout_sec, suseconds_t timeout_usec);
+
 #endif /* (!EMBEDDED) */
 /*! @} */
diff --git a/src/socket.c b/src/socket.c
index 34972b8..810e39c 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -1868,6 +1868,57 @@
 	return setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio));
 }
 
+/*! Wait until a socket becomes writeable.
+ *  \param[in] fd file descriptor of related scoket.
+ *  \param[in] timeout_sec timeout seconds.
+ *  \param[in] timeout_usec timeout microseconds.
+ *  \returns 0 on success; negative otherwise
+ *
+ *  The function returns 0 when the socket becomes writeable and no errors are
+ *  detected. The return code is -EIO if one of the syscalls (select,
+ *  getsockopt) fails, -EINPROGRESS if the (select) timout expires while waiting
+ *  for the socket to become writeable. If the error is socket specific then the
+ *  SO_ERROR related return values from errno.h will be used. */
+int osmo_sock_wait(int fd, time_t timeout_sec, suseconds_t timeout_usec)
+{
+	int so_error;
+	socklen_t so_error_len = sizeof(so_error);
+	fd_set write_fds;
+	fd_set except_fds;
+	struct timeval timeout;
+	int rc;
+
+	timeout.tv_sec = timeout_sec;
+	timeout.tv_usec = timeout_usec;
+
+	/* We monitor the given file descriptor for writeability and
+	 * exceptional conditions. */
+	FD_ZERO(&write_fds);
+	FD_ZERO(&except_fds);
+	FD_SET(fd, &write_fds);
+	FD_SET(fd, &except_fds);
+	rc = select(fd + 1, NULL, &write_fds, &except_fds, &timeout);
+	if (rc < 0)
+		return -EIO;
+
+	/* The socket did not become writeable, nor did it exhibit any
+	 * exeptional behaviour (select timeout). */
+	if (rc == 0)
+		return -EINPROGRESS;
+
+	if (FD_ISSET(fd, &write_fds) || FD_ISSET(fd, &except_fds)) {
+		rc = getsockopt(fd, SOL_SOCKET, SO_ERROR, &so_error,
+				&so_error_len);
+		if (rc < 0)
+			return -EIO;
+		return so_error;	/* 0 if no error occured */
+	}
+
+	/* Should not be reached as either select will return 0 on timeout
+	 * or at least one of the fd sets will contain fd. */
+	return -EINVAL;
+}
+
 #endif /* HAVE_SYS_SOCKET_H */
 
 /*! @} */

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/24435
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I1c68185120fa2a6c9b6cb8aa2a25232a44ff5508
Gerrit-Change-Number: 24435
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210527/f42959dd/attachment.htm>


More information about the gerrit-log mailing list