Revert "net: unify socket info file descriptor"

This reverts commit 27b332283e.
This commit is contained in:
ligd
2021-02-25 23:24:21 +08:00
committed by 刘海涛
parent a25ad34d82
commit df76063a35
67 changed files with 1539 additions and 516 deletions
+1 -1
View File
@@ -1226,7 +1226,7 @@ static int telnet_poll(FAR struct file *filep, FAR struct pollfd *fds,
*/
psock = &priv->td_psock;
if (!psock || !psock->s_conn)
if (!psock || psock->s_crefs <= 0)
{
return -EBADF;
}
-1
View File
@@ -50,7 +50,6 @@ 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
+22 -23
View File
@@ -1075,6 +1075,9 @@ 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;
@@ -1108,7 +1111,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 && !INODE_IS_SOCKET(file->f_inode))
if (file->f_inode)
{
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %8ld %04x\n", i, (long)file->f_pos,
@@ -1145,33 +1148,29 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
/* Examine each open socket descriptor */
for (i = 0, file = group->tg_filelist.fl_files;
i < CONFIG_NFILE_DESCRIPTORS;
i++, file++)
for (i = 0, socket = group->tg_socketlist.sl_sockets;
i < CONFIG_NSOCKET_DESCRIPTORS;
i++, socket++)
{
/* Is there an connection associated with the socket descriptor? */
if (file->f_inode && INODE_IS_SOCKET(file->f_inode))
if (socket->s_conn)
{
FAR struct socket *socket = file->f_inode->i_private;
if (socket->s_conn)
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %2d %3d %02x",
i + CONFIG_NFILE_DESCRIPTORS,
socket->s_crefs, socket->s_type,
socket->s_flags);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
remaining, &offset);
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
{
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %3d %02x",
i + CONFIG_NFILE_DESCRIPTORS,
socket->s_type,
socket->s_flags);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
remaining, &offset);
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
{
return totalsize;
}
return totalsize;
}
}
}
-31
View File
@@ -1,31 +0,0 @@
############################################################################
# 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
-298
View File
@@ -1,298 +0,0 @@
/****************************************************************************
* 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 <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/net/net.h>
#include <nuttx/fs/fs.h>
#include <nuttx/mm/mm.h>
#include <sys/socket.h>
#include <assert.h>
#include <fcntl.h>
#include <errno.h>
#include <debug.h>
#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.
*
* 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 sockfd;
*psock = kmm_zalloc(sizeof(**psock));
if (*psock == NULL)
{
return -ENOMEM;
}
sockfd = files_allocate(&g_sock_inode, O_RDWR, 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;
FAR struct file *filep;
int errcode;
int sockfd;
int ret;
/* Allocate a socket descriptor */
sockfd = sockfd_allocate(&psock);
if (sockfd < 0)
{
nerr("ERROR: Failed to allocate a socket descriptor\n");
errcode = -sockfd;
goto errout;
}
ret = fs_getfilep(sockfd, &filep);
if (ret < 0)
{
goto errout_with_sockfd;
}
if (type & SOCK_CLOEXEC)
{
filep->f_oflags |= O_CLOEXEC;
}
/* 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;
}
return sockfd;
errout_with_sockfd:
close(sockfd);
errout:
set_errno(errcode);
return ERROR;
}
+16 -1
View File
@@ -46,6 +46,10 @@
#include <nuttx/cancelpt.h>
#include <nuttx/fs/fs.h>
#ifdef CONFIG_NET
# include <nuttx/net/net.h>
#endif
#include "inode/inode.h"
/****************************************************************************
@@ -126,7 +130,18 @@ int nx_close(int fd)
if (fd >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
/* 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
+18 -1
View File
@@ -134,7 +134,24 @@ int nx_dup(int fd)
}
else
{
return -EBADF;
/* 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. */
return net_dup(fd, CONFIG_NFILE_DESCRIPTORS);
}
else
#endif
{
/* No.. then it is a bad descriptor number */
return -EBADF;
}
}
}
+18 -2
View File
@@ -117,7 +117,6 @@ 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);
}
@@ -167,7 +166,24 @@ int nx_dup2(int fd1, int fd2)
if (fd1 >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
/* 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
{
+26 -18
View File
@@ -236,6 +236,7 @@ static int file_vfcntl(FAR struct file *filep, int cmd, va_list ap)
static int nx_vfcntl(int fd, int cmd, va_list ap)
{
FAR struct file *filep;
int ret;
/* Did we get a valid file descriptor? */
@@ -243,34 +244,41 @@ static int nx_vfcntl(int fd, int cmd, va_list ap)
{
/* Get the file structure corresponding to the file descriptor. */
if (fs_getfilep(fd, &filep) >= 0)
ret = fs_getfilep(fd, &filep);
if (ret >= 0)
{
DEBUGASSERT(filep != NULL);
/* 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)
{
/* Yes.. defer socket descriptor operations to psock_vfcntl(). The
* errno is not set on failures.
*/
return psock_vfcntl(sockfd_socket(fd), cmd, ap);
}
#endif
/* Let file_vfcntl() do the real work. The errno is not set on
* failures.
*/
return file_vfcntl(filep, cmd, 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;
}
}
/* No.. this descriptor number is out of range */
return -EBADF;
return ret;
}
/****************************************************************************
+11
View File
@@ -33,6 +33,7 @@
#include <nuttx/semaphore.h>
#include <nuttx/fs/fs.h>
#include <nuttx/lib/lib.h>
#include <nuttx/net/net.h>
#include "inode/inode.h"
@@ -145,8 +146,18 @@ int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
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
+14 -15
View File
@@ -237,8 +237,22 @@ int fstat(int fd, FAR struct stat *buf)
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
@@ -252,21 +266,6 @@ 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);
+18 -1
View File
@@ -46,6 +46,12 @@
#include <fcntl.h>
#include <assert.h>
#include <net/if.h>
#ifdef CONFIG_NET
# include <nuttx/net/net.h>
#endif
#include "inode/inode.h"
/****************************************************************************
@@ -96,7 +102,18 @@ static int nx_vioctl(int fd, int req, va_list ap)
if (fd >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
/* 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;
}
}
else
{
+38 -3
View File
@@ -49,6 +49,7 @@
#include <nuttx/semaphore.h>
#include <nuttx/cancelpt.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include <arch/irq.h>
@@ -89,7 +90,18 @@ static int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup)
if (fd >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
/* 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 fs_poll(fd, fds, setup);
@@ -152,6 +164,15 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds,
}
break;
#ifdef CONFIG_NET
case POLLSOCK:
if (fds[i].ptr != NULL)
{
ret = psock_poll(fds[i].ptr, &fds[i], true);
}
break;
#endif
default:
ret = -EINVAL;
break;
@@ -177,6 +198,12 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds,
file_poll(fds[j].ptr, &fds[j], false);
break;
#ifdef CONFIG_NET
case POLLSOCK:
psock_poll(fds[j].ptr, &fds[j], false);
break;
#endif
default:
break;
}
@@ -228,6 +255,15 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds,
}
break;
#ifdef CONFIG_NET
case POLLSOCK:
if (fds[i].ptr != NULL)
{
status = psock_poll(fds[i].ptr, &fds[i], false);
}
break;
#endif
default:
status = -EINVAL;
break;
@@ -290,8 +326,7 @@ 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) ||
INODE_IS_SOCKET(inode)) &&
if ((INODE_IS_DRIVER(inode) || INODE_IS_MQUEUE(inode)) &&
inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL)
{
/* Yes, it does... Setup the poll */
+13
View File
@@ -41,12 +41,14 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <errno.h>
#include <nuttx/cancelpt.h>
#include <nuttx/net/net.h>
#include "inode/inode.h"
@@ -63,6 +65,7 @@
*
* - 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:
@@ -139,7 +142,17 @@ ssize_t nx_read(int fd, FAR void *buf, size_t nbytes)
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
{
#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
}
else
{
+10 -10
View File
@@ -108,35 +108,35 @@ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count)
* descriptor? Check the source file: Is it a normal file?
*/
FAR struct socket *psock;
psock = sockfd_socket(outfd);
if (psock != NULL)
if ((unsigned int)outfd >= CONFIG_NFILE_DESCRIPTORS &&
(unsigned int)infd < CONFIG_NFILE_DESCRIPTORS)
{
FAR struct file *filep;
int ret;
/* This appears to be a file-to-socket transfer. Get the file
* structure.
*/
FAR struct file *infilep;
int ret = fs_getfilep(infd, &infilep);
ret = fs_getfilep(infd, &filep);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
DEBUGASSERT(infilep != NULL);
DEBUGASSERT(filep != NULL);
/* Then let psock_sendfile do the work. */
/* Then let net_sendfile do the work. */
ret = psock_sendfile(psock, infilep, offset, count);
ret = net_sendfile(outfd, filep, offset, count);
if (ret >= 0 || get_errno() != ENOSYS)
{
return ret;
}
/* Fall back to the slow path if errno equals ENOSYS,
* because psock_sendfile fail to optimize this transfer.
* because net_sendfile fail to optimize this transfer.
*/
}
#endif
+16 -2
View File
@@ -47,7 +47,12 @@
#include <errno.h>
#include <assert.h>
#ifdef CONFIG_NET_TCP
# include <sys/socket.h>
#endif
#include <nuttx/cancelpt.h>
#include <nuttx/net/net.h>
#include "inode/inode.h"
@@ -66,6 +71,7 @@
*
* - 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
@@ -118,7 +124,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf,
* - It is not a cancellation point.
*
* Input Parameters:
* fd - file descriptor to write to
* fd - file descriptor (or socket descriptor) to write to
* buf - Data to write
* nbytes - Length of data to write
*
@@ -144,7 +150,15 @@ ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes)
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
{
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_CAN)
/* Write to a socket descriptor is equivalent to
* send with flags == 0.
*/
ret = nx_send(fd, buf, nbytes, 0);
#else
ret = -EBADF;
#endif
}
else
{
@@ -175,7 +189,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 to write to
* fd - file descriptor (or socket descriptor) to write to
* buf - Data to write
* nbytes - Length of data to write
*
+1 -1
View File
@@ -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 > 127
#if (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS) > 127
int16_t aio_fildes; /* File descriptor (should be int) */
#else
int8_t aio_fildes; /* File descriptor (should be int) */
-3
View File
@@ -114,7 +114,6 @@
#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) \
@@ -129,7 +128,6 @@
#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) \
@@ -147,7 +145,6 @@
#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 */
+194 -20
View File
@@ -96,6 +96,7 @@
/* 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 */
@@ -114,6 +115,7 @@
/* 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)
@@ -123,7 +125,7 @@
/* Determine if a socket is valid. Valid means both (1) allocated and (2)
* successfully initialized:
*
* Allocated: psock->s_conn != NULL
* Allocated: psock->s_crefs > 0
* 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
@@ -132,7 +134,7 @@
* pthread.
*/
#define _PS_ALLOCD(psock) ((psock)->s_conn != NULL)
#define _PS_ALLOCD(psock) ((psock)->s_crefs > 0)
#define _PS_INITD(psock) (_SS_INITD((psock)->s_flags))
#define _PS_VALID(psock) (_PS_ALLOCD(psock) && _PS_INITD(psock))
@@ -260,6 +262,7 @@ 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 */
@@ -294,6 +297,16 @@ 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
****************************************************************************/
@@ -511,21 +524,51 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid);
#endif
/****************************************************************************
* Name: sockfd_allocate
* Name: net_checksd
*
* Description:
* Allocate a socket descriptor
*
* Input Parameters:
* psock A double pointer to socket structure to be allocated.
*
* Returned Value:
* Allocate a struct files instance and associate it with an socket
* instance. Returns the file descriptor == index into the files array.
* 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 sockfd_allocate(FAR struct socket **psock);
int net_checksd(int fd, int oflags);
/****************************************************************************
* Name: net_initlist
*
* Description:
* Initialize a list of sockets for a new task
*
* Input Parameters:
* list -- A reference to the pre-alloated socket list to be initialized.
*
* Returned Value:
* None
*
****************************************************************************/
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);
/****************************************************************************
* Name: sockfd_socket
@@ -587,6 +630,25 @@ FAR struct socket *sockfd_socket(int sockfd);
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
*
@@ -1229,6 +1291,39 @@ 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
*
@@ -1252,10 +1347,32 @@ struct pollfd; /* Forward reference -- see poll.h */
int psock_poll(FAR struct socket *psock, struct pollfd *fds, bool setup);
/****************************************************************************
* Name: psock_dup2
* Name: net_poll
*
* Description:
* Clone a socket instance to an new instance.
* 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,
@@ -1263,16 +1380,54 @@ int psock_poll(FAR struct socket *psock, struct pollfd *fds, bool setup);
*
****************************************************************************/
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()
*
****************************************************************************/
int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2);
/****************************************************************************
* Name: psock_fstat
* 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
*
* Description:
* Performs fstat operations on socket
*
* Input Parameters:
* psock - An instance of the internal socket structure.
* sockfd - Socket descriptor of the socket to operate on
* buf - Caller-provided location in which to return the fstat data
*
* Returned Value:
@@ -1283,10 +1438,10 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2);
struct stat; /* Forward reference. See sys/stat.h */
int psock_fstat(FAR struct socket *psock, FAR struct stat *buf);
int net_fstat(int sockfd, FAR struct stat *buf);
/****************************************************************************
* Name: psock_sendfile
* Name: net_sendfile
*
* Description:
* The send() call may be used only when the socket is in a connected state
@@ -1349,8 +1504,8 @@ int psock_fstat(FAR struct socket *psock, FAR struct stat *buf);
#ifdef CONFIG_NET_SENDFILE
struct file;
ssize_t psock_sendfile(FAR struct socket *psock, FAR struct file *infile,
FAR off_t *offset, size_t count);
ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
size_t count);
#endif
/****************************************************************************
@@ -1393,6 +1548,25 @@ 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
*
+10
View File
@@ -594,6 +594,12 @@ 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 ********************************************************/
@@ -904,6 +910,10 @@ 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
*
+2 -1
View File
@@ -93,7 +93,8 @@
#define POLLFD (0x00)
#define POLLFILE (0x40)
#define POLLMASK (0x40)
#define POLLSOCK (0x80)
#define POLLMASK (0xC0)
/****************************************************************************
* Public Type Definitions
+5 -1
View File
@@ -52,7 +52,11 @@
/* Get the total number of descriptors that we will have to support */
#define FD_SETSIZE CONFIG_NFILE_DESCRIPTORS
#ifdef CONFIG_NSOCKET_DESCRIPTORS
# define FD_SETSIZE (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)
#else
# define FD_SETSIZE CONFIG_NFILE_DESCRIPTORS
#endif
/* 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?
+2 -1
View File
@@ -243,12 +243,13 @@ ssize_t psock_bluetooth_sendto(FAR struct socket *psock, FAR const void *buf,
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
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.
+6 -6
View File
@@ -184,15 +184,15 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
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_conn)
if (!psock || psock->s_crefs <= 0)
{
return -EBADF;
}
conn = (FAR struct can_conn_s *)psock->s_conn;
/* Get the device driver that will service this transfer */
dev = conn->dev;
@@ -316,15 +316,15 @@ ssize_t psock_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_conn)
if (!psock || psock->s_crefs <= 0)
{
return -EBADF;
}
conn = (FAR struct can_conn_s *)psock->s_conn;
/* Get the device driver that will service this transfer */
dev = conn->dev;
+2 -1
View File
@@ -431,12 +431,13 @@ ssize_t psock_ieee802154_sendto(FAR struct socket *psock,
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
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.
+1
View File
@@ -874,6 +874,7 @@ 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;
+1
View File
@@ -233,6 +233,7 @@ 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;
+39 -1
View File
@@ -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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
@@ -1772,6 +1772,44 @@ 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
*
+1 -1
View File
@@ -177,7 +177,7 @@ ssize_t psock_pkt_send(FAR struct socket *psock, FAR const void *buf,
/* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || !psock->s_conn)
if (!psock || psock->s_crefs <= 0)
{
return -EBADF;
}
+1
View File
@@ -732,6 +732,7 @@ 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);
+3 -2
View File
@@ -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_conn != NULL);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_STREAM);
/* Make sure that this is a valid socket */
if (psock == NULL || psock->s_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
@@ -738,6 +738,7 @@ 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 */
+5 -4
View File
@@ -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_conn != NULL && to != NULL);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && 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_conn == NULL || psock->s_type != SOCK_DGRAM)
if (psock->s_crefs <= 0 || 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_conn != NULL);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
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_conn == NULL)
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
@@ -359,6 +359,7 @@ 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 */
+7 -1
View File
@@ -37,7 +37,7 @@
SOCK_CSRCS += bind.c connect.c getsockname.c getpeername.c
SOCK_CSRCS += recv.c recvfrom.c send.c sendto.c
SOCK_CSRCS += socket.c net_close.c
SOCK_CSRCS += socket.c net_sockets.c net_close.c net_dup.c
SOCK_CSRCS += net_dup2.c net_sockif.c net_poll.c net_vfcntl.c
SOCK_CSRCS += net_fstat.c
@@ -58,6 +58,12 @@ 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)
+10 -4
View File
@@ -42,7 +42,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
@@ -250,7 +249,7 @@ 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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
/* 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
@@ -273,13 +272,20 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
* cannot fail later)
*/
newfd = sockfd_allocate(&newsock);
newfd = sockfd_allocate(0);
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)
{
@@ -291,7 +297,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
return newfd;
errout_with_socket:
close(newfd);
sockfd_release(newfd);
errout:
leave_cancellation_point();
+1 -1
View File
@@ -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_conn == NULL)
if (!psock || psock->s_crefs <= 0)
{
return -ENOTSOCK;
}
+1 -1
View File
@@ -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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
+1 -1
View File
@@ -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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
+1 -1
View File
@@ -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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
+1 -1
View File
@@ -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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
+1 -1
View File
@@ -148,7 +148,7 @@ int listen(int sockfd, int backlog)
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
/* It is not a valid socket description. Distinguish between the
* cases where sockfd is a just invalid and when it is a valid file
+70
View File
@@ -0,0 +1,70 @@
/****************************************************************************
* 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 <nuttx/config.h>
#include <sys/socket.h>
#include <sched.h>
#include <errno.h>
#include <debug.h>
#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;
}
+28 -5
View File
@@ -65,7 +65,7 @@ int psock_close(FAR struct socket *psock)
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
@@ -78,7 +78,7 @@ int psock_close(FAR struct socket *psock)
* waiting in accept.
*/
if (psock->s_conn != NULL)
if (psock->s_crefs <= 1 && 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,11 +109,34 @@ int psock_close(FAR struct socket *psock)
}
}
/* The socket will not persist... reset it */
memset(psock, 0, sizeof(*psock));
/* Then release our reference on the socket structure containing the
* connection.
*/
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 */
+149
View File
@@ -0,0 +1,149 @@
/****************************************************************************
* net/socket/net_dup.c
*
* Copyright (C) 2009, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <sys/socket.h>
#include <sched.h>
#include <errno.h>
#include <debug.h>
#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);
}
+64 -3
View File
@@ -59,7 +59,7 @@
* Name: psock_dup2
*
* Description:
* Performs the low level, common portion of dup
* Performs the low level, common portion of net_dup() and net_dup2()
*
* Input Parameters:
* psock1 - The existing socket that is being cloned.
@@ -98,6 +98,10 @@ 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.
*/
@@ -136,9 +140,11 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2)
inet_close(psock2);
/* The socket will not persist... reset it */
/* Then release our reference on the socket structure containing
* the connection.
*/
memset(psock2, 0, sizeof(*psock2));
psock_release(psock2);
}
}
#endif
@@ -146,3 +152,58 @@ 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;
}
+8 -4
View File
@@ -56,13 +56,13 @@
****************************************************************************/
/****************************************************************************
* Name: psock_fstat
* Name: net_fstat
*
* Description:
* Performs fstat operations on socket
*
* Input Parameters:
* psock - The pointer of the socket to operate on
* sockfd - Socket descriptor of the socket to operate on
* buf - Caller-provided location in which to return the fstat data
*
* Returned Value:
@@ -71,11 +71,15 @@
*
****************************************************************************/
int psock_fstat(FAR struct socket *psock, FAR struct stat *buf)
int net_fstat(int sockfd, FAR struct stat *buf)
{
FAR struct socket *psock;
int ret = OK;
if (psock == NULL || psock->s_conn == NULL)
/* Get the underlying socket structure */
psock = sockfd_socket(sockfd);
if (psock == NULL)
{
/* sockfd does not refer to a valid, open socket */
+39
View File
@@ -77,3 +77,42 @@ 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);
}
+6 -5
View File
@@ -60,10 +60,10 @@
****************************************************************************/
/****************************************************************************
* Name: psock_sendfile
* Name: net_sendfile
*
* Description:
* The psock_sendfile() call may be used only when the socket is in a
* The net_sendfile() call may be used only when the socket is in a
* connected state (so that the intended recipient is known).
*
* Input Parameters:
@@ -118,16 +118,17 @@
*
****************************************************************************/
ssize_t psock_sendfile(FAR struct socket *psock, FAR struct file *infile,
FAR off_t *offset, size_t count)
ssize_t net_sendfile(int outfd, 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_conn == NULL)
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
_SO_SETERRNO(psock, EBADF);
+264
View File
@@ -0,0 +1,264 @@
/****************************************************************************
* 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 <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <sched.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h>
#include <nuttx/kmalloc.h>
#include <nuttx/semaphore.h>
#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;
}
+83 -1
View File
@@ -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_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
@@ -93,6 +93,66 @@ 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 <fcntl.h> 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 <fcntl.h>, 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
* <fcntl.h>, for the file description associated with fd. The file
@@ -266,3 +326,25 @@ 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);
}
+1 -1
View File
@@ -103,7 +103,7 @@ ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_conn == NULL)
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}

Some files were not shown because too many files have changed in this diff Show More