fs/vfs: Add nx_dup and nx_dup2 function

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao
2020-05-04 03:07:01 +08:00
committed by patacongo
parent 1da8cd6b89
commit 390f9a5fb7
8 changed files with 196 additions and 194 deletions
+58 -39
View File
@@ -50,6 +50,59 @@
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Name: nx_dup
*
* Description:
* nx_dup() is similar to the standard 'dup' interface except that is
* not a cancellation point and it does not modify the errno variable.
*
* nx_dup() 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_dup(int fd)
{
/* Check the range of the descriptor to see if we got a file or a socket
* descriptor.
*/
if (fd < CONFIG_NFILE_DESCRIPTORS)
{
/* Its a valid file descriptor.. dup the file descriptor using any
* other file descriptor.
*/
return fs_dupfd(fd, 0);
}
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. */
return net_dup(fd, CONFIG_NFILE_DESCRIPTORS);
}
else
#endif
{
/* No.. then it is a bad descriptor number */
return -EBADF;
}
}
}
/**************************************************************************** /****************************************************************************
* Name: dup * Name: dup
* *
@@ -60,47 +113,13 @@
int dup(int fd) int dup(int fd)
{ {
int ret = OK; int ret;
/* Check the range of the descriptor to see if we got a file or a socket ret = nx_dup(fd);
* descriptor. if (ret < 0)
*/
if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
{ {
/* Its a valid file descriptor.. dup the file descriptor using any set_errno(-ret);
* other file descriptor. fd_dupfd() sets the errno value in the ret = ERROR;
* event of any failures.
*/
ret = fs_dupfd(fd, 0);
}
else
{
/* Not a valid file descriptor. Did we get a valid socket descriptor? */
#ifdef CONFIG_NET
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))
{
/* Yes.. dup the socket descriptor. The errno value is not set. */
ret = net_dup(fd, CONFIG_NFILE_DESCRIPTORS);
}
else
#endif
{
/* No.. then it is a bad descriptor number */
ret = -EBADF;
}
/* Set the errno value on failures */
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
}
} }
return ret; return ret;
+58 -46
View File
@@ -46,17 +46,62 @@
#include "inode/inode.h" #include "inode/inode.h"
/* This logic in this applies only when both socket and file descriptors are
* in that case, this function discriminates which type of dup2 is being
* performed.
*/
#ifdef CONFIG_NET
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* 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 fs_dupfd2(fd1, fd2);
}
}
/**************************************************************************** /****************************************************************************
* Name: dup2 * Name: dup2
* *
@@ -68,47 +113,14 @@
int dup2(int fd1, int fd2) int dup2(int fd1, int fd2)
{ {
/* Check the range of the descriptor to see if we got a file or a socket int ret;
* descriptor.
*/
if ((unsigned int)fd1 >= CONFIG_NFILE_DESCRIPTORS) ret = nx_dup2(fd1, fd2);
if (ret < 0)
{ {
int ret; set_errno(-ret);
ret = ERROR;
/* Not a valid file descriptor. Did we get a valid socket descriptor? */
if ((unsigned int)fd1 < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))
{
/* Yes.. dup the socket descriptor. The errno value is not set. */
ret = net_dup2(fd1, fd2);
}
else
{
/* No.. then it is a bad descriptor number */
ret = -EBADF;
}
/* Set the errno value on failures */
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
}
return ret;
} }
else
{
/* Its a valid file descriptor.. dup the file descriptor. fd_dupfd()
* sets the errno value in the event of any failures.
*/
return fs_dupfd2(fd1, fd2); return ret;
}
} }
#endif /* CONFIG_NET */
+7 -22
View File
@@ -47,8 +47,7 @@
* *
* Description: * Description:
* Equivalent to the non-standard fs_dupfd() function except that it * Equivalent to the non-standard fs_dupfd() function except that it
* accepts a struct file instance instead of a file descriptor and does * accepts a struct file instance instead of a file descriptor.
* not set the errno variable.
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@@ -89,19 +88,15 @@ int file_dup(FAR struct file *filep, int minfd)
} }
/**************************************************************************** /****************************************************************************
* Name: fs_dupfd OR dup * Name: fs_dupfd
* *
* Description: * Description:
* Clone a file descriptor 'fd' to an arbitrary descriptor number (any * Clone a file descriptor 'fd' to an arbitrary descriptor number (any
* value greater than or equal to 'minfd'). If socket descriptors are * value greater than or equal to 'minfd').
* implemented, then this is called by dup() for the case of file
* descriptors. If socket descriptors are not implemented, then this
* function IS dup().
* *
* Returned Value: * Returned Value:
* fs_dupfd is sometimes an OS internal function and sometimes is a direct * Zero (OK) is returned on success; a negated errno value is returned on
* substitute for dup(). So it must return an errno value as though it * any failure.
* were dup().
* *
****************************************************************************/ ****************************************************************************/
@@ -115,22 +110,12 @@ int fs_dupfd(int fd, int minfd)
ret = fs_getfilep(fd, &filep); ret = fs_getfilep(fd, &filep);
if (ret < 0) if (ret < 0)
{ {
goto errout; return ret;
} }
DEBUGASSERT(filep != NULL); DEBUGASSERT(filep != NULL);
/* Let file_dup() do the real work */ /* Let file_dup() do the real work */
ret = file_dup(filep, minfd); return file_dup(filep, minfd);
if (ret < 0)
{
goto errout;
}
return ret;
errout:
set_errno(-ret);
return ERROR;
} }
+7 -26
View File
@@ -61,26 +61,18 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: fs_dupfd2 OR dup2 * Name: fs_dupfd2
* *
* Description: * Description:
* Clone a file descriptor to a specific descriptor number. If socket * Clone a file descriptor to a specific descriptor number.
* descriptors are implemented, then this is called by dup2() for the
* case of file descriptors. If socket descriptors are not implemented,
* then this function IS dup2().
* *
* Returned Value: * Returned Value:
* fs_dupfd is sometimes an OS internal function and sometimes is a direct * Zero (OK) is returned on success; a negated errno value is return on
* substitute for dup2(). So it must return an errno value as though it * any failure.
* were dup2().
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET
int fs_dupfd2(int fd1, int fd2) int fs_dupfd2(int fd1, int fd2)
#else
int dup2(int fd1, int fd2)
#endif
{ {
FAR struct file *filep1; FAR struct file *filep1;
FAR struct file *filep2 = NULL; FAR struct file *filep2 = NULL;
@@ -96,7 +88,7 @@ int dup2(int fd1, int fd2)
if (ret < 0) if (ret < 0)
{ {
goto errout; return ret;
} }
DEBUGASSERT(filep1 != NULL && filep2 != NULL); DEBUGASSERT(filep1 != NULL && filep2 != NULL);
@@ -105,8 +97,7 @@ int dup2(int fd1, int fd2)
if (!DUP_ISOPEN(filep1)) if (!DUP_ISOPEN(filep1))
{ {
ret = -EBADF; return -EBADF;
goto errout;
} }
/* Handle a special case */ /* Handle a special case */
@@ -118,15 +109,5 @@ int dup2(int fd1, int fd2)
/* Perform the dup2 operation */ /* Perform the dup2 operation */
ret = file_dup2(filep1, filep2); return file_dup2(filep1, filep2);
if (ret < 0)
{
goto errout;
}
return OK;
errout:
set_errno(-ret);
return ERROR;
} }
+46 -24
View File
@@ -721,8 +721,7 @@ void files_releaselist(FAR struct filelist *list);
* *
* Description: * Description:
* Equivalent to the non-standard fs_dupfd() function except that it * Equivalent to the non-standard fs_dupfd() function except that it
* accepts a struct file instance instead of a file descriptor and does * accepts a struct file instance instead of a file descriptor.
* not set the errno variable.
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@@ -733,27 +732,41 @@ void files_releaselist(FAR struct filelist *list);
int file_dup(FAR struct file *filep, int minfd); int file_dup(FAR struct file *filep, int minfd);
/**************************************************************************** /****************************************************************************
* Name: fs_dupfd OR dup * Name: fs_dupfd
* *
* Description: * Description:
* Clone a file descriptor 'fd' to an arbitrary descriptor number (any * Clone a file descriptor 'fd' to an arbitrary descriptor number (any
* value greater than or equal to 'minfd'). If socket descriptors are * value greater than or equal to 'minfd').
* implemented, then this is called by dup() for the case of file
* descriptors. If socket descriptors are not implemented, then this
* function IS dup().
* *
* This alternative naming is used when dup could operate on both file and * This alternative naming is used when dup could operate on both file and
* socket descriptors to avoid drawing unused socket support into the link. * socket descriptors to avoid drawing unused socket support into the link.
* *
* Returned Value: * Returned Value:
* fs_dupfd is sometimes an OS internal function and sometimes is a direct * Zero (OK) is returned on success; a negated errno value is returned on
* substitute for dup(). So it must return an errno value as though it * any failure.
* were dup().
* *
****************************************************************************/ ****************************************************************************/
int fs_dupfd(int fd, int minfd); int fs_dupfd(int fd, int minfd);
/****************************************************************************
* Name: nx_dup
*
* Description:
* nx_dup() is similar to the standard 'dup' interface except that is
* not a cancellation point and it does not modify the errno variable.
*
* nx_dup() 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_dup(int fd);
/**************************************************************************** /****************************************************************************
* Name: file_dup2 * Name: file_dup2
* *
@@ -762,8 +775,7 @@ int fs_dupfd(int fd, int minfd);
* dup2. * dup2.
* *
* Equivalent to the non-standard fs_dupfd2() function except that it * Equivalent to the non-standard fs_dupfd2() function except that it
* accepts struct file instances instead of file descriptors and it does * accepts struct file instances instead of file descriptors.
* not set the errno variable.
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is return on * Zero (OK) is returned on success; a negated errno value is return on
@@ -774,29 +786,39 @@ int fs_dupfd(int fd, int minfd);
int file_dup2(FAR struct file *filep1, FAR struct file *filep2); int file_dup2(FAR struct file *filep1, FAR struct file *filep2);
/**************************************************************************** /****************************************************************************
* Name: fs_dupfd2 OR dup2 * Name: fs_dupfd2
* *
* Description: * Description:
* Clone a file descriptor to a specific descriptor number. If socket * Clone a file descriptor to a specific descriptor number.
* descriptors are implemented, then this is called by dup2() for the
* case of file descriptors. If socket descriptors are not implemented,
* then this function IS dup2().
* *
* This alternative naming is used when dup2 could operate on both file and * This alternative naming is used when dup2 could operate on both file and
* socket descriptors to avoid drawing unused socket support into the link. * socket descriptors to avoid drawing unused socket support into the link.
* *
* Returned Value: * Returned Value:
* fs_dupfd2 is sometimes an OS internal function and sometimes is a direct * Zero (OK) is returned on success; a negated errno value is return on
* substitute for dup2(). So it must return an errno value as though it * any failure.
* were dup2().
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET
int fs_dupfd2(int fd1, int fd2); int fs_dupfd2(int fd1, int fd2);
#else
# define fs_dupfd2(fd1, fd2) dup2(fd1, fd2) /****************************************************************************
#endif * 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);
/**************************************************************************** /****************************************************************************
* Name: file_open * Name: file_open
+9 -18
View File
@@ -1341,14 +1341,11 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup);
* Name: psock_dup * Name: psock_dup
* *
* Description: * Description:
* Clone a socket descriptor to an arbitrary descriptor number. If file * Clone a socket descriptor to an arbitrary descriptor number.
* descriptors are implemented, then this is called by dup() for the case
* of socket file descriptors. If file descriptors are not implemented,
* then this function IS dup().
* *
* Returned Value: * Returned Value:
* On success, returns the number of characters sent. On any error, * On success, returns the number of new socket. On any error,
* a negated errno value is returned:. * a negated errno value is returned.
* *
****************************************************************************/ ****************************************************************************/
@@ -1358,14 +1355,11 @@ int psock_dup(FAR struct socket *psock, int minsd);
* Name: net_dup * Name: net_dup
* *
* Description: * Description:
* Clone a socket descriptor to an arbitrary descriptor number. If file * Clone a socket descriptor to an arbitrary descriptor number.
* descriptors are implemented, then this is called by dup() for the case
* of socket file descriptors. If file descriptors are not implemented,
* then this function IS dup().
* *
* Returned Value: * Returned Value:
* On success, returns the number of characters sent. On any error, * On success, returns the number of new socket. On any error,
* a negated errno value is returned:. * a negated errno value is returned.
* *
****************************************************************************/ ****************************************************************************/
@@ -1385,14 +1379,11 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2);
* Name: net_dup2 * Name: net_dup2
* *
* Description: * Description:
* Clone a socket descriptor to an arbitrary descriptor number. If file * Clone a socket descriptor to an arbitrary descriptor number.
* descriptors are implemented, then this is called by dup2() for the case
* of socket file descriptors. If file descriptors are not implemented,
* then this function IS dup2().
* *
* Returned Value: * Returned Value:
* On success, returns the number of characters sent. On any error, * Zero (OK) is returned on success; a negated errno value is returned on
* a negated errno value is returned:. * any failure.
* *
****************************************************************************/ ****************************************************************************/
+6 -12
View File
@@ -54,14 +54,11 @@
* Name: psock_dup * Name: psock_dup
* *
* Description: * Description:
* Clone a socket descriptor to an arbitrary descriptor number. If file * Clone a socket descriptor to an arbitrary descriptor number.
* descriptors are implemented, then this is called by dup() for the case
* of socket file descriptors. If file descriptors are not implemented,
* then this function IS dup().
* *
* Returned Value: * Returned Value:
* On success, returns the number of characters sent. On any error, * On success, returns the number of new socket. On any error,
* a negated errno value is returned:. * a negated errno value is returned.
* *
****************************************************************************/ ****************************************************************************/
@@ -138,14 +135,11 @@ errout:
* Name: net_dup * Name: net_dup
* *
* Description: * Description:
* Clone a socket descriptor to an arbitrary descriptor number. If file * Clone a socket descriptor to an arbitrary descriptor number.
* descriptors are implemented, then this is called by dup() for the case
* of socket file descriptors. If file descriptors are not implemented,
* then this function IS dup().
* *
* Returned Value: * Returned Value:
* On success, returns the number of characters sent. On any error, * On success, returns the number of new socket. On any error,
* a negated errno value is returned:. * a negated errno value is returned.
* *
****************************************************************************/ ****************************************************************************/
+5 -7
View File
@@ -106,7 +106,8 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2)
* for this address family type. * for this address family type.
*/ */
DEBUGASSERT(psock2->s_sockif != NULL && psock2->s_sockif->si_addref != NULL); DEBUGASSERT(psock2->s_sockif != NULL &&
psock2->s_sockif->si_addref != NULL);
psock2->s_sockif->si_addref(psock2); psock2->s_sockif->si_addref(psock2);
#ifdef NET_TCP_HAVE_STACK #ifdef NET_TCP_HAVE_STACK
@@ -156,14 +157,11 @@ int psock_dup2(FAR struct socket *psock1, FAR struct socket *psock2)
* Name: net_dup2 * Name: net_dup2
* *
* Description: * Description:
* Clone a socket descriptor to an arbitrary descriptor number. If file * Clone a socket descriptor to an arbitrary descriptor number.
* descriptors are implemented, then this is called by dup2() for the case
* of socket file descriptors. If file descriptors are not implemented,
* then this function IS dup2().
* *
* Returned Value: * Returned Value:
* On success, returns the number of characters sent. On any error, * Zero (OK) is returned on success; a negated errno value is returned on
* a negated errno value is returned:. * any failure.
* *
****************************************************************************/ ****************************************************************************/