net_socket: add accept4 function

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2022-11-18 18:16:19 +08:00 committed by Xiang Xiao
parent 47d628d22e
commit 48c9d10336
8 changed files with 69 additions and 16 deletions

View file

@ -785,13 +785,10 @@ static int usrsock_rpmsg_accept_handler(FAR struct rpmsg_endpoint *ept,
nxrmutex_unlock(&priv->mutex); nxrmutex_unlock(&priv->mutex);
ret = psock_accept(&priv->socks[req->usockid], ret = psock_accept(&priv->socks[req->usockid],
outaddrlen ? (FAR struct sockaddr *)(ack + 1) : NULL, outaddrlen ? (FAR struct sockaddr *)(ack + 1) : NULL,
outaddrlen ? &outaddrlen : NULL, &priv->socks[i]); outaddrlen ? &outaddrlen : NULL, &priv->socks[i],
SOCK_NONBLOCK);
if (ret >= 0) if (ret >= 0)
{ {
int nonblock = 1;
psock_ioctl(&priv->socks[i], FIONBIO, &nonblock);
/* Append index as usockid to the payload */ /* Append index as usockid to the payload */
if (outaddrlen <= inaddrlen) if (outaddrlen <= inaddrlen)

View file

@ -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); 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) if (ret < 0)
{ {
goto errout_with_listener; goto errout_with_listener;

View file

@ -700,6 +700,7 @@ int psock_listen(FAR struct socket *psock, int backlog);
* addrlen Input: allocated size of 'addr', Return: returned size of * addrlen Input: allocated size of 'addr', Return: returned size of
* 'addr' * 'addr'
* newsock Location to return the accepted socket information. * newsock Location to return the accepted socket information.
* flags The flags used for initialization
* *
* Returned Value: * Returned Value:
* Returns zero (OK) on success. On failure, it returns a negated errno * 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, 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 * Name: psock_connect

View file

@ -387,6 +387,8 @@ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen);
int listen(int sockfd, int backlog); int listen(int sockfd, int backlog);
int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen); 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 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, ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,

View file

@ -348,6 +348,7 @@ SYSCALL_LOOKUP(munmap, 2)
#ifdef CONFIG_NET #ifdef CONFIG_NET
SYSCALL_LOOKUP(accept, 3) SYSCALL_LOOKUP(accept, 3)
SYSCALL_LOOKUP(accept4, 4)
SYSCALL_LOOKUP(bind, 3) SYSCALL_LOOKUP(bind, 3)
SYSCALL_LOOKUP(connect, 3) SYSCALL_LOOKUP(connect, 3)
SYSCALL_LOOKUP(getpeername, 3) SYSCALL_LOOKUP(getpeername, 3)

View file

@ -1936,6 +1936,8 @@ static int inet_socketpair(FAR struct socket *psocks[2])
#if defined(CONFIG_NET_TCP) #if defined(CONFIG_NET_TCP)
if (psocks[0]->s_type == SOCK_STREAM) if (psocks[0]->s_type == SOCK_STREAM)
{ {
FAR struct socket_conn_s *conn = psocks[1]->s_conn;
ret = psock_listen(pserver, 2); ret = psock_listen(pserver, 2);
if (ret < 0) if (ret < 0)
{ {
@ -1954,7 +1956,8 @@ static int inet_socketpair(FAR struct socket *psocks[2])
psock_close(psocks[1]); 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 */ #endif /* CONFIG_NET_TCP */

View file

@ -78,6 +78,7 @@
* addrlen Input: allocated size of 'addr', Return: returned size * addrlen Input: allocated size of 'addr', Return: returned size
* of 'addr' * of 'addr'
* newsock Location to return the accepted socket information. * newsock Location to return the accepted socket information.
* flags The flags used for initialization
* *
* Returned Value: * Returned Value:
* Returns 0 (OK) on success. On failure, it returns a negated errno 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, 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; FAR struct socket_conn_s *conn;
int ret; int ret;
@ -148,6 +150,10 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
conn = newsock->s_conn; conn = newsock->s_conn;
conn->s_flags |= _SF_CONNECTED; conn->s_flags |= _SF_CONNECTED;
conn->s_flags &= ~_SF_CLOSED; conn->s_flags &= ~_SF_CLOSED;
if (flags & SOCK_NONBLOCK)
{
conn->s_flags |= _SF_NONBLOCK;
}
} }
else else
{ {
@ -159,10 +165,10 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
} }
/**************************************************************************** /****************************************************************************
* Name: accept * Name: accept4
* *
* Description: * 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 * (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
* connection request on the queue of pending connections, creates a new * connection request on the queue of pending connections, creates a new
* connected socket with mostly the same properties as 'sockfd', and * 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 * addr Receives the address of the connecting client
* addrlen Input: allocated size of 'addr', * addrlen Input: allocated size of 'addr',
* Return: returned size of 'addr' * Return: returned size of 'addr'
* flags The flags used for initialization
* *
* Returned Value: * Returned Value:
* Returns -1 on error. If it succeeds, it returns a non-negative integer * 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; FAR struct socket *newsock;
int oflags = O_RDWR;
int errcode; int errcode;
int newfd; int newfd;
int ret; int ret;
/* accept() is a cancellation point */ /* accept4() is a cancellation point */
enter_cancellation_point(); enter_cancellation_point();
if (flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC))
{
errcode = EINVAL;
goto errout;
}
/* Get the underlying socket structure */ /* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock); ret = sockfd_socket(sockfd, &psock);
@ -258,7 +273,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
goto errout; goto errout;
} }
ret = psock_accept(psock, addr, addrlen, newsock); ret = psock_accept(psock, addr, addrlen, newsock, flags);
if (ret < 0) if (ret < 0)
{ {
errcode = -ret; errcode = -ret;
@ -269,7 +284,17 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
* cannot fail later) * 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) if (newfd < 0)
{ {
errcode = ENFILE; errcode = ENFILE;
@ -291,3 +316,25 @@ errout:
_SO_SETERRNO(psock, errcode); _SO_SETERRNO(psock, errcode);
return ERROR; 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);
}

View file

@ -1,6 +1,7 @@
"_exit","unistd.h","","noreturn","int" "_exit","unistd.h","","noreturn","int"
"_assert","assert.h","","void","FAR const char *","int" "_assert","assert.h","","void","FAR const char *","int"
"accept","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *" "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 *" "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_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 *" "aio_fsync","aio.h","defined(CONFIG_FS_AIO)","int","int","FAR struct aiocb *"

Can't render this file because it has a wrong number of fields in line 2.