diff --git a/drivers/net/telnet.c b/drivers/net/telnet.c index 241ef778f6d..e09d9655e11 100644 --- a/drivers/net/telnet.c +++ b/drivers/net/telnet.c @@ -1226,7 +1226,7 @@ static int telnet_poll(FAR struct file *filep, FAR struct pollfd *fds, */ psock = &priv->td_psock; - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/fs/Makefile b/fs/Makefile index 8908cb79f13..4233cebecf9 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -50,6 +50,7 @@ include mmap/Make.defs include semaphore/Make.defs include mqueue/Make.defs include shm/Make.defs +include socket/Make.defs # Additional files required is mount-able file systems are supported diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 62682e7cc25..4a4d0fe9679 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include +#include #include #include "inode/inode.h" @@ -163,9 +165,15 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos, } /**************************************************************************** - * Name: files_dup2 + * Name: nx_dup2 * * Description: + * nx_dup2() is similar to the standard 'dup2' interface except that is + * not a cancellation point and it does not modify the errno variable. + * + * nx_dup2() is an internal NuttX interface and should not be called from + * applications. + * * Clone a file descriptor to a specific descriptor number. * * Returned Value: @@ -174,7 +182,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos, * ****************************************************************************/ -int files_dup2(int fd1, int fd2) +int nx_dup2(int fd1, int fd2) { FAR struct filelist *list; int ret; @@ -211,18 +219,51 @@ int files_dup2(int fd1, int fd2) } /**************************************************************************** - * Name: files_close + * Name: dup2 * * Description: + * Clone a file descriptor or socket descriptor to a specific descriptor + * number + * + ****************************************************************************/ + +int dup2(int fd1, int fd2) +{ + int ret; + + ret = nx_dup2(fd1, fd2); + if (ret < 0) + { + set_errno(-ret); + ret = ERROR; + } + + return ret; +} + +/**************************************************************************** + * Name: nx_close + * + * Description: + * nx_close() is similar to the standard 'close' interface except that is + * not a cancellation point and it does not modify the errno variable. + * + * nx_close() is an internal NuttX interface and should not be called from + * applications. + * * Close an inode (if open) * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * on any failure. + * * Assumptions: * Caller holds the list semaphore because the file descriptor will be * freed. * ****************************************************************************/ -int files_close(int fd) +int nx_close(int fd) { FAR struct filelist *list; int ret; @@ -255,31 +296,43 @@ int files_close(int fd) } /**************************************************************************** - * Name: files_release + * Name: close + * + * Description: + * close() closes a file descriptor, so that it no longer refers to any + * file and may be reused. Any record locks (see fcntl(2)) held on the file + * it was associated with, and owned by the process, are removed + * (regardless of the file descriptor that was used to obtain the lock). + * + * If fd is the last copy of a particular file descriptor the resources + * associated with it are freed; if the descriptor was the last reference + * to a file which has been removed using unlink(2) the file is deleted. + * + * Input Parameters: + * fd file descriptor to close + * + * Returned Value: + * 0 on success; -1 on error with errno set appropriately. * * Assumptions: - * Similar to files_close(). Called only from open() logic on error - * conditions. * ****************************************************************************/ -void files_release(int fd) +int close(int fd) { - FAR struct filelist *list; int ret; - list = nxsched_get_files(); - DEBUGASSERT(list != NULL); + /* close() is a cancellation point */ - if (fd >= 0 && fd < CONFIG_NFILE_DESCRIPTORS) + enter_cancellation_point(); + + ret = nx_close(fd); + if (ret < 0) { - ret = _files_semtake(list); - if (ret >= 0) - { - list->fl_files[fd].f_oflags = 0; - list->fl_files[fd].f_pos = 0; - list->fl_files[fd].f_inode = NULL; - _files_semgive(list); - } + set_errno(-ret); + ret = ERROR; } + + leave_cancellation_point(); + return ret; } diff --git a/fs/inode/inode.h b/fs/inode/inode.h index 07681e9e8c6..e664b13106c 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -389,45 +389,6 @@ void weak_function files_initialize(void); int files_allocate(FAR struct inode *inode, int oflags, off_t pos, FAR void *priv, int minfd); -/**************************************************************************** - * Name: files_dup2 - * - * Description: - * Clone a file descriptor to a specific descriptor number. - * - * Returned Value: - * fd2 is returned on success; a negated errno value is return on - * any failure. - * - ****************************************************************************/ - -int files_dup2(int fd1, int fd2); - -/**************************************************************************** - * Name: files_close - * - * Description: - * Close an inode (if open) - * - * Assumptions: - * Caller holds the list semaphore because the file descriptor will be - * freed. - * - ****************************************************************************/ - -int files_close(int fd); - -/**************************************************************************** - * Name: files_release - * - * Assumptions: - * Similar to files_close(). Called only from open() logic on error - * conditions. - * - ****************************************************************************/ - -void files_release(int fd); - #undef EXTERN #if defined(__cplusplus) } diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index bec2fc33b7f..c16a855aba7 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -1075,9 +1075,6 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile, { FAR struct task_group_s *group = tcb->group; FAR struct file *file; -#ifdef CONFIG_NET - FAR struct socket *socket; -#endif size_t remaining; size_t linesize; size_t copysize; @@ -1111,7 +1108,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile, { /* Is there an inode associated with the file descriptor? */ - if (file->f_inode) + if (file->f_inode && !INODE_IS_SOCKET(file->f_inode)) { linesize = snprintf(procfile->line, STATUS_LINELEN, "%3d %8ld %04x\n", i, (long)file->f_pos, @@ -1148,18 +1145,19 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile, /* Examine each open socket descriptor */ - for (i = 0, socket = group->tg_socketlist.sl_sockets; - i < CONFIG_NSOCKET_DESCRIPTORS; - i++, socket++) + for (i = 0, file = group->tg_filelist.fl_files; + i < CONFIG_NFILE_DESCRIPTORS; + i++, file++) { /* Is there an connection associated with the socket descriptor? */ - if (socket->s_conn) + if (file->f_inode && INODE_IS_SOCKET(file->f_inode)) { + FAR struct socket *socket = file->f_priv; linesize = snprintf(procfile->line, STATUS_LINELEN, - "%3d %2d %3d %02x", + "%3d %3d %02x", i + CONFIG_NFILE_DESCRIPTORS, - socket->s_crefs, socket->s_type, + socket->s_type, socket->s_flags); copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); diff --git a/fs/socket/Make.defs b/fs/socket/Make.defs new file mode 100644 index 00000000000..f605f18450c --- /dev/null +++ b/fs/socket/Make.defs @@ -0,0 +1,31 @@ +############################################################################ +# fs/socket/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# Include socket support + +ifeq ($(CONFIG_NET),y) + +CSRCS += socket.c + +# Include socket build support + +DEPPATH += --dep-path socket +VPATH += :socket +endif diff --git a/fs/socket/socket.c b/fs/socket/socket.c new file mode 100644 index 00000000000..ad923ca280c --- /dev/null +++ b/fs/socket/socket.c @@ -0,0 +1,291 @@ +/**************************************************************************** + * fs/socket/socket.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "inode/inode.h" + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +static int sock_file_open(FAR struct file *filep); +static int sock_file_close(FAR struct file *filep); +static ssize_t sock_file_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t sock_file_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen); +static int sock_file_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int sock_file_poll(FAR struct file *filep, struct pollfd *fds, + bool setup); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_sock_fileops = +{ + sock_file_open, /* open */ + sock_file_close, /* close */ + sock_file_read, /* read */ + sock_file_write, /* write */ + NULL, /* seek */ + sock_file_ioctl, /* ioctl */ + sock_file_poll, /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + NULL, /* unlink */ +#endif +}; + +static struct inode g_sock_inode = +{ + .i_crefs = 1, + .i_flags = FSNODEFLAG_TYPE_SOCKET, + .u = + { + .i_ops = &g_sock_fileops, + }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int sock_file_open(FAR struct file *filep) +{ + FAR struct socket *psock; + int ret; + + psock = kmm_zalloc(sizeof(*psock)); + if (psock == NULL) + { + return -ENOMEM; + } + + ret = psock_dup2(filep->f_priv, psock); + if (ret >= 0) + { + filep->f_priv = psock; + } + else + { + kmm_free(psock); + } + + return ret; +} + +static int sock_file_close(FAR struct file *filep) +{ + psock_close(filep->f_priv); + kmm_free(filep->f_priv); + return 0; +} + +static ssize_t sock_file_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + return psock_recv(filep->f_priv, buffer, buflen, 0); +} + +static ssize_t sock_file_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + return psock_send(filep->f_priv, buffer, buflen, 0); +} + +static int sock_file_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + return psock_ioctl(filep->f_priv, cmd, arg); +} + +static int sock_file_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + return psock_poll(filep->f_priv, fds, setup); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sockfd_allocate + * + * Description: + * Allocate a socket descriptor + * + * Input Parameters: + * psock A double pointer to socket structure to be allocated. + * oflags Open mode flags. + * + * Returned Value: + * Allocate a struct files instance and associate it with an socket + * instance. Returns the file descriptor == index into the files array. + * + ****************************************************************************/ + +int sockfd_allocate(FAR struct socket **psock, int oflags) +{ + int sockfd; + + *psock = kmm_zalloc(sizeof(**psock)); + if (*psock == NULL) + { + return -ENOMEM; + } + + sockfd = files_allocate(&g_sock_inode, oflags, 0, *psock, 0); + if (sockfd < 0) + { + kmm_free(*psock); + } + + inode_addref(&g_sock_inode); + + return sockfd; +} + +/**************************************************************************** + * Name: sockfd_socket + * + * Description: + * Given a socket descriptor, return the underlying socket structure. + * + * Input Parameters: + * sockfd - The socket descriptor index to use. + * + * Returned Value: + * On success, a reference to the socket structure associated with the + * the socket descriptor is returned. NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct socket *sockfd_socket(int sockfd) +{ + FAR struct file *filep; + + if (fs_getfilep(sockfd, &filep) < 0) + { + return NULL; + } + + if (INODE_IS_SOCKET(filep->f_inode)) + { + return filep->f_priv; + } + + return NULL; +} + +/**************************************************************************** + * Name: socket + * + * Description: + * socket() creates an endpoint for communication and returns a descriptor. + * + * Input Parameters: + * domain (see sys/socket.h) + * type (see sys/socket.h) + * protocol (see sys/socket.h) + * + * Returned Value: + * A non-negative socket descriptor on success; -1 on error with errno set + * appropriately. + * + * EACCES + * Permission to create a socket of the specified type and/or protocol + * is denied. + * EAFNOSUPPORT + * The implementation does not support the specified address family. + * EINVAL + * Unknown protocol, or protocol family not available. + * EMFILE + * Process file table overflow. + * ENFILE + * The system limit on the total number of open files has been reached. + * ENOBUFS or ENOMEM + * Insufficient memory is available. The socket cannot be created until + * sufficient resources are freed. + * EPROTONOSUPPORT + * The protocol type or the specified protocol is not supported within + * this domain. + * + * Assumptions: + * + ****************************************************************************/ + +int socket(int domain, int type, int protocol) +{ + FAR struct socket *psock; + int oflags = O_RDWR; + int sockfd; + int ret; + + if (type & SOCK_CLOEXEC) + { + oflags |= O_CLOEXEC; + } + + /* 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; + } + + /* Initialize the socket structure */ + + ret = psock_socket(domain, type, protocol, psock); + if (ret < 0) + { + nerr("ERROR: psock_socket() failed: %d\n", ret); + goto errout_with_sockfd; + } + + return sockfd; + +errout_with_sockfd: + nx_close(sockfd); + +errout: + set_errno(-ret); + return ERROR; +} diff --git a/fs/vfs/fs_close.c b/fs/vfs/fs_close.c index 4f7eec8fe52..dd2a05d1d33 100644 --- a/fs/vfs/fs_close.c +++ b/fs/vfs/fs_close.c @@ -39,17 +39,11 @@ #include -#include #include #include -#include #include -#ifdef CONFIG_NET -# include -#endif - #include "inode/inode.h" /**************************************************************************** @@ -107,94 +101,3 @@ int file_close(FAR struct file *filep) return ret; } - -/**************************************************************************** - * Name: nx_close - * - * Description: - * nx_close() is similar to the standard 'close' interface except that is - * not a cancellation point and it does not modify the errno variable. - * - * nx_close() is an internal NuttX interface and should not be called from - * applications. - * - * Returned Value: - * The new file descriptor is returned on success; a negated errno value is - * returned on any failure. - * - ****************************************************************************/ - -int nx_close(int fd) -{ - /* Did we get a valid file descriptor? */ - - if (fd >= CONFIG_NFILE_DESCRIPTORS) - { - /* Close a socket descriptor */ - -#ifdef CONFIG_NET - if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - return net_close(fd); - } - else -#endif - { - return -EBADF; - } - } - - /* Close the driver or mountpoint. NOTES: (1) there is no - * exclusion mechanism here, the driver or mountpoint must be - * able to handle concurrent operations internally, (2) The driver - * may have been opened numerous times (for different file - * descriptors) and must also handle being closed numerous times. - * (3) for the case of the mountpoint, we depend on the close - * methods bing identical in signature and position in the operations - * vtable. - */ - - return files_close(fd); -} - -/**************************************************************************** - * Name: close - * - * Description: - * close() closes a file descriptor, so that it no longer refers to any - * file and may be reused. Any record locks (see fcntl(2)) held on the file - * it was associated with, and owned by the process, are removed - * (regardless of the file descriptor that was used to obtain the lock). - * - * If fd is the last copy of a particular file descriptor the resources - * associated with it are freed; if the descriptor was the last reference - * to a file which has been removed using unlink(2) the file is deleted. - * - * Input Parameters: - * fd file descriptor to close - * - * Returned Value: - * 0 on success; -1 on error with errno set appropriately. - * - * Assumptions: - * - ****************************************************************************/ - -int close(int fd) -{ - int ret; - - /* close() is a cancellation point */ - - enter_cancellation_point(); - - ret = nx_close(fd); - if (ret < 0) - { - set_errno(-ret); - ret = ERROR; - } - - leave_cancellation_point(); - return ret; -} diff --git a/fs/vfs/fs_dup.c b/fs/vfs/fs_dup.c index 2dd3d556e34..988aa8cdeab 100644 --- a/fs/vfs/fs_dup.c +++ b/fs/vfs/fs_dup.c @@ -109,50 +109,22 @@ int file_dup(FAR struct file *filep, int minfd) int nx_dup(int fd) { - /* Check the range of the descriptor to see if we got a file or a socket - * descriptor. - */ + FAR struct file *filep; + int ret; - if (fd < CONFIG_NFILE_DESCRIPTORS) + /* Get the file structure corresponding to the file descriptor. */ + + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - FAR struct file *filep; - int ret; - - /* Get the file structure corresponding to the file descriptor. */ - - ret = fs_getfilep(fd, &filep); - if (ret < 0) - { - return ret; - } - - DEBUGASSERT(filep != NULL); - - /* Let file_dup() do the real work */ - - return file_dup(filep, 0); + return ret; } - else - { - /* Not a valid file descriptor. - * Did we get a valid socket descriptor? - */ -#ifdef CONFIG_NET - if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - /* Yes.. dup the socket descriptor. */ + DEBUGASSERT(filep != NULL); - return net_dup(fd, CONFIG_NFILE_DESCRIPTORS); - } - else -#endif - { - /* No.. then it is a bad descriptor number */ + /* Let file_dup() do the real work */ - return -EBADF; - } - } + return file_dup(filep, 0); } /**************************************************************************** diff --git a/fs/vfs/fs_dup2.c b/fs/vfs/fs_dup2.c index c59b04a7b76..cec77fdb819 100644 --- a/fs/vfs/fs_dup2.c +++ b/fs/vfs/fs_dup2.c @@ -117,6 +117,7 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2) { /* (Re-)open the pseudo file or device driver */ + temp.f_priv = filep1->f_priv; ret = inode->u.i_ops->open(&temp); } @@ -141,78 +142,3 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2) memcpy(filep2, &temp, sizeof(temp)); return OK; } - -/**************************************************************************** - * Name: nx_dup2 - * - * Description: - * nx_dup2() is similar to the standard 'dup2' interface except that is - * not a cancellation point and it does not modify the errno variable. - * - * nx_dup2() is an internal NuttX interface and should not be called from - * applications. - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is return on - * any failure. - * - ****************************************************************************/ - -int nx_dup2(int fd1, int fd2) -{ - /* Check the range of the descriptor to see if we got a file or a socket - * descriptor. - */ - - if (fd1 >= CONFIG_NFILE_DESCRIPTORS) - { - /* Not a valid file descriptor. - * Did we get a valid socket descriptor? - */ - -#ifdef CONFIG_NET - if (fd1 < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - /* Yes.. dup the socket descriptor. */ - - return net_dup2(fd1, fd2); - } - else -#endif - { - /* No.. then it is a bad descriptor number */ - - return -EBADF; - } - } - else - { - /* Its a valid file descriptor.. dup the file descriptor. - */ - - return files_dup2(fd1, fd2); - } -} - -/**************************************************************************** - * Name: dup2 - * - * Description: - * Clone a file descriptor or socket descriptor to a specific descriptor - * number - * - ****************************************************************************/ - -int dup2(int fd1, int fd2) -{ - int ret; - - ret = nx_dup2(fd1, fd2); - if (ret < 0) - { - set_errno(-ret); - ret = ERROR; - } - - return ret; -} diff --git a/fs/vfs/fs_fcntl.c b/fs/vfs/fs_fcntl.c index 28c92fd4d2d..811f0824828 100644 --- a/fs/vfs/fs_fcntl.c +++ b/fs/vfs/fs_fcntl.c @@ -238,17 +238,28 @@ static int nx_vfcntl(int fd, int cmd, va_list ap) FAR struct file *filep; int ret; - /* Did we get a valid file descriptor? */ + /* Get the file structure corresponding to the file descriptor. */ - if (fd < CONFIG_NFILE_DESCRIPTORS) + ret = fs_getfilep(fd, &filep); + if (ret >= 0) { - /* Get the file structure corresponding to the file descriptor. */ + DEBUGASSERT(filep != NULL); - ret = fs_getfilep(fd, &filep); - if (ret >= 0) + /* check for operations on a socket descriptor */ + +#ifdef CONFIG_NET + if (INODE_IS_SOCKET(filep->f_inode) && + cmd != F_DUPFD && cmd != F_GETFD && cmd != F_SETFD) { - DEBUGASSERT(filep != NULL); + /* Yes.. defer socket descriptor operations to + * psock_vfcntl(). The errno is not set on failures. + */ + ret = psock_vfcntl(sockfd_socket(fd), cmd, ap); + } + else +#endif + { /* Let file_vfcntl() do the real work. The errno is not set on * failures. */ @@ -256,27 +267,6 @@ static int nx_vfcntl(int fd, int cmd, va_list ap) ret = file_vfcntl(filep, cmd, ap); } } - else - { - /* No... check for operations on a socket descriptor */ - -#ifdef CONFIG_NET - if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - /* Yes.. defer socket descriptor operations to net_vfcntl(). The - * errno is not set on failures. - */ - - ret = net_vfcntl(fd, cmd, ap); - } - else -#endif - { - /* No.. this descriptor number is out of range */ - - ret = -EBADF; - } - } return ret; } diff --git a/fs/vfs/fs_fdopen.c b/fs/vfs/fs_fdopen.c index cace0ca49de..e2436784da3 100644 --- a/fs/vfs/fs_fdopen.c +++ b/fs/vfs/fs_fdopen.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "inode/inode.h" @@ -115,7 +114,7 @@ int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb, { FAR struct streamlist *slist; FAR FILE *stream; - int ret; + int ret = OK; /* Check input parameters */ @@ -137,34 +136,7 @@ int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb, DEBUGASSERT(tcb && tcb->group); - /* Verify that this is a valid file/socket descriptor and that the - * requested access can be support. - * - * Is this fd in the range of valid file descriptors? Socket descriptors - * lie in a different range. - */ - - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) - { - /* No.. If networking is enabled then this might be a socket - * descriptor. - */ - -#ifdef CONFIG_NET - ret = net_checksd(fd, oflags); -#else - /* No networking... it is just a bad descriptor */ - - ret = -EBADF; - goto errout; -#endif - } - - /* The descriptor is in a valid range to file descriptor... perform some - * more checks. - */ - - else + if (fd >= 3) { ret = fs_checkfd(tcb, fd, oflags); } diff --git a/fs/vfs/fs_fstat.c b/fs/vfs/fs_fstat.c index 2612ba86343..8e698996e6b 100644 --- a/fs/vfs/fs_fstat.c +++ b/fs/vfs/fs_fstat.c @@ -233,30 +233,7 @@ int fstat(int fd, FAR struct stat *buf) FAR struct file *filep; int ret; - /* Did we get a valid file descriptor? */ - - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) - { -#ifdef CONFIG_NET - /* Let the networking logic handle the fstat() */ - - ret = net_fstat(fd, buf); - if (ret < 0) - { - goto errout; - } - - return OK; -#else - /* No networking... it is just a bad descriptor */ - - ret = -EBADF; - goto errout; -#endif - } - - /* The descriptor is in a valid range for a file descriptor... do the - * fstat. First, get the file structure. Note that on failure, + /* First, get the file structure. Note that on failure, * fs_getfilep() will set the errno variable. */ @@ -266,6 +243,21 @@ int fstat(int fd, FAR struct stat *buf) goto errout; } +#ifdef CONFIG_NET + if (INODE_IS_SOCKET(filep->f_inode)) + { + /* Let the networking logic handle the fstat() */ + + ret = psock_fstat(sockfd_socket(fd), buf); + if (ret < 0) + { + goto errout; + } + + return OK; + } +#endif + /* Perform the fstat operation */ ret = file_fstat(filep, buf); diff --git a/fs/vfs/fs_fstatfs.c b/fs/vfs/fs_fstatfs.c index 7e4ddb3879c..370fa4a9629 100644 --- a/fs/vfs/fs_fstatfs.c +++ b/fs/vfs/fs_fstatfs.c @@ -76,18 +76,7 @@ int fstatfs(int fd, FAR struct statfs *buf) DEBUGASSERT(buf != NULL); - /* Did we get a valid file descriptor? */ - - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) - { - /* It is a bad, out-of-range descriptor */ - - ret = -EBADF; - goto errout; - } - - /* The descriptor is in a valid range to file descriptor... do the - * read. First, get the file structure. Note that on failure, + /* First, get the file structure. Note that on failure, * fs_getfilep() will set the errno variable. */ diff --git a/fs/vfs/fs_ioctl.c b/fs/vfs/fs_ioctl.c index 0e8b15db5d4..21e420e7081 100644 --- a/fs/vfs/fs_ioctl.c +++ b/fs/vfs/fs_ioctl.c @@ -46,12 +46,6 @@ #include #include -#include - -#ifdef CONFIG_NET -# include -#endif - #include "inode/inode.h" /**************************************************************************** @@ -98,39 +92,19 @@ static int nx_vioctl(int fd, int req, va_list ap) FAR int *arg; int ret; - /* Did we get a valid file descriptor? */ + /* Get the file structure corresponding to the file descriptor. */ - if (fd >= CONFIG_NFILE_DESCRIPTORS) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* Perform the socket ioctl */ - -#ifdef CONFIG_NET - if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - ret = netdev_vioctl(fd, req, ap); - } - else -#endif - { - return -EBADF; - } + return ret; } - else - { - /* Get the file structure corresponding to the file descriptor. */ - ret = fs_getfilep(fd, &filep); - if (ret < 0) - { - return ret; - } + DEBUGASSERT(filep != NULL); - DEBUGASSERT(filep != NULL); + /* Perform the file ioctl. */ - /* Perform the file ioctl. */ - - ret = file_vioctl(filep, req, ap); - } + ret = file_vioctl(filep, req, ap); /* Check for File system IOCTL commands that can be implemented via * fcntl() diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index a3e8d1d42fd..488e3c70009 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -86,25 +86,22 @@ static int poll_semtake(FAR sem_t *sem) static int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup) { - /* Check for a valid file descriptor */ + FAR struct file *filep; + int ret; - if (fd >= CONFIG_NFILE_DESCRIPTORS) + /* Get the file pointer corresponding to this file descriptor */ + + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* Perform the socket ioctl */ - -#ifdef CONFIG_NET - if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - return net_poll(fd, fds, setup); - } - else -#endif - { - return -EBADF; - } + return ret; } - return fs_poll(fd, fds, setup); + DEBUGASSERT(filep != NULL); + + /* Let file_poll() do the rest */ + + return file_poll(filep, fds, setup); } /**************************************************************************** @@ -298,7 +295,7 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, * * Description: * Low-level poll operation based on struct file. This is used both to (1) - * support detached file, and also (2) by fs_poll() to perform all + * support detached file, and also (2) by poll_fdsetup() to perform all * normal operations on file descriptors. * * Input Parameters: @@ -326,7 +323,8 @@ int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) * If not, return -ENOSYS */ - if ((INODE_IS_DRIVER(inode) || INODE_IS_MQUEUE(inode)) && + if ((INODE_IS_DRIVER(inode) || INODE_IS_MQUEUE(inode) || + INODE_IS_SOCKET(inode)) && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL) { /* Yes, it does... Setup the poll */ @@ -358,45 +356,6 @@ int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) return ret; } -/**************************************************************************** - * Name: fs_poll - * - * Description: - * The standard poll() operation redirects operations on file descriptors - * to this function. - * - * Input Parameters: - * fd - The file descriptor of interest - * fds - The structure describing the events to be monitored, OR NULL if - * this is a request to stop monitoring events. - * setup - true: Setup up the poll; false: Teardown the poll - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is returned on - * any failure. - * - ****************************************************************************/ - -int fs_poll(int fd, FAR struct pollfd *fds, bool setup) -{ - FAR struct file *filep; - int ret; - - /* Get the file pointer corresponding to this file descriptor */ - - ret = fs_getfilep(fd, &filep); - if (ret < 0) - { - return ret; - } - - DEBUGASSERT(filep != NULL); - - /* Let file_poll() do the rest */ - - return file_poll(filep, fds, setup); -} - /**************************************************************************** * Name: nx_poll * diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c index 994c6139aa3..24b1b57cfba 100644 --- a/fs/vfs/fs_read.c +++ b/fs/vfs/fs_read.c @@ -41,14 +41,12 @@ #include #include -#include #include #include #include #include #include -#include #include "inode/inode.h" @@ -65,7 +63,6 @@ * * - It does not modify the errno variable, * - It is not a cancellation point, - * - It does not handle socket descriptors, and * - It accepts a file structure instance instead of file descriptor. * * Input Parameters: @@ -107,7 +104,9 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) * signature and position in the operations vtable. */ - ret = (int)inode->u.i_ops->read(filep, (FAR char *)buf, (size_t)nbytes); + ret = (int)inode->u.i_ops->read(filep, + (FAR char *)buf, + (size_t)nbytes); } /* Return the number of bytes read (or possibly an error code) */ @@ -138,42 +137,22 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) ssize_t nx_read(int fd, FAR void *buf, size_t nbytes) { - /* Did we get a valid file descriptor? */ + FAR struct file *filep; + ssize_t ret; - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) + /* First, get the file structure. Note that on failure, + * fs_getfilep() will return the errno. + */ + + ret = (ssize_t)fs_getfilep(fd, &filep); + if (ret < 0) { -#ifdef CONFIG_NET - /* No.. If networking is enabled, read() is the same as recv() with - * the flags parameter set to zero. - */ - - return nx_recv(fd, buf, nbytes, 0); -#else - /* No networking... it is a bad descriptor in any event */ - - return -EBADF; -#endif + return ret; } - else - { - FAR struct file *filep; - ssize_t ret; - /* The descriptor is in a valid range to file descriptor... do the - * read. First, get the file structure. Note that on failure, - * fs_getfilep() will set the errno variable. - */ + /* Then let file_read do all of the work. */ - ret = (ssize_t)fs_getfilep(fd, &filep); - if (ret < 0) - { - return ret; - } - - /* Then let file_read do all of the work. */ - - return file_read(filep, buf, nbytes); - } + return file_read(filep, buf, nbytes); } /**************************************************************************** diff --git a/fs/vfs/fs_sendfile.c b/fs/vfs/fs_sendfile.c index 6ecf6f78740..78083beb29f 100644 --- a/fs/vfs/fs_sendfile.c +++ b/fs/vfs/fs_sendfile.c @@ -108,8 +108,10 @@ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count) * descriptor? Check the source file: Is it a normal file? */ - if ((unsigned int)outfd >= CONFIG_NFILE_DESCRIPTORS && - (unsigned int)infd < CONFIG_NFILE_DESCRIPTORS) + FAR struct socket *psock; + + psock = sockfd_socket(outfd); + if (psock != NULL) { FAR struct file *filep; int ret; @@ -127,16 +129,16 @@ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count) DEBUGASSERT(filep != NULL); - /* Then let net_sendfile do the work. */ + /* Then let psock_sendfile do the work. */ - ret = net_sendfile(outfd, filep, offset, count); + ret = psock_sendfile(psock, filep, offset, count); if (ret >= 0 || get_errno() != ENOSYS) { return ret; } /* Fall back to the slow path if errno equals ENOSYS, - * because net_sendfile fail to optimize this transfer. + * because psock_sendfile fail to optimize this transfer. */ } #endif diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c index d1b7f035b31..d48e2b706ea 100644 --- a/fs/vfs/fs_write.c +++ b/fs/vfs/fs_write.c @@ -47,12 +47,7 @@ #include #include -#ifdef CONFIG_NET_TCP -# include -#endif - #include -#include #include "inode/inode.h" @@ -71,7 +66,6 @@ * * - It does not modify the errno variable, * - It is not a cancellation point, and - * - It does not handle socket descriptors. * * Input Parameters: * filep - Instance of struct file to use with the write @@ -124,7 +118,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, * - It is not a cancellation point. * * Input Parameters: - * fd - file descriptor (or socket descriptor) to write to + * fd - file descriptor to write to * buf - Data to write * nbytes - Length of data to write * @@ -146,36 +140,18 @@ ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes) return -EINVAL; } - /* Did we get a valid file descriptor? */ + /* First, get the file structure. + * Note that fs_getfilep() will return the errno on failure. + */ - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) + ret = (ssize_t)fs_getfilep(fd, &filep); + if (ret >= 0) { -#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_CAN) - /* Write to a socket descriptor is equivalent to - * send with flags == 0. + /* Perform the write operation using the file descriptor as an + * index. Note that file_write() will return the errno on failure. */ - ret = nx_send(fd, buf, nbytes, 0); -#else - ret = -EBADF; -#endif - } - else - { - /* The descriptor is in the right range to be a file descriptor.. - * write to the file. Note that fs_getfilep() will set the errno on - * failure. - */ - - ret = (ssize_t)fs_getfilep(fd, &filep); - if (ret >= 0) - { - /* Perform the write operation using the file descriptor as an - * index. Note that file_write() will set the errno on failure. - */ - - ret = file_write(filep, buf, nbytes); - } + ret = file_write(filep, buf, nbytes); } return ret; @@ -189,7 +165,7 @@ ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes) * descriptor fd from the buffer starting at buf. * * Input Parameters: - * fd - file descriptor (or socket descriptor) to write to + * fd - file descriptor to write to * buf - Data to write * nbytes - Length of data to write * diff --git a/include/aio.h b/include/aio.h index fd9379c4b20..a740073ab82 100644 --- a/include/aio.h +++ b/include/aio.h @@ -128,7 +128,7 @@ struct aiocb FAR volatile void *aio_buf; /* Location of buffer */ off_t aio_offset; /* File offset */ size_t aio_nbytes; /* Length of transfer */ -#if (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS) > 127 +#if CONFIG_NFILE_DESCRIPTORS > 127 int16_t aio_fildes; /* File descriptor (should be int) */ #else int8_t aio_fildes; /* File descriptor (should be int) */ diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 4bba51ad243..ce49050cbfd 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -114,6 +114,7 @@ #define FSNODEFLAG_TYPE_SHM 0x00000006 /* Shared memory region */ #define FSNODEFLAG_TYPE_MTD 0x00000007 /* Named MTD driver */ #define FSNODEFLAG_TYPE_SOFTLINK 0x00000008 /* Soft link */ +#define FSNODEFLAG_TYPE_SOCKET 0x00000009 /* Socket */ #define FSNODEFLAG_DELETED 0x00000010 /* Unlinked */ #define INODE_IS_TYPE(i,t) \ @@ -128,6 +129,7 @@ #define INODE_IS_SHM(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SHM) #define INODE_IS_MTD(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MTD) #define INODE_IS_SOFTLINK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) +#define INODE_IS_SOCKET(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOCKET) #define INODE_GET_TYPE(i) ((i)->i_flags & FSNODEFLAG_TYPE_MASK) #define INODE_SET_TYPE(i,t) \ @@ -145,6 +147,7 @@ #define INODE_SET_SHM(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SHM) #define INODE_SET_MTD(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MTD) #define INODE_SET_SOFTLINK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) +#define INODE_SET_SOCKET(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOCKET) /* Mountpoint fd_flags values */ @@ -1232,7 +1235,7 @@ int nx_fcntl(int fd, int cmd, ...); * * Description: * Low-level poll operation based on struct file. This is used both to (1) - * support detached file, and also (2) by fs_poll() to perform all + * support detached file, and also (2) by poll_fdsetup() to perform all * normal operations on file descriptors. * * Input Parameters: @@ -1248,26 +1251,6 @@ int nx_fcntl(int fd, int cmd, ...); int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); -/**************************************************************************** - * Name: fs_poll - * - * Description: - * The standard poll() operation redirects operations on file descriptors - * to this function. - * - * Input Parameters: - * fd - The file descriptor of interest - * fds - The structure describing the events to be monitored, OR NULL if - * this is a request to stop monitoring events. - * setup - true: Setup up the poll; false: Teardown the poll - * - * Returned Value: - * 0: Success; Negated errno on failure - * - ****************************************************************************/ - -int fs_poll(int fd, FAR struct pollfd *fds, bool setup); - /**************************************************************************** * Name: nx_poll * diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 38eee8a7e1c..17be9a67465 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -96,7 +96,6 @@ /* Definitions of 8-bit socket flags */ #define _SF_INITD 0x01 /* Bit 0: Socket structure is initialized */ -#define _SF_CLOEXEC 0x04 /* Bit 2: Close on execute */ #define _SF_NONBLOCK 0x08 /* Bit 3: Don't block if no data (TCP/READ only) */ #define _SF_LISTENING 0x10 /* Bit 4: SOCK_STREAM is listening */ #define _SF_BOUND 0x20 /* Bit 5: SOCK_STREAM is bound to an address */ @@ -115,7 +114,6 @@ /* Macro to manage the socket state and flags */ #define _SS_INITD(s) (((s) & _SF_INITD) != 0) -#define _SS_ISCLOEXEC(s) (((s) & _SF_CLOEXEC) != 0) #define _SS_ISNONBLOCK(s) (((s) & _SF_NONBLOCK) != 0) #define _SS_ISLISTENING(s) (((s) & _SF_LISTENING) != 0) #define _SS_ISBOUND(s) (((s) & _SF_BOUND) != 0) @@ -125,7 +123,7 @@ /* Determine if a socket is valid. Valid means both (1) allocated and (2) * successfully initialized: * - * Allocated: psock->s_crefs > 0 + * Allocated: psock->s_conn != NULL * Initialized: _SF_INITD bit set in psock->s_flags * * This logic is used within the OS to pick the sockets to be cloned when a @@ -134,7 +132,7 @@ * pthread. */ -#define _PS_ALLOCD(psock) ((psock)->s_crefs > 0) +#define _PS_ALLOCD(psock) ((psock)->s_conn != NULL) #define _PS_INITD(psock) (_SS_INITD((psock)->s_flags)) #define _PS_VALID(psock) (_PS_ALLOCD(psock) && _PS_INITD(psock)) @@ -252,7 +250,6 @@ struct devif_callback_s; /* Forward reference */ struct socket { - int16_t s_crefs; /* Reference count on the socket */ uint8_t s_domain; /* IP domain */ uint8_t s_type; /* Protocol type */ uint8_t s_proto; /* Socket Protocol */ @@ -287,16 +284,6 @@ struct socket #endif }; -/* This defines a list of sockets indexed by the socket descriptor */ - -#ifdef CONFIG_NET -struct socketlist -{ - sem_t sl_sem; /* Manage access to the socket list */ - struct socket sl_sockets[CONFIG_NSOCKET_DESCRIPTORS]; -}; -#endif - /**************************************************************************** * Public Data ****************************************************************************/ @@ -514,51 +501,22 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid); #endif /**************************************************************************** - * Name: net_checksd + * Name: sockfd_allocate * * Description: - * Check if the socket descriptor is valid for the provided TCB and if it - * supports the requested access. This trivial operation is part of the - * fdopen() operation when the fdopen() is performed on a socket - * descriptor. It simply performs some sanity checking before permitting - * the socket descriptor to be wrapped as a C FILE stream. - * - ****************************************************************************/ - -int net_checksd(int fd, int oflags); - -/**************************************************************************** - * Name: net_initlist - * - * Description: - * Initialize a list of sockets for a new task + * Allocate a socket descriptor * * Input Parameters: - * list -- A reference to the pre-alloated socket list to be initialized. + * psock A double pointer to socket structure to be allocated. + * oflags Open mode flags. * * Returned Value: - * None + * Allocate a struct files instance and associate it with an socket + * instance. Returns the file descriptor == index into the files array. * ****************************************************************************/ -void net_initlist(FAR struct socketlist *list); - -/**************************************************************************** - * Name: net_releaselist - * - * Description: - * Release resources held by the socket list - * - * Input Parameters: - * list -- A reference to the pre-allocated socket list to be un- - * initialized. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void net_releaselist(FAR struct socketlist *list); +int sockfd_allocate(FAR struct socket **psock, int oflags); /**************************************************************************** * Name: sockfd_socket @@ -613,32 +571,11 @@ FAR struct socket *sockfd_socket(int sockfd); * The protocol type or the specified protocol is not supported within * this domain. * - * Assumptions: - * ****************************************************************************/ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock); -/**************************************************************************** - * Name: net_close - * - * Description: - * Performs the close operation on socket descriptors - * - * Input Parameters: - * sockfd Socket descriptor of socket - * - * Returned Value: - * Returns zero (OK) on success. On failure, it returns a negated errno - * value to indicate the nature of the error. - * - * Assumptions: - * - ****************************************************************************/ - -int net_close(int sockfd); - /**************************************************************************** * Name: psock_close * @@ -683,8 +620,6 @@ int psock_close(FAR struct socket *psock); * ENOTSOCK * psock is a descriptor for a file, not a socket. * - * Assumptions: - * ****************************************************************************/ struct sockaddr; /* Forward reference. See nuttx/include/sys/socket.h */ @@ -859,8 +794,6 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, * Timeout while attempting connection. The server may be too busy * to accept new connections. * - * Assumptions: - * ****************************************************************************/ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr, @@ -1341,39 +1274,6 @@ int psock_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr, int psock_vioctl(FAR struct socket *psock, int cmd, va_list ap); int psock_ioctl(FAR struct socket *psock, int cmd, ...); -/**************************************************************************** - * Name: netdev_vioctl - * - * Description: - * Perform network device specific operations. - * - * Input Parameters: - * sockfd Socket descriptor of device - * cmd The ioctl command - * ap The argument of the ioctl cmd - * - * Returned Value: - * A non-negative value is returned on success; a negated errno value is - * returned on any failure to indicate the nature of the failure: - * - * EBADF - * 'sockfd' is not a valid socket descriptor. - * EFAULT - * 'arg' references an inaccessible memory area. - * ENOTTY - * 'cmd' not valid. - * EINVAL - * 'arg' is not valid. - * ENOTTY - * 'sockfd' is not associated with a network device. - * ENOTTY - * The specified request does not apply to the kind of object that the - * descriptor 'sockfd' references. - * - ****************************************************************************/ - -int netdev_vioctl(int sockfd, int cmd, va_list ap); - /**************************************************************************** * Name: psock_poll * @@ -1396,88 +1296,28 @@ struct pollfd; /* Forward reference -- see poll.h */ int psock_poll(FAR struct socket *psock, struct pollfd *fds, bool setup); -/**************************************************************************** - * Name: net_poll - * - * Description: - * The standard poll() operation redirects operations on socket descriptors - * to this function. - * - * Input Parameters: - * fd - The socket descriptor of interest - * fds - The structure describing the events to be monitored, OR NULL if - * this is a request to stop monitoring events. - * setup - true: Setup up the poll; false: Teardown the poll - * - * Returned Value: - * 0: Success; Negated errno on failure - * - ****************************************************************************/ - -struct pollfd; /* Forward reference -- see poll.h */ - -int net_poll(int sockfd, struct pollfd *fds, bool setup); - -/**************************************************************************** - * Name: psock_dup - * - * Description: - * Clone a socket descriptor to an arbitrary descriptor number. - * - * Returned Value: - * On success, returns the number of new socket. On any error, - * a negated errno value is returned. - * - ****************************************************************************/ - -int psock_dup(FAR struct socket *psock, int minsd); - -/**************************************************************************** - * Name: net_dup - * - * Description: - * Clone a socket descriptor to an arbitrary descriptor number. - * - * Returned Value: - * On success, returns the number of new socket. On any error, - * a negated errno value is returned. - * - ****************************************************************************/ - -int net_dup(int sockfd, int minsd); - /**************************************************************************** * Name: psock_dup2 * * Description: - * Performs the low level, common portion of net_dup() and net_dup2() + * Clone a socket instance to an new instance. + * + * Returned Value: + * On success, returns the number of new socket. On any error, + * a negated errno value is returned. * ****************************************************************************/ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2); /**************************************************************************** - * Name: net_dup2 - * - * Description: - * Clone a socket descriptor to an arbitrary descriptor number. - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is returned on - * any failure. - * - ****************************************************************************/ - -int net_dup2(int sockfd1, int sockfd2); - -/**************************************************************************** - * Name: net_fstat + * Name: psock_fstat * * Description: * Performs fstat operations on socket * * Input Parameters: - * sockfd - Socket descriptor of the socket to operate on + * psock - An instance of the internal socket structure. * buf - Caller-provided location in which to return the fstat data * * Returned Value: @@ -1488,10 +1328,10 @@ int net_dup2(int sockfd1, int sockfd2); struct stat; /* Forward reference. See sys/stat.h */ -int net_fstat(int sockfd, FAR struct stat *buf); +int psock_fstat(FAR struct socket *psock, FAR struct stat *buf); /**************************************************************************** - * Name: net_sendfile + * Name: psock_sendfile * * Description: * The send() call may be used only when the socket is in a connected state @@ -1554,8 +1394,8 @@ int net_fstat(int sockfd, FAR struct stat *buf); #ifdef CONFIG_NET_SENDFILE struct file; -ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, - size_t count); +ssize_t psock_sendfile(FAR struct socket *psock, FAR struct file *infile, + FAR off_t *offset, size_t count); #endif /**************************************************************************** @@ -1598,25 +1438,6 @@ int psock_vfcntl(FAR struct socket *psock, int cmd, va_list ap); int psock_fcntl(FAR struct socket *psock, int cmd, ...); -/**************************************************************************** - * Name: net_vfcntl - * - * Description: - * Performs fcntl operations on socket - * - * Input Parameters: - * sockfd - Socket descriptor of the socket to operate on - * cmd - The fcntl command. - * ap - Command-specific arguments - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is returned on - * any failure to indicate the nature of the failure. - * - ****************************************************************************/ - -int net_vfcntl(int sockfd, int cmd, va_list ap); - /**************************************************************************** * Name: netdev_register * diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 0d1a1b06063..c4376d491fd 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -594,12 +594,6 @@ struct task_group_s #endif #endif -#ifdef CONFIG_NET - /* Sockets ********************************************************************/ - - struct socketlist tg_socketlist; /* Maps socket descriptor to socket */ -#endif - #ifdef CONFIG_ARCH_ADDRENV /* Address Environment ********************************************************/ @@ -910,10 +904,6 @@ FAR struct filelist *nxsched_get_files(void); FAR struct streamlist *nxsched_get_streams(void); #endif /* CONFIG_FILE_STREAM */ -#ifdef CONFIG_NET -FAR struct socketlist *nxsched_get_sockets(void); -#endif - /******************************************************************************** * Name: nxtask_init * diff --git a/include/sys/select.h b/include/sys/select.h index 9a357ac7209..7b136d44927 100644 --- a/include/sys/select.h +++ b/include/sys/select.h @@ -52,11 +52,7 @@ /* Get the total number of descriptors that we will have to support */ -#ifdef CONFIG_NSOCKET_DESCRIPTORS -# define FD_SETSIZE (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS) -#else -# define FD_SETSIZE CONFIG_NFILE_DESCRIPTORS -#endif +#define FD_SETSIZE CONFIG_NFILE_DESCRIPTORS /* We will use a 32-bit bitsets to represent the set of descriptors. How * many uint32_t's do we need to span all descriptors? diff --git a/net/bluetooth/bluetooth_sendmsg.c b/net/bluetooth/bluetooth_sendmsg.c index 59a6f9b5c0c..6c8e1ec042d 100644 --- a/net/bluetooth/bluetooth_sendmsg.c +++ b/net/bluetooth/bluetooth_sendmsg.c @@ -250,13 +250,12 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } conn = (FAR struct bluetooth_conn_s *)psock->s_conn; - DEBUGASSERT(conn != NULL); /* Verify that the address is large enough to be a valid PF_BLUETOOTH * address. diff --git a/net/can/can_sendmsg.c b/net/can/can_sendmsg.c index 32c6b7a6b3c..85eae5b42c7 100644 --- a/net/can/can_sendmsg.c +++ b/net/can/can_sendmsg.c @@ -179,15 +179,15 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, struct send_s state; int ret = OK; - conn = (FAR struct can_conn_s *)psock->s_conn; - /* Verify that the sockfd corresponds to valid, allocated socket */ - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } + conn = (FAR struct can_conn_s *)psock->s_conn; + /* Only SOCK_RAW is supported */ if (psock->s_type != SOCK_RAW) diff --git a/net/ieee802154/ieee802154_sendmsg.c b/net/ieee802154/ieee802154_sendmsg.c index 963e78fc794..240266a7765 100644 --- a/net/ieee802154/ieee802154_sendmsg.c +++ b/net/ieee802154/ieee802154_sendmsg.c @@ -428,7 +428,7 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } @@ -445,7 +445,6 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, } conn = (FAR struct ieee802154_conn_s *)psock->s_conn; - DEBUGASSERT(conn != NULL); /* Verify that the address is large enough to be a valid PF_IEEE802154 * address. diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c index 549a4bbd977..79e39c9c912 100644 --- a/net/inet/inet_sockif.c +++ b/net/inet/inet_sockif.c @@ -872,7 +872,6 @@ static int inet_accept(FAR struct socket *psock, FAR struct sockaddr *addr, /* Initialize the socket structure. */ - newsock->s_crefs = 1; newsock->s_domain = psock->s_domain; newsock->s_type = SOCK_STREAM; newsock->s_sockif = psock->s_sockif; diff --git a/net/local/local_accept.c b/net/local/local_accept.c index 8f03700f380..3a8e548efb5 100644 --- a/net/local/local_accept.c +++ b/net/local/local_accept.c @@ -233,7 +233,6 @@ int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr, { /* Setup the client socket structure */ - newsock->s_crefs = 1; newsock->s_domain = psock->s_domain; newsock->s_type = SOCK_STREAM; newsock->s_sockif = psock->s_sockif; diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 5b1984a886b..e387af7a076 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1662,7 +1662,7 @@ int psock_vioctl(FAR struct socket *psock, int cmd, va_list ap) /* Verify that the psock corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } @@ -1772,44 +1772,6 @@ int psock_ioctl(FAR struct socket *psock, int cmd, ...) return ret; } -/**************************************************************************** - * Name: netdev_vioctl - * - * Description: - * Perform network device specific operations. - * - * Input Parameters: - * sockfd Socket descriptor of device - * cmd The ioctl command - * ap The argument of the ioctl cmd - * - * Returned Value: - * A non-negative value is returned on success; a negated errno value is - * returned on any failure to indicate the nature of the failure: - * - * EBADF - * 'sockfd' is not a valid socket descriptor. - * EFAULT - * 'arg' references an inaccessible memory area. - * ENOTTY - * 'cmd' not valid. - * EINVAL - * 'arg' is not valid. - * ENOTTY - * 'sockfd' is not associated with a network device. - * ENOTTY - * The specified request does not apply to the kind of object that the - * descriptor 'sockfd' references. - * - ****************************************************************************/ - -int netdev_vioctl(int sockfd, int cmd, va_list ap) -{ - FAR struct socket *psock = sockfd_socket(sockfd); - - return psock_vioctl(psock, cmd, ap); -} - /**************************************************************************** * Name: netdev_ifup / netdev_ifdown * diff --git a/net/pkt/pkt_sendmsg.c b/net/pkt/pkt_sendmsg.c index de958583d69..4bf7b67e4d1 100644 --- a/net/pkt/pkt_sendmsg.c +++ b/net/pkt/pkt_sendmsg.c @@ -194,7 +194,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/rpmsg/rpmsg_sockif.c b/net/rpmsg/rpmsg_sockif.c index 5b1ee0cc734..31cc47b69c8 100644 --- a/net/rpmsg/rpmsg_sockif.c +++ b/net/rpmsg/rpmsg_sockif.c @@ -720,7 +720,6 @@ static int rpmsg_socket_accept(FAR struct socket *psock, newsock->s_sockif = psock->s_sockif; newsock->s_type = SOCK_STREAM; newsock->s_conn = conn; - newsock->s_crefs = 1; rpmsg_socket_getaddr(conn, addr, addrlen); diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 0019f3a5c7c..a9b3b133023 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -716,12 +716,12 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, ninfo("buflen %lu\n", (unsigned long)buflen); sixlowpan_dumpbuffer("Outgoing TCP payload", buf, buflen); - DEBUGASSERT(psock != NULL && psock->s_crefs > 0); + DEBUGASSERT(psock != NULL && psock->s_conn != NULL); DEBUGASSERT(psock->s_type == SOCK_STREAM); /* Make sure that this is a valid socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { nerr("ERROR: Invalid socket\n"); return (ssize_t)-EBADF; @@ -738,7 +738,6 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, /* Get the underlying TCP connection structure */ conn = (FAR struct tcp_conn_s *)psock->s_conn; - DEBUGASSERT(conn != NULL); #ifdef CONFIG_NET_IPv4 /* Ignore if not IPv6 domain */ diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index 309504df795..1ceeb322a6d 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -157,7 +157,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, ninfo("buflen %lu\n", (unsigned long)buflen); - DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && to != NULL); + DEBUGASSERT(psock != NULL && psock->s_conn != NULL && to != NULL); DEBUGASSERT(psock->s_type == SOCK_DGRAM); sixlowpan_dumpbuffer("Outgoing UDP payload", buf, buflen); @@ -169,7 +169,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, /* Make sure that this is a datagram valid socket */ - if (psock->s_crefs <= 0 || psock->s_type != SOCK_DGRAM) + if (psock->s_conn == NULL || psock->s_type != SOCK_DGRAM) { nerr("ERROR: Invalid socket\n"); return (ssize_t)-EBADF; @@ -334,14 +334,14 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, ninfo("buflen %lu\n", (unsigned long)buflen); - DEBUGASSERT(psock != NULL && psock->s_crefs > 0); + DEBUGASSERT(psock != NULL && psock->s_conn != NULL); DEBUGASSERT(psock->s_type == SOCK_DGRAM); sixlowpan_dumpbuffer("Outgoing UDP payload", buf, buflen); /* Make sure that this is a valid socket */ - if (psock != NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { nerr("ERROR: Invalid socket\n"); return (ssize_t)-EBADF; @@ -359,7 +359,6 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, /* Get the underlying UDP "connection" structure */ conn = (FAR struct udp_conn_s *)psock->s_conn; - DEBUGASSERT(conn != NULL); /* Ignore if not IPv6 domain */ diff --git a/net/socket/Kconfig b/net/socket/Kconfig index 986084be472..c34628d3f1d 100644 --- a/net/socket/Kconfig +++ b/net/socket/Kconfig @@ -5,13 +5,6 @@ menu "Socket Support" -config NSOCKET_DESCRIPTORS - int "Number of socket descriptors" - default 8 - range 1 99999 - ---help--- - Maximum number of socket descriptors per task/thread. - config NET_NACTIVESOCKETS int "Max socket operations" default 16 diff --git a/net/socket/Make.defs b/net/socket/Make.defs index 4e1dc97f962..cf96175a507 100644 --- a/net/socket/Make.defs +++ b/net/socket/Make.defs @@ -37,8 +37,7 @@ SOCK_CSRCS += bind.c connect.c getsockname.c getpeername.c SOCK_CSRCS += recv.c recvfrom.c send.c sendto.c -SOCK_CSRCS += recvmsg.c sendmsg.c -SOCK_CSRCS += socket.c net_sockets.c net_close.c net_dup.c +SOCK_CSRCS += socket.c net_close.c recvmsg.c sendmsg.c SOCK_CSRCS += net_dup2.c net_sockif.c net_poll.c net_vfcntl.c SOCK_CSRCS += net_fstat.c @@ -59,12 +58,6 @@ ifeq ($(CONFIG_NET_SOCKOPTS),y) SOCK_CSRCS += setsockopt.c getsockopt.c net_timeo.c endif -# Support for network access using streams - -ifeq ($(CONFIG_FILE_STREAM),y) -SOCK_CSRCS += net_checksd.c -endif - # Support for sendfile() ifeq ($(CONFIG_NET_SENDFILE),y) diff --git a/net/socket/accept.c b/net/socket/accept.c index d7a78b33a06..67450dfaf87 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -42,11 +42,14 @@ #include #include +#include #include #include #include +#include #include +#include #include #include "socket/socket.h" @@ -86,7 +89,8 @@ * Input Parameters: * psock Reference to the listening socket structure * addr Receives the address of the connecting client - * addrlen Input: allocated size of 'addr', Return: returned size of 'addr' + * addrlen Input: allocated size of 'addr', Return: returned size + * of 'addr' * newsock Location to return the accepted socket information. * * Returned Value: @@ -197,7 +201,8 @@ errout_with_lock: * 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' + * addrlen Input: allocated size of 'addr', + * Return: returned size of 'addr' * * Returned Value: * Returns -1 on error. If it succeeds, it returns a non-negative integer @@ -249,11 +254,11 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { /* It is not a valid socket description. Distinguish between the cases - * where sockfd is a just valid and when it is a valid file descriptor used - * in the wrong context. + * where sockfd is a just valid and when it is a valid file descriptor + * used in the wrong context. */ if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS) @@ -272,20 +277,13 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) * cannot fail later) */ - newfd = sockfd_allocate(0); + newfd = sockfd_allocate(&newsock, O_RDWR); if (newfd < 0) { errcode = ENFILE; goto errout; } - newsock = sockfd_socket(newfd); - if (newsock == NULL) - { - errcode = ENFILE; - goto errout_with_socket; - } - ret = psock_accept(psock, addr, addrlen, newsock); if (ret < 0) { @@ -297,7 +295,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) return newfd; errout_with_socket: - sockfd_release(newfd); + nx_close(newfd); errout: leave_cancellation_point(); diff --git a/net/socket/bind.c b/net/socket/bind.c index 572622d9238..6f0ce05f307 100644 --- a/net/socket/bind.c +++ b/net/socket/bind.c @@ -95,7 +95,7 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr, /* Verify that the psock corresponds to valid, allocated socket */ - if (!psock || psock->s_crefs <= 0) + if (!psock || psock->s_conn == NULL) { return -ENOTSOCK; } diff --git a/net/socket/connect.c b/net/socket/connect.c index ed8b78aa97a..812d6994f5d 100644 --- a/net/socket/connect.c +++ b/net/socket/connect.c @@ -135,7 +135,7 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr, /* Verify that the psock corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } @@ -149,7 +149,8 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr, /* Let the address family's connect() method handle the operation */ - DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_connect != NULL); + DEBUGASSERT(psock->s_sockif != NULL && + psock->s_sockif->si_connect != NULL); ret = psock->s_sockif->si_connect(psock, addr, addrlen); if (ret < 0) { diff --git a/net/socket/getpeername.c b/net/socket/getpeername.c index 6444d17bbd8..2b082c6f2be 100644 --- a/net/socket/getpeername.c +++ b/net/socket/getpeername.c @@ -81,7 +81,7 @@ int psock_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr, { /* Verify that the psock corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/socket/getsockname.c b/net/socket/getsockname.c index 613e0f67df5..8527539da9b 100644 --- a/net/socket/getsockname.c +++ b/net/socket/getsockname.c @@ -96,7 +96,7 @@ int psock_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr, { /* Verify that the psock corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c index f6c5862b23d..a9e059bc5dd 100644 --- a/net/socket/getsockopt.c +++ b/net/socket/getsockopt.c @@ -339,7 +339,7 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/socket/listen.c b/net/socket/listen.c index 6f1b8951e3d..82ab9084df3 100644 --- a/net/socket/listen.c +++ b/net/socket/listen.c @@ -148,7 +148,7 @@ int listen(int sockfd, int backlog) /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { /* It is not a valid socket description. Distinguish between the * cases where sockfd is a just invalid and when it is a valid file diff --git a/net/socket/net_checksd.c b/net/socket/net_checksd.c deleted file mode 100644 index e7069a37b80..00000000000 --- a/net/socket/net_checksd.c +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** - * net/socket/net_checksd.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include -#include -#include - -#include "socket/socket.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: net_checksd - * - * Description: - * Check if the socket descriptor is valid for the provided TCB and if it - * supports the requested access. This trivial operation is part of the - * fdopen() operation when the fdopen() is performed on a socket - * descriptor. It simply performs some sanity checking before permitting - * the socket descriptor to be wrapped as a C FILE stream. - * - ****************************************************************************/ - -int net_checksd(int sd, int oflags) -{ - FAR struct socket *psock = sockfd_socket(sd); - - /* Verify that the sockfd corresponds to valid, allocated socket */ - - if (!psock || psock->s_crefs <= 0) - { - ninfo("No valid socket for sd: %d\n", sd); - return -EBADF; - } - - /* NOTE: We permit the socket FD to be "wrapped" in a stream as - * soon as the socket descriptor is created by socket(). Therefore - * (1) we don't care if the socket is connected yet, and (2) there - * are no access restrictions that can be enforced yet. - */ - - return OK; -} diff --git a/net/socket/net_close.c b/net/socket/net_close.c index 8d00fceac0b..5b47dcb64ba 100644 --- a/net/socket/net_close.c +++ b/net/socket/net_close.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ int psock_close(FAR struct socket *psock) /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL) { return -EBADF; } @@ -78,7 +79,7 @@ int psock_close(FAR struct socket *psock) * waiting in accept. */ - if (psock->s_crefs <= 1 && psock->s_conn != NULL) + if (psock->s_conn != NULL) { /* Assume that the socket close operation will be successful. Save * the current flags and mark the socket uninitialized. This avoids @@ -109,34 +110,11 @@ int psock_close(FAR struct socket *psock) } } - /* Then release our reference on the socket structure containing the - * connection. - */ + /* The socket will not persist... reset it */ + + memset(psock, 0, sizeof(*psock)); - psock_release(psock); return OK; } -/**************************************************************************** - * Name: net_close - * - * Description: - * Performs the close operation on socket descriptors - * - * Input Parameters: - * sockfd Socket descriptor of socket - * - * Returned Value: - * Returns zero (OK) on success. On failure, it returns a negated errno - * value to indicate the nature of the error. - * - * Assumptions: - * - ****************************************************************************/ - -int net_close(int sockfd) -{ - return psock_close(sockfd_socket(sockfd)); -} - #endif /* CONFIG_NET */ diff --git a/net/socket/net_dup.c b/net/socket/net_dup.c deleted file mode 100644 index e8a38804de1..00000000000 --- a/net/socket/net_dup.c +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** - * net/socket/net_dup.c - * - * Copyright (C) 2009, 2017 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include "socket/socket.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: psock_dup - * - * Description: - * Clone a socket descriptor to an arbitrary descriptor number. - * - * Returned Value: - * On success, returns the number of new socket. On any error, - * a negated errno value is returned. - * - ****************************************************************************/ - -int psock_dup(FAR struct socket *psock, int minsd) -{ - FAR struct socket *psock2; - int sockfd2; - int ret; - - /* Make sure that the minimum socket descriptor is within the legal range. - * The minimum value we receive is relative to file descriptor 0; we need - * map it relative of the first socket descriptor. - */ - - if (minsd >= CONFIG_NFILE_DESCRIPTORS) - { - minsd -= CONFIG_NFILE_DESCRIPTORS; - } - else - { - minsd = 0; - } - - /* Lock the scheduler throughout the following */ - - sched_lock(); - - /* Verify that the sockfd corresponds to valid, allocated socket */ - - if (!psock || psock->s_crefs <= 0) - { - ret = -EBADF; - goto errout; - } - - /* Allocate a new socket descriptor */ - - sockfd2 = sockfd_allocate(minsd); - if (sockfd2 < 0) - { - ret = -ENFILE; - goto errout; - } - - /* Get the socket structure underlying the new descriptor */ - - psock2 = sockfd_socket(sockfd2); - if (!psock2) - { - ret = -ENOSYS; /* Should not happen */ - goto errout_with_sockfd; - } - - /* Duplicate the socket state */ - - ret = psock_dup2(psock, psock2); - if (ret < 0) - { - goto errout_with_sockfd; - } - - sched_unlock(); - return sockfd2; - -errout_with_sockfd: - sockfd_release(sockfd2); - -errout: - sched_unlock(); - return ret; -} - -/**************************************************************************** - * Name: net_dup - * - * Description: - * Clone a socket descriptor to an arbitrary descriptor number. - * - * Returned Value: - * On success, returns the number of new socket. On any error, - * a negated errno value is returned. - * - ****************************************************************************/ - -int net_dup(int sockfd, int minsd) -{ - return psock_dup(sockfd_socket(sockfd), minsd); -} diff --git a/net/socket/net_dup2.c b/net/socket/net_dup2.c index 1e9f4d25d83..4ff03637e5d 100644 --- a/net/socket/net_dup2.c +++ b/net/socket/net_dup2.c @@ -59,7 +59,7 @@ * Name: psock_dup2 * * Description: - * Performs the low level, common portion of net_dup() and net_dup2() + * Performs the low level, common portion of dup * * Input Parameters: * psock1 - The existing socket that is being cloned. @@ -98,10 +98,6 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2) #endif psock2->s_conn = psock1->s_conn; /* UDP or TCP connection structure */ - /* Increment the reference count on the socket */ - - psock2->s_crefs = 1; /* One reference on the new socket itself */ - /* Increment the reference count on the underlying connection structure * for this address family type. */ @@ -140,11 +136,9 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2) inet_close(psock2); - /* Then release our reference on the socket structure containing - * the connection. - */ + /* The socket will not persist... reset it */ - psock_release(psock2); + memset(psock2, 0, sizeof(*psock2)); } } #endif @@ -152,58 +146,3 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2) net_unlock(); return ret; } - -/**************************************************************************** - * Name: net_dup2 - * - * Description: - * Clone a socket descriptor to an arbitrary descriptor number. - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is returned on - * any failure. - * - ****************************************************************************/ - -int net_dup2(int sockfd1, int sockfd2) -{ - FAR struct socket *psock1; - FAR struct socket *psock2; - int ret; - - /* Lock the scheduler throughout the following */ - - sched_lock(); - - /* Get the socket structures underly both descriptors */ - - psock1 = sockfd_socket(sockfd1); - psock2 = sockfd_socket(sockfd2); - - /* Verify that the sockfd1 and sockfd2 both refer to valid socket - * descriptors and that sockfd2 corresponds to an allocated socket - */ - - if (psock1 == NULL || psock2 == NULL || psock1->s_crefs <= 0) - { - ret = -EBADF; - goto errout; - } - - /* If sockfd2 also valid, allocated socket, then we will have to - * close it! - */ - - if (psock2->s_crefs > 0) - { - net_close(sockfd2); - } - - /* Duplicate the socket state */ - - ret = psock_dup2(psock1, psock2); - -errout: - sched_unlock(); - return ret; -} diff --git a/net/socket/net_fstat.c b/net/socket/net_fstat.c index 46b6788bded..06062ff011f 100644 --- a/net/socket/net_fstat.c +++ b/net/socket/net_fstat.c @@ -56,13 +56,13 @@ ****************************************************************************/ /**************************************************************************** - * Name: net_fstat + * Name: psock_fstat * * Description: * Performs fstat operations on socket * * Input Parameters: - * sockfd - Socket descriptor of the socket to operate on + * psock - The pointer of the socket to operate on * buf - Caller-provided location in which to return the fstat data * * Returned Value: @@ -71,14 +71,10 @@ * ****************************************************************************/ -int net_fstat(int sockfd, FAR struct stat *buf) +int psock_fstat(FAR struct socket *psock, FAR struct stat *buf) { - FAR struct socket *psock; int ret = OK; - /* Get the underlying socket structure */ - - psock = sockfd_socket(sockfd); if (psock == NULL) { /* sockfd does not refer to a valid, open socket */ diff --git a/net/socket/net_poll.c b/net/socket/net_poll.c index 11fa7c41ff9..45747df89f5 100644 --- a/net/socket/net_poll.c +++ b/net/socket/net_poll.c @@ -77,42 +77,3 @@ int psock_poll(FAR struct socket *psock, FAR struct pollfd *fds, bool setup) DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_poll != NULL); return psock->s_sockif->si_poll(psock, fds, setup); } - -/**************************************************************************** - * Name: net_poll - * - * Description: - * The standard poll() operation redirects operations on socket descriptors - * to this function. - * - * Input Parameters: - * fd - The socket descriptor of interest - * fds - The structure describing the events to be monitored, OR NULL if - * this is a request to stop monitoring events. - * setup - true: Setup up the poll; false: Teardown the poll - * - * Returned Value: - * 0: Success; Negated errno on failure - * - ****************************************************************************/ - -int net_poll(int sockfd, struct pollfd *fds, bool setup) -{ - FAR struct socket *psock; - - DEBUGASSERT(fds != NULL); - - /* Get the underlying socket structure and verify that the sockfd - * corresponds to valid, allocated socket - */ - - psock = sockfd_socket(sockfd); - if (!psock || psock->s_crefs <= 0) - { - return -EBADF; - } - - /* Then let psock_poll() do the heavy lifting */ - - return psock_poll(psock, fds, setup); -} diff --git a/net/socket/net_sendfile.c b/net/socket/net_sendfile.c index a499504b126..c9407f73095 100644 --- a/net/socket/net_sendfile.c +++ b/net/socket/net_sendfile.c @@ -60,10 +60,10 @@ ****************************************************************************/ /**************************************************************************** - * Name: net_sendfile + * Name: psock_sendfile * * Description: - * The net_sendfile() call may be used only when the socket is in a + * The psock_sendfile() call may be used only when the socket is in a * connected state (so that the intended recipient is known). * * Input Parameters: @@ -118,17 +118,16 @@ * ****************************************************************************/ -ssize_t net_sendfile(int outfd, FAR struct file *infile, FAR off_t *offset, - size_t count) +ssize_t psock_sendfile(FAR struct socket *psock, FAR struct file *infile, + FAR off_t *offset, size_t count) { - FAR struct socket *psock = sockfd_socket(outfd); ssize_t ret = -ENOSYS; DEBUGASSERT(psock != NULL && infile != NULL); /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock != NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { nerr("ERROR: Invalid socket\n"); _SO_SETERRNO(psock, EBADF); diff --git a/net/socket/net_sockets.c b/net/socket/net_sockets.c deleted file mode 100644 index 547e283dce3..00000000000 --- a/net/socket/net_sockets.c +++ /dev/null @@ -1,264 +0,0 @@ -/**************************************************************************** - * net/socket/net_sockets.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "socket/socket.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void _net_semtake(FAR struct socketlist *list) -{ - net_lockedwait_uninterruptible(&list->sl_sem); -} - -#define _net_semgive(list) nxsem_post(&list->sl_sem) - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: net_initlist - * - * Description: - * Initialize a list of sockets for a new task - * - * Input Parameters: - * list -- A reference to the pre-allocated socket list to be initialized. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void net_initlist(FAR struct socketlist *list) -{ - /* Initialize the list access mutex */ - - nxsem_init(&list->sl_sem, 0, 1); -} - -/**************************************************************************** - * Name: net_releaselist - * - * Description: - * Release resources held by the socket list - * - * Input Parameters: - * list - A reference to the pre-allocated socket list to be un- - * initialized. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void net_releaselist(FAR struct socketlist *list) -{ - int ndx; - - DEBUGASSERT(list); - - /* Close each open socket in the list. */ - - for (ndx = 0; ndx < CONFIG_NSOCKET_DESCRIPTORS; ndx++) - { - FAR struct socket *psock = &list->sl_sockets[ndx]; - if (psock->s_crefs > 0) - { - psock_close(psock); - } - } - - /* Destroy the semaphore */ - - nxsem_destroy(&list->sl_sem); -} - -/**************************************************************************** - * Name: sockfd_allocate - * - * Description: - * Allocate a socket descriptor - * - * Input Parameters: - * Lowest socket descriptor index to be used. - * - * Returned Value: - * On success, a socket descriptor >= minsd is returned. A negated errno - * value is returned on failure. - * - ****************************************************************************/ - -int sockfd_allocate(int minsd) -{ - FAR struct socketlist *list; - int i; - - /* Get the socket list for this task/thread */ - - list = nxsched_get_sockets(); - if (list) - { - /* Search for a socket structure with no references */ - - _net_semtake(list); - for (i = minsd; i < CONFIG_NSOCKET_DESCRIPTORS; i++) - { - /* Are there references on this socket? */ - - if (!list->sl_sockets[i].s_crefs) - { - /* No take the reference and return the index + an offset - * as the socket descriptor. - */ - - memset(&list->sl_sockets[i], 0, sizeof(struct socket)); - list->sl_sockets[i].s_crefs = 1; - _net_semgive(list); - return i + __SOCKFD_OFFSET; - } - } - - _net_semgive(list); - } - - return ERROR; -} - -/**************************************************************************** - * Name: psock_release - * - * Description: - * Free a socket. - * - * Input Parameters: - * psock - A reference to the socket instance to be freed. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void psock_release(FAR struct socket *psock) -{ - if (psock != NULL) - { - /* Decrement the count if there the socket will persist - * after this. - */ - - if (psock->s_crefs > 1) - { - psock->s_crefs--; - } - else - { - /* The socket will not persist... reset it */ - - memset(psock, 0, sizeof(struct socket)); - } - } -} - -/**************************************************************************** - * Name: sockfd_release - * - * Description: - * Free the socket by its socket descriptor. - * - * Input Parameters: - * sockfd - Socket descriptor identifies the socket to be released. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void sockfd_release(int sockfd) -{ - /* Get the socket structure for this sockfd */ - - FAR struct socket *psock = sockfd_socket(sockfd); - - if (psock) - { - /* Take the list semaphore so that there will be no accesses - * to this socket structure. - */ - - FAR struct socketlist *list = nxsched_get_sockets(); - if (list) - { - _net_semtake(list); - psock_release(psock); - _net_semgive(list); - } - } -} - -/**************************************************************************** - * Name: sockfd_socket - * - * Description: - * Given a socket descriptor, return the underlying socket structure. - * - * Input Parameters: - * sockfd - The socket descriptor index to use. - * - * Returned Value: - * On success, a reference to the socket structure associated with the - * the socket descriptor is returned. NULL is returned on any failure. - * - ****************************************************************************/ - -FAR struct socket *sockfd_socket(int sockfd) -{ - FAR struct socketlist *list; - int ndx = sockfd - __SOCKFD_OFFSET; - - if (ndx >= 0 && ndx < CONFIG_NSOCKET_DESCRIPTORS) - { - list = nxsched_get_sockets(); - if (list) - { - return &list->sl_sockets[ndx]; - } - } - - return NULL; -} diff --git a/net/socket/net_vfcntl.c b/net/socket/net_vfcntl.c index a065e4f5fc0..3a048595ea4 100644 --- a/net/socket/net_vfcntl.c +++ b/net/socket/net_vfcntl.c @@ -81,7 +81,7 @@ int psock_vfcntl(FAR struct socket *psock, int cmd, va_list ap) /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } @@ -93,66 +93,6 @@ int psock_vfcntl(FAR struct socket *psock, int cmd, va_list ap) net_lock(); switch (cmd) { - case F_DUPFD: - /* Return a new file descriptor which shall be the lowest numbered - * available (that is, not already open) file descriptor greater than - * or equal to the third argument, arg, taken as an integer of type - * int. The new file descriptor shall refer to the same open file - * description as the original file descriptor, and shall share any - * locks. The FD_CLOEXEC flag associated with the new file - * descriptor shall be cleared to keep the file open across calls - * to one of the exec functions. - */ - - { - /* Does not set the errno value on failure */ - - ret = psock_dup(psock, va_arg(ap, int)); - } - break; - - case F_GETFD: - /* Get the file descriptor flags defined in that are - * associated with the file descriptor fd. File descriptor flags - * are associated with a single file descriptor and do not affect - * other file descriptors that refer to the same file. - */ - - { - ret = _SS_ISCLOEXEC(psock->s_flags) ? FD_CLOEXEC : 0; - } - break; - - case F_SETFD: - /* Set the file descriptor flags defined in , that are - * associated with fd, to the third argument, arg, taken as type int. - * If the FD_CLOEXEC flag in the third argument is 0, the file shall - * remain open across the exec functions; otherwise, the file shall - * be closed upon successful execution of one of the exec functions. - */ - - { - int oflags = va_arg(ap, int); - - if (oflags & ~FD_CLOEXEC) - { - ret = -ENOSYS; - break; - } - - if (oflags & FD_CLOEXEC) - { - psock->s_flags |= _SF_CLOEXEC; - } - else - { - psock->s_flags &= ~_SF_CLOEXEC; - } - - ret = OK; - } - break; - case F_GETFL: /* Get the file status flags and file access modes, defined in * , for the file description associated with fd. The file @@ -326,25 +266,3 @@ int psock_fcntl(FAR struct socket *psock, int cmd, ...) va_end(ap); return ret; } - -/**************************************************************************** - * Name: net_vfcntl - * - * Description: - * Performs fcntl operations on socket - * - * Input Parameters: - * sockfd - Socket descriptor of the socket to operate on - * cmd - The fcntl command. - * ap - Command-specific arguments - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is returned on - * any failure to indicate the nature of the failure. - * - ****************************************************************************/ - -int net_vfcntl(int sockfd, int cmd, va_list ap) -{ - return psock_vfcntl(sockfd_socket(sockfd), cmd, ap); -} diff --git a/net/socket/recvmsg.c b/net/socket/recvmsg.c index 61bd4bff978..207748ecae0 100644 --- a/net/socket/recvmsg.c +++ b/net/socket/recvmsg.c @@ -104,7 +104,7 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/socket/sendmsg.c b/net/socket/sendmsg.c index 35fd5f3aecd..938486a5991 100644 --- a/net/socket/sendmsg.c +++ b/net/socket/sendmsg.c @@ -94,7 +94,7 @@ ssize_t psock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c index 74e62a422ab..39cb5b6b0f0 100644 --- a/net/socket/setsockopt.c +++ b/net/socket/setsockopt.c @@ -361,7 +361,7 @@ int psock_setsockopt(FAR struct socket *psock, int level, int option, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { return -EBADF; } diff --git a/net/socket/socket.c b/net/socket/socket.c index b0ea41f95e1..5041ab4a869 100644 --- a/net/socket/socket.c +++ b/net/socket/socket.c @@ -84,7 +84,6 @@ int psock_socket(int domain, int type, int protocol, /* Initialize the socket structure */ - psock->s_crefs = 1; psock->s_domain = domain; psock->s_proto = protocol; psock->s_conn = NULL; @@ -92,11 +91,6 @@ int psock_socket(int domain, int type, int protocol, psock->s_sndcb = NULL; #endif - if (type & SOCK_CLOEXEC) - { - psock->s_flags |= _SF_CLOEXEC; - } - if (type & SOCK_NONBLOCK) { psock->s_flags |= _SF_NONBLOCK; @@ -114,120 +108,38 @@ int psock_socket(int domain, int type, int protocol, ret = g_usrsock_sockif.si_setup(psock, protocol); psock->s_sockif = &g_usrsock_sockif; - return ret; } + else #endif /* CONFIG_NET_USRSOCK */ - - /* Get the socket interface */ - - sockif = net_sockif(domain, type, protocol); - if (sockif == NULL) { - nerr("ERROR: socket address family unsupported: %d\n", domain); - return -EAFNOSUPPORT; - } + /* Get the socket interface */ - /* The remaining of the socket initialization depends on the address - * family. - */ + sockif = net_sockif(domain, type, protocol); + if (sockif == NULL) + { + nerr("ERROR: socket address family unsupported: %d\n", domain); + return -EAFNOSUPPORT; + } - DEBUGASSERT(sockif->si_setup != NULL); - psock->s_sockif = sockif; + /* The remaining of the socket initialization depends on the address + * family. + */ - ret = sockif->si_setup(psock, protocol); - if (ret < 0) - { - nerr("ERROR: socket si_setup() failed: %d\n", ret); - return ret; - } + DEBUGASSERT(sockif->si_setup != NULL); + psock->s_sockif = sockif; - return OK; -} - -/**************************************************************************** - * Name: socket - * - * Description: - * socket() creates an endpoint for communication and returns a descriptor. - * - * Input Parameters: - * domain (see sys/socket.h) - * type (see sys/socket.h) - * protocol (see sys/socket.h) - * - * Returned Value: - * A non-negative socket descriptor on success; -1 on error with errno set - * appropriately. - * - * EACCES - * Permission to create a socket of the specified type and/or protocol - * is denied. - * EAFNOSUPPORT - * The implementation does not support the specified address family. - * EINVAL - * Unknown protocol, or protocol family not available. - * EMFILE - * Process file table overflow. - * ENFILE - * The system limit on the total number of open files has been reached. - * ENOBUFS or ENOMEM - * Insufficient memory is available. The socket cannot be created until - * sufficient resources are freed. - * EPROTONOSUPPORT - * The protocol type or the specified protocol is not supported within - * this domain. - * - * Assumptions: - * - ****************************************************************************/ - -int socket(int domain, int type, int protocol) -{ - FAR struct socket *psock; - int errcode; - int sockfd; - int ret; - - /* Allocate a socket descriptor */ - - sockfd = sockfd_allocate(0); - if (sockfd < 0) - { - nerr("ERROR: Failed to allocate a socket descriptor\n"); - errcode = ENFILE; - goto errout; - } - - /* Get the underlying socket structure */ - - psock = sockfd_socket(sockfd); - if (!psock) - { - errcode = ENOSYS; /* should not happen */ - goto errout_with_sockfd; - } - - /* Initialize the socket structure */ - - ret = psock_socket(domain, type, protocol, psock); - if (ret < 0) - { - nerr("ERROR: psock_socket() failed: %d\n", ret); - errcode = -ret; - goto errout_with_sockfd; + ret = sockif->si_setup(psock, protocol); + if (ret < 0) + { + nerr("ERROR: socket si_setup() failed: %d\n", ret); + return ret; + } } /* The socket has been successfully initialized */ psock->s_flags |= _SF_INITD; - return sockfd; - -errout_with_sockfd: - sockfd_release(sockfd); - -errout: - set_errno(errcode); - return ERROR; + return ret; } #endif /* CONFIG_NET */ diff --git a/net/socket/socket.h b/net/socket/socket.h index bd2a0ea792e..841637209da 100644 --- a/net/socket/socket.h +++ b/net/socket/socket.h @@ -139,55 +139,6 @@ extern "C" * Public Function Prototypes ****************************************************************************/ -/**************************************************************************** - * Name: sockfd_allocate - * - * Description: - * Allocate a socket descriptor - * - * Input Parameters: - * Lowest socket descriptor index to be used. - * - * Returned Value: - * On success, a socket descriptor >= minsd is returned. A negated errno - * value is returned on failure. - * - ****************************************************************************/ - -int sockfd_allocate(int minsd); - -/**************************************************************************** - * Name: psock_release - * - * Description: - * Free a socket. - * - * Input Parameters: - * psock - A reference to the socket instance to be freed. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void psock_release(FAR struct socket *psock); - -/**************************************************************************** - * Name: sockfd_release - * - * Description: - * Free the socket by its socket descriptor. - * - * Input Parameters: - * sockfd - Socket descriptor identifies the socket to be released. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void sockfd_release(int sockfd); - /**************************************************************************** * Name: net_sockif * @@ -230,5 +181,10 @@ net_sockif(sa_family_t family, int type, int protocol); int net_timeo(clock_t start_time, socktimeo_t timeo); #endif +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* CONFIG_NET */ #endif /* _NET_SOCKET_SOCKET_H */ diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 754d42d0894..5cd5be37653 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -983,7 +983,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, bool nonblock; int ret = OK; - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { nerr("ERROR: Invalid socket\n"); ret = -EBADF; @@ -1000,7 +1000,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, /* Make sure that we have the IP address mapping */ conn = (FAR struct tcp_conn_s *)psock->s_conn; - DEBUGASSERT(conn); #if defined(CONFIG_NET_ARP_SEND) || defined(CONFIG_NET_ICMPv6_NEIGHBOR) #ifdef CONFIG_NET_ARP_SEND @@ -1224,7 +1223,7 @@ int psock_tcp_cansend(FAR struct socket *psock) { /* Verify that we received a valid socket */ - if (!psock || psock->s_crefs <= 0) + if (!psock || !psock->s_conn) { nerr("ERROR: Invalid socket\n"); return -EBADF; diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 387f3c78d08..981ea7c686f 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -593,7 +593,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (psock == NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { nerr("ERROR: Invalid socket\n"); ret = -EBADF; diff --git a/net/tcp/tcp_txdrain.c b/net/tcp/tcp_txdrain.c index 4993df828fe..76bb21a4d2d 100644 --- a/net/tcp/tcp_txdrain.c +++ b/net/tcp/tcp_txdrain.c @@ -105,7 +105,7 @@ int tcp_txdrain(FAR struct socket *psock, unsigned int timeout) sem_t waitsem; int ret; - DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && psock->s_conn != NULL); + DEBUGASSERT(psock != NULL && psock->s_conn != NULL); DEBUGASSERT(psock->s_type == SOCK_STREAM); conn = (FAR struct tcp_conn_s *)psock->s_conn; diff --git a/net/udp/udp_sendto_buffered.c b/net/udp/udp_sendto_buffered.c index a2511924f14..528e188f8a8 100644 --- a/net/udp/udp_sendto_buffered.c +++ b/net/udp/udp_sendto_buffered.c @@ -821,7 +821,7 @@ int psock_udp_cansend(FAR struct socket *psock) { /* Verify that we received a valid socket */ - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_conn == NULL) { nerr("ERROR: Invalid socket\n"); return -EBADF; diff --git a/net/udp/udp_txdrain.c b/net/udp/udp_txdrain.c index 01b12bb0174..4a977fea7cd 100644 --- a/net/udp/udp_txdrain.c +++ b/net/udp/udp_txdrain.c @@ -105,7 +105,7 @@ int udp_txdrain(FAR struct socket *psock, unsigned int timeout) sem_t waitsem; int ret; - DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && psock->s_conn != NULL); + DEBUGASSERT(psock != NULL && psock->s_conn != NULL); DEBUGASSERT(psock->s_type == SOCK_DGRAM); conn = (FAR struct udp_conn_s *)psock->s_conn; diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 58344748893..a3396e001c0 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -157,12 +157,6 @@ static inline void group_release(FAR struct task_group_s *group) lib_stream_release(group); #endif /* CONFIG_FILE_STREAM */ -#ifdef CONFIG_NET - /* Free resource held by the socket list */ - - net_releaselist(&group->tg_socketlist); -#endif - #ifndef CONFIG_DISABLE_ENVIRON /* Release all shared environment variables */ diff --git a/sched/group/group_setupidlefiles.c b/sched/group/group_setupidlefiles.c index ff8e8c54ba5..b990c5ed06e 100644 --- a/sched/group/group_setupidlefiles.c +++ b/sched/group/group_setupidlefiles.c @@ -84,12 +84,6 @@ int group_setupidlefiles(FAR struct task_tcb_s *tcb) files_initlist(&group->tg_filelist); -#ifdef CONFIG_NET - /* Allocate socket descriptors for the TCB */ - - net_initlist(&group->tg_socketlist); -#endif - /* Open stdin, dup to get stdout and stderr. This should always * be the first file opened and, hence, should always get file * descriptor 0. diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c index 5dff08e6086..6a1742d4939 100644 --- a/sched/group/group_setuptaskfiles.c +++ b/sched/group/group_setuptaskfiles.c @@ -113,65 +113,6 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb) # define sched_dupfiles(tcb) #endif /* !CONFIG_FDCLONE_DISABLE */ -/**************************************************************************** - * Name: sched_dupsockets - * - * Description: - * Duplicate the parent task's socket descriptors. - * - * Input Parameters: - * tcb - tcb of the new task. - * - * Returned Value: - * None - * - ****************************************************************************/ - -#if defined(CONFIG_NET) && !defined(CONFIG_SDCLONE_DISABLE) -static inline void sched_dupsockets(FAR struct task_tcb_s *tcb) -{ - /* The parent task is the one at the head of the ready-to-run list */ - - FAR struct tcb_s *rtcb = this_task(); - FAR struct socket *parent; - FAR struct socket *child; - int i; - - /* Duplicate the socket descriptors of all sockets opened by the parent - * task. - */ - - DEBUGASSERT(tcb && tcb->cmn.group && rtcb->group); - - /* Get pointers to the parent and child task socket lists */ - - parent = rtcb->group->tg_socketlist.sl_sockets; - child = tcb->cmn.group->tg_socketlist.sl_sockets; - - /* Check each socket in the parent socket list */ - - for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++) - { - /* Check if this parent socket is valid. Valid means both (1) - * allocated and (2) successfully initialized. A complexity in SMP - * mode is that a socket my be allocated, but not yet initialized when - * the socket is cloned by another pthread. - * - * Sockets with the close-on-exec flag set should not be cloned either. - */ - - if (_PS_VALID(&parent[i]) && !_SS_ISCLOEXEC(parent[i].s_flags)) - { - /* Yes... duplicate it for the child */ - - psock_dup2(&parent[i], &child[i]); - } - } -} -#else /* CONFIG_NET && !CONFIG_SDCLONE_DISABLE */ -# define sched_dupsockets(tcb) -#endif /* CONFIG_NET && !CONFIG_SDCLONE_DISABLE */ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -208,20 +149,10 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb) files_initlist(&group->tg_filelist); -#ifdef CONFIG_NET - /* Allocate socket descriptors for the TCB */ - - net_initlist(&group->tg_socketlist); -#endif - /* Duplicate the parent task's file descriptors */ sched_dupfiles(tcb); - /* Duplicate the parent task's socket descriptors */ - - sched_dupsockets(tcb); - /* Allocate file/socket streams for the new TCB */ #ifdef CONFIG_FILE_STREAM diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs index f46c39db7ae..d42d37985e8 100644 --- a/sched/sched/Make.defs +++ b/sched/sched/Make.defs @@ -23,7 +23,7 @@ CSRCS += sched_addreadytorun.c sched_removereadytorun.c CSRCS += sched_addprioritized.c sched_mergeprioritized.c sched_mergepending.c CSRCS += sched_addblocked.c sched_removeblocked.c CSRCS += sched_gettcb.c sched_verifytcb.c sched_releasetcb.c -CSRCS += sched_getsockets.c sched_getstreams.c +CSRCS += sched_getstreams.c CSRCS += sched_setparam.c sched_setpriority.c sched_getparam.c CSRCS += sched_setscheduler.c sched_getscheduler.c CSRCS += sched_yield.c sched_rrgetinterval.c sched_foreach.c diff --git a/sched/sched/sched_getsockets.c b/sched/sched/sched_getsockets.c deleted file mode 100644 index b29421d9c49..00000000000 --- a/sched/sched/sched_getsockets.c +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** - * sched/sched/sched_getsockets.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include "sched/sched.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxsched_get_sockets - * - * Description: - * Return a pointer to the socket list for this thread - * - * Input Parameters: - * None - * - * Returned Value: - * A pointer to the errno. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_NET -FAR struct socketlist *nxsched_get_sockets(void) -{ - FAR struct tcb_s *rtcb = this_task(); - FAR struct task_group_s *group = rtcb->group; - - DEBUGASSERT(group); - return &group->tg_socketlist; -} -#endif