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 *"