mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
net: unify socket info file descriptor
MIRTOS-255 Change-Id: Iee680c8ac07fe87fb6e7900b4f792e0f1ff5036d Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+73
-20
@@ -25,6 +25,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sched.h>
|
||||
@@ -32,6 +33,7 @@
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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 <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.
|
||||
* 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;
|
||||
}
|
||||
@@ -39,17 +39,11 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
# include <nuttx/net/net.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
+10
-38
@@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
+1
-75
@@ -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;
|
||||
}
|
||||
|
||||
+17
-27
@@ -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;
|
||||
}
|
||||
|
||||
+2
-30
@@ -33,7 +33,6 @@
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/lib/lib.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
+16
-24
@@ -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);
|
||||
|
||||
+1
-12
@@ -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.
|
||||
*/
|
||||
|
||||
|
||||
+7
-33
@@ -46,12 +46,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
# include <nuttx/net/net.h>
|
||||
#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()
|
||||
|
||||
+15
-56
@@ -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
|
||||
*
|
||||
|
||||
+14
-35
@@ -41,14 +41,12 @@
|
||||
#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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -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
|
||||
|
||||
+10
-34
@@ -47,12 +47,7 @@
|
||||
#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"
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
+1
-1
@@ -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) */
|
||||
|
||||
+4
-21
@@ -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
|
||||
*
|
||||
|
||||
+20
-199
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+12
-14
@@ -42,11 +42,14 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#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();
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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 <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;
|
||||
}
|
||||
+6
-28
@@ -27,6 +27,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
@@ -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 */
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
}
|
||||
+3
-64
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user