You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/11 15:28:15 UTC
[nuttx] branch master updated: net_socket: add accept4 function
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 48c9d10336 net_socket: add accept4 function
48c9d10336 is described below
commit 48c9d1033659603663f6e35587cf27045a130e0d
Author: zhanghongyu <zh...@xiaomi.com>
AuthorDate: Fri Nov 18 18:16:19 2022 +0800
net_socket: add accept4 function
Signed-off-by: zhanghongyu <zh...@xiaomi.com>
---
drivers/usrsock/usrsock_rpmsg_server.c | 7 ++--
drivers/video/vnc/vnc_server.c | 2 +-
include/nuttx/net/net.h | 4 ++-
include/sys/socket.h | 2 ++
include/sys/syscall_lookup.h | 1 +
net/inet/inet_sockif.c | 5 ++-
net/socket/accept.c | 63 +++++++++++++++++++++++++++++-----
syscall/syscall.csv | 1 +
8 files changed, 69 insertions(+), 16 deletions(-)
diff --git a/drivers/usrsock/usrsock_rpmsg_server.c b/drivers/usrsock/usrsock_rpmsg_server.c
index 2795a55e3c..56d423efcb 100644
--- a/drivers/usrsock/usrsock_rpmsg_server.c
+++ b/drivers/usrsock/usrsock_rpmsg_server.c
@@ -785,13 +785,10 @@ static int usrsock_rpmsg_accept_handler(FAR struct rpmsg_endpoint *ept,
nxrmutex_unlock(&priv->mutex);
ret = psock_accept(&priv->socks[req->usockid],
outaddrlen ? (FAR struct sockaddr *)(ack + 1) : NULL,
- outaddrlen ? &outaddrlen : NULL, &priv->socks[i]);
+ outaddrlen ? &outaddrlen : NULL, &priv->socks[i],
+ SOCK_NONBLOCK);
if (ret >= 0)
{
- int nonblock = 1;
-
- psock_ioctl(&priv->socks[i], FIONBIO, &nonblock);
-
/* Append index as usockid to the payload */
if (outaddrlen <= inaddrlen)
diff --git a/drivers/video/vnc/vnc_server.c b/drivers/video/vnc/vnc_server.c
index fada149e33..f0d79158f8 100644
--- a/drivers/video/vnc/vnc_server.c
+++ b/drivers/video/vnc/vnc_server.c
@@ -185,7 +185,7 @@ static int vnc_connect(FAR struct vnc_session_s *session, int port)
ginfo("Accepting connection for Display %d\n", session->display);
- ret = psock_accept(&session->listen, NULL, NULL, &session->connect);
+ ret = psock_accept(&session->listen, NULL, NULL, &session->connect, 0);
if (ret < 0)
{
goto errout_with_listener;
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index bdabcbaf83..5e5cec7b0f 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -700,6 +700,7 @@ int psock_listen(FAR struct socket *psock, int backlog);
* addrlen Input: allocated size of 'addr', Return: returned size of
* 'addr'
* newsock Location to return the accepted socket information.
+ * flags The flags used for initialization
*
* Returned Value:
* Returns zero (OK) on success. On failure, it returns a negated errno
@@ -734,7 +735,8 @@ int psock_listen(FAR struct socket *psock, int backlog);
****************************************************************************/
int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
- FAR socklen_t *addrlen, FAR struct socket *newsock);
+ FAR socklen_t *addrlen, FAR struct socket *newsock,
+ int flags);
/****************************************************************************
* Name: psock_connect
diff --git a/include/sys/socket.h b/include/sys/socket.h
index 28cd271491..d54c38f542 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -387,6 +387,8 @@ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen);
+int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
+ int flags);
ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h
index fdfbb710a9..5a75cb4dd0 100644
--- a/include/sys/syscall_lookup.h
+++ b/include/sys/syscall_lookup.h
@@ -348,6 +348,7 @@ SYSCALL_LOOKUP(munmap, 2)
#ifdef CONFIG_NET
SYSCALL_LOOKUP(accept, 3)
+ SYSCALL_LOOKUP(accept4, 4)
SYSCALL_LOOKUP(bind, 3)
SYSCALL_LOOKUP(connect, 3)
SYSCALL_LOOKUP(getpeername, 3)
diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index 85f12a0521..7c2b30cfcb 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -1936,6 +1936,8 @@ static int inet_socketpair(FAR struct socket *psocks[2])
#if defined(CONFIG_NET_TCP)
if (psocks[0]->s_type == SOCK_STREAM)
{
+ FAR struct socket_conn_s *conn = psocks[1]->s_conn;
+
ret = psock_listen(pserver, 2);
if (ret < 0)
{
@@ -1954,7 +1956,8 @@ static int inet_socketpair(FAR struct socket *psocks[2])
psock_close(psocks[1]);
- ret = psock_accept(pserver, &addr[1].addr, &len, psocks[1]);
+ ret = psock_accept(pserver, &addr[1].addr, &len, psocks[1],
+ conn->s_flags & _SF_NONBLOCK ? SOCK_NONBLOCK : 0);
}
#endif /* CONFIG_NET_TCP */
diff --git a/net/socket/accept.c b/net/socket/accept.c
index 14491128c3..c0a2cc0eb3 100644
--- a/net/socket/accept.c
+++ b/net/socket/accept.c
@@ -78,6 +78,7 @@
* addrlen Input: allocated size of 'addr', Return: returned size
* of 'addr'
* newsock Location to return the accepted socket information.
+ * flags The flags used for initialization
*
* Returned Value:
* Returns 0 (OK) on success. On failure, it returns a negated errno value
@@ -111,7 +112,8 @@
****************************************************************************/
int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
- FAR socklen_t *addrlen, FAR struct socket *newsock)
+ FAR socklen_t *addrlen, FAR struct socket *newsock,
+ int flags)
{
FAR struct socket_conn_s *conn;
int ret;
@@ -148,6 +150,10 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
conn = newsock->s_conn;
conn->s_flags |= _SF_CONNECTED;
conn->s_flags &= ~_SF_CLOSED;
+ if (flags & SOCK_NONBLOCK)
+ {
+ conn->s_flags |= _SF_NONBLOCK;
+ }
}
else
{
@@ -159,10 +165,10 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
}
/****************************************************************************
- * Name: accept
+ * Name: accept4
*
* Description:
- * The accept function is used with connection-based socket types
+ * The accept4 function is used with connection-based socket types
* (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
* connection request on the queue of pending connections, creates a new
* connected socket with mostly the same properties as 'sockfd', and
@@ -190,6 +196,7 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
* addr Receives the address of the connecting client
* addrlen Input: allocated size of 'addr',
* Return: returned size of 'addr'
+ * flags The flags used for initialization
*
* Returned Value:
* Returns -1 on error. If it succeeds, it returns a non-negative integer
@@ -227,18 +234,26 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
*
****************************************************************************/
-int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
+int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
+ int flags)
{
- FAR struct socket *psock;
+ FAR struct socket *psock = NULL;
FAR struct socket *newsock;
+ int oflags = O_RDWR;
int errcode;
int newfd;
int ret;
- /* accept() is a cancellation point */
+ /* accept4() is a cancellation point */
enter_cancellation_point();
+ if (flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC))
+ {
+ errcode = EINVAL;
+ goto errout;
+ }
+
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
@@ -258,7 +273,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
goto errout;
}
- ret = psock_accept(psock, addr, addrlen, newsock);
+ ret = psock_accept(psock, addr, addrlen, newsock, flags);
if (ret < 0)
{
errcode = -ret;
@@ -269,7 +284,17 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
* cannot fail later)
*/
- newfd = sockfd_allocate(newsock, O_RDWR);
+ if (flags & SOCK_CLOEXEC)
+ {
+ oflags |= O_CLOEXEC;
+ }
+
+ if (flags & SOCK_NONBLOCK)
+ {
+ oflags |= O_NONBLOCK;
+ }
+
+ newfd = sockfd_allocate(newsock, oflags);
if (newfd < 0)
{
errcode = ENFILE;
@@ -291,3 +316,25 @@ errout:
_SO_SETERRNO(psock, errcode);
return ERROR;
}
+
+/****************************************************************************
+ * Name: accept
+ *
+ * Description:
+ * The accept() call is identical to accept4() with a zero flags.
+ *
+ * Input Parameters:
+ * sockfd The listening socket descriptor
+ * addr Receives the address of the connecting client
+ * addrlen Input: allocated size of 'addr',
+ * Return: returned size of 'addr'
+ *
+ * Returned Value:
+ * (see accept4)
+ *
+ ****************************************************************************/
+
+int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
+{
+ return accept4(sockfd, addr, addrlen, 0);
+}
diff --git a/syscall/syscall.csv b/syscall/syscall.csv
index ecf735fe89..042f276060 100644
--- a/syscall/syscall.csv
+++ b/syscall/syscall.csv
@@ -1,6 +1,7 @@
"_exit","unistd.h","","noreturn","int"
"_assert","assert.h","","void","FAR const char *","int"
"accept","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *"
+"accept4","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *","int"
"adjtime","sys/time.h","defined(CONFIG_CLOCK_TIMEKEEPING)","int","FAR const struct timeval *","FAR struct timeval *"
"aio_cancel","aio.h","defined(CONFIG_FS_AIO)","int","int","FAR struct aiocb *"
"aio_fsync","aio.h","defined(CONFIG_FS_AIO)","int","int","FAR struct aiocb *"