diff --git a/fs/socket/socket.c b/fs/socket/socket.c index ad923ca280..69718cb545 100644 --- a/fs/socket/socket.c +++ b/fs/socket/socket.c @@ -150,7 +150,7 @@ static int sock_file_poll(FAR struct file *filep, FAR struct pollfd *fds, * Allocate a socket descriptor * * Input Parameters: - * psock A double pointer to socket structure to be allocated. + * psock A pointer to socket structure. * oflags Open mode flags. * * Returned Value: @@ -159,24 +159,16 @@ static int sock_file_poll(FAR struct file *filep, FAR struct pollfd *fds, * ****************************************************************************/ -int sockfd_allocate(FAR struct socket **psock, int oflags) +int sockfd_allocate(FAR struct socket *psock, int oflags) { int sockfd; - *psock = kmm_zalloc(sizeof(**psock)); - if (*psock == NULL) + sockfd = files_allocate(&g_sock_inode, oflags, 0, psock, 0); + if (sockfd >= 0) { - return -ENOMEM; + inode_addref(&g_sock_inode); } - sockfd = files_allocate(&g_sock_inode, oflags, 0, *psock, 0); - if (sockfd < 0) - { - kmm_free(*psock); - } - - inode_addref(&g_sock_inode); - return sockfd; } @@ -261,13 +253,10 @@ int socket(int domain, int type, int protocol) oflags |= O_CLOEXEC; } - /* Allocate a socket descriptor */ - - sockfd = sockfd_allocate(&psock, oflags); - if (sockfd < 0) + psock = kmm_zalloc(sizeof(*psock)); + if (psock == NULL) { - nerr("ERROR: Failed to allocate a socket descriptor\n"); - ret = sockfd; + ret = -ENOMEM; goto errout; } @@ -277,13 +266,26 @@ int socket(int domain, int type, int protocol) if (ret < 0) { nerr("ERROR: psock_socket() failed: %d\n", ret); - goto errout_with_sockfd; + goto errout_with_alloc; + } + + /* Allocate a socket descriptor */ + + sockfd = sockfd_allocate(psock, oflags); + if (sockfd < 0) + { + nerr("ERROR: Failed to allocate a socket descriptor\n"); + ret = sockfd; + goto errout_with_psock; } return sockfd; -errout_with_sockfd: - nx_close(sockfd); +errout_with_psock: + psock_close(psock); + +errout_with_alloc: + kmm_free(psock); errout: set_errno(-ret); diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 21c50df6cc..cf7ba013e8 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -496,7 +496,7 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid); * Allocate a socket descriptor * * Input Parameters: - * psock A double pointer to socket structure to be allocated. + * psock A pointer to socket structure. * oflags Open mode flags. * * Returned Value: @@ -505,7 +505,7 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid); * ****************************************************************************/ -int sockfd_allocate(FAR struct socket **psock, int oflags); +int sockfd_allocate(FAR struct socket *psock, int oflags); /**************************************************************************** * Name: sockfd_socket diff --git a/net/socket/accept.c b/net/socket/accept.c index 772a27354d..08107d9eb7 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -35,6 +35,7 @@ #include #include +#include #include #include "socket/socket.h" @@ -230,8 +231,8 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) FAR struct socket *psock = sockfd_socket(sockfd); FAR struct socket *newsock; FAR struct file *filep; - int newfd; int errcode; + int newfd; int ret; /* accept() is a cancellation point */ @@ -259,15 +260,22 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) goto errout; } + newsock = kmm_zalloc(sizeof(*newsock)); + if (newsock == NULL) + { + errcode = ENOMEM; + goto errout; + } + /* Allocate a socket descriptor for the new connection now (so that it * cannot fail later) */ - newfd = sockfd_allocate(&newsock, O_RDWR); + newfd = sockfd_allocate(newsock, O_RDWR); if (newfd < 0) { errcode = ENFILE; - goto errout; + goto errout_with_alloc; } ret = psock_accept(psock, addr, addrlen, newsock); @@ -283,6 +291,9 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) errout_with_socket: nx_close(newfd); +errout_with_alloc: + kmm_free(newsock); + errout: leave_cancellation_point();