fs/vfs: Add nx_ioctl/nx_fcntl function

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2020-05-03 17:38:48 +08:00 committed by patacongo
parent 65308eabb4
commit 4b5360362e
3 changed files with 212 additions and 95 deletions

View File

@ -94,9 +94,9 @@ int file_vfcntl(FAR struct file *filep, int cmd, va_list ap)
* or equal to the third argument, arg, taken as an integer of type * or equal to the third argument, arg, taken as an integer of type
* int. The new file descriptor shall refer to the same open file * int. The new file descriptor shall refer to the same open file
* description as the original file descriptor, and shall share any * description as the original file descriptor, and shall share any
* locks. The FD_CLOEXEC flag associated with the new file descriptor * locks. The FD_CLOEXEC flag associated with the new file
* shall be cleared to keep the file open across calls to one of the * descriptor shall be cleared to keep the file open across calls to
* exec functions. * one of the exec functions.
*/ */
{ {
@ -107,10 +107,10 @@ int file_vfcntl(FAR struct file *filep, int cmd, va_list ap)
break; break;
case F_GETFD: case F_GETFD:
/* Get the file descriptor flags defined in <fcntl.h> that are associated /* Get the file descriptor flags defined in <fcntl.h> that are
* with the file descriptor fd. File descriptor flags are associated * associated with the file descriptor fd. File descriptor flags are
* with a single file descriptor and do not affect other file descriptors * associated with a single file descriptor and do not affect other
* that refer to the same file. * file descriptors that refer to the same file.
*/ */
{ {
@ -281,41 +281,33 @@ int file_fcntl(FAR struct file *filep, int cmd, ...)
} }
/**************************************************************************** /****************************************************************************
* Name: fcntl * Name: nx_fcntl and nx_vfcntl
* *
* Description: * Description:
* fcntl() will perform the operation specified by 'cmd' on an open file. * nx_fcntl() is similar to the standard 'fcntl' interface except that is
* not a cancellation point and it does not modify the errno variable.
* *
* Input Parameters: * nx_vfcntl() is identical except that it accepts a va_list as an argument
* fd - File descriptor of the open file * versus taking a variable length list of arguments.
* cmd - Identifies the operation to be performed. Command specific *
* arguments may follow. * nx_fcntl() and nx_vfcntl are internal NuttX interface and should not be
* called from applications.
* *
* Returned Value: * Returned Value:
* The returned value depends on the nature of the command but for all * Returns a non-negative number on success; A negated errno value is
* commands the return value of -1 (ERROR) indicates that an error has * returned on any failure (see comments fcntl() for a list of appropriate
* occurred and, in this case, the errno variable will be set * errno values).
* appropriately
* *
****************************************************************************/ ****************************************************************************/
int fcntl(int fd, int cmd, ...) int nx_vfcntl(int fd, int cmd, va_list ap)
{ {
FAR struct file *filep; FAR struct file *filep;
va_list ap;
int ret; int ret;
/* fcntl() is a cancellation point */
enter_cancellation_point();
/* Setup to access the variable argument list */
va_start(ap, cmd);
/* Did we get a valid file descriptor? */ /* Did we get a valid file descriptor? */
if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS) if (fd < CONFIG_NFILE_DESCRIPTORS)
{ {
/* Get the file structure corresponding to the file descriptor. */ /* Get the file structure corresponding to the file descriptor. */
@ -336,7 +328,7 @@ int fcntl(int fd, int cmd, ...)
/* No... check for operations on a socket descriptor */ /* No... check for operations on a socket descriptor */
#ifdef CONFIG_NET #ifdef CONFIG_NET
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))
{ {
/* Yes.. defer socket descriptor operations to net_vfcntl(). The /* Yes.. defer socket descriptor operations to net_vfcntl(). The
* errno is not set on failures. * errno is not set on failures.
@ -353,6 +345,66 @@ int fcntl(int fd, int cmd, ...)
} }
} }
return ret;
}
int nx_fcntl(int fd, int cmd, ...)
{
va_list ap;
int ret;
/* Setup to access the variable argument list */
va_start(ap, cmd);
/* Let nx_vfcntl() do the real work. The errno is not set on
* failures.
*/
ret = nx_vfcntl(fd, cmd, ap);
va_end(ap);
return ret;
}
/****************************************************************************
* Name: fcntl
*
* Description:
* fcntl() will perform the operation specified by 'cmd' on an open file.
*
* Input Parameters:
* fd - File descriptor of the open file
* cmd - Identifies the operation to be performed. Command specific
* arguments may follow.
*
* Returned Value:
* The returned value depends on the nature of the command but for all
* commands the return value of -1 (ERROR) indicates that an error has
* occurred and, in this case, the errno variable will be set
* appropriately
*
****************************************************************************/
int fcntl(int fd, int cmd, ...)
{
va_list ap;
int ret;
/* fcntl() is a cancellation point */
enter_cancellation_point();
/* Setup to access the variable argument list */
va_start(ap, cmd);
/* Let nx_vfcntl() do the real work. The errno is not set on
* failures.
*/
ret = nx_vfcntl(fd, cmd, ap);
va_end(ap); va_end(ap);
if (ret < 0) if (ret < 0)

View File

@ -102,6 +102,92 @@ int file_ioctl(FAR struct file *filep, int req, unsigned long arg)
return (int)inode->u.i_ops->ioctl(filep, req, arg); return (int)inode->u.i_ops->ioctl(filep, req, arg);
} }
/****************************************************************************
* Name: nx_ioctl
*
* Description:
* nx_ioctl() is similar to the standard 'ioctl' interface except that is
* not a cancellation point and it does not modify the errno variable.
*
* nx_ioctl() is an internal NuttX interface and should not be called from
* applications.
*
* Returned Value:
* Returns a non-negative number on success; A negated errno value is
* returned on any failure (see comments ioctl() for a list of appropriate
* errno values).
*
****************************************************************************/
int nx_ioctl(int fd, int req, unsigned long arg)
{
FAR struct file *filep;
int ret;
/* Did we get a valid file descriptor? */
if (fd >= CONFIG_NFILE_DESCRIPTORS)
{
/* Perform the socket ioctl */
#ifdef CONFIG_NET
if (fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))
{
ret = netdev_ioctl(fd, req, arg);
}
else
#endif
{
return -EBADF;
}
}
else
{
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
return ret;
}
DEBUGASSERT(filep != NULL);
/* Perform the file ioctl. */
ret = file_ioctl(filep, req, arg);
}
/* Check for File system IOCTL commands that can be implemented via
* fcntl()
*/
if (ret == -ENOTTY)
{
switch (req)
{
case FIONBIO:
{
DEBUGASSERT(arg != 0);
if (*(FAR int *)((uintptr_t)arg))
{
ret = nx_fcntl(fd, F_SETFL,
nx_fcntl(fd, F_GETFL) | O_NONBLOCK);
}
else
{
ret = nx_fcntl(fd, F_SETFL,
nx_fcntl(fd, F_GETFL) & ~O_NONBLOCK);
}
}
break;
}
}
return ret;
}
/**************************************************************************** /****************************************************************************
* Name: ioctl/fs_ioctl * Name: ioctl/fs_ioctl
* *
@ -137,74 +223,9 @@ int fs_ioctl(int fd, int req, unsigned long arg)
int ioctl(int fd, int req, unsigned long arg) int ioctl(int fd, int req, unsigned long arg)
#endif #endif
{ {
FAR struct file *filep;
int ret; int ret;
/* Did we get a valid file descriptor? */ ret = nx_ioctl(fd, req, arg);
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
{
/* Perform the socket ioctl */
#ifdef CONFIG_NET
if ((unsigned int)fd <
(CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))
{
ret = netdev_ioctl(fd, req, arg);
}
else
#endif
{
ret = -EBADF;
goto errout;
}
}
else
{
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
goto errout;
}
DEBUGASSERT(filep != NULL);
/* Perform the file ioctl. */
ret = file_ioctl(filep, req, arg);
}
/* Check for File system IOCTL commands that can be implemented via
* fcntl()
*/
if (ret == -ENOTTY)
{
switch (req)
{
case FIONBIO:
{
DEBUGASSERT(arg != 0);
if (*(FAR int *)((uintptr_t)arg))
{
return fcntl(fd, F_SETFL,
fcntl(fd, F_GETFL) | O_NONBLOCK);
}
else
{
return fcntl(fd, F_SETFL,
fcntl(fd, F_GETFL) & ~O_NONBLOCK);
}
}
break;
}
}
errout:
if (ret < 0) if (ret < 0)
{ {
set_errno(-ret); set_errno(-ret);

View File

@ -81,6 +81,7 @@
# define _NX_READ(f,b,s) nx_read(f,b,s) # define _NX_READ(f,b,s) nx_read(f,b,s)
# define _NX_WRITE(f,b,s) nx_write(f,b,s) # define _NX_WRITE(f,b,s) nx_write(f,b,s)
# define _NX_SEEK(f,o,w) nx_seek(f,o,w) # define _NX_SEEK(f,o,w) nx_seek(f,o,w)
# define _NX_IOCTL(f,r,a) nx_ioctl(f,r,a)
# define _NX_STAT(p,s) nx_stat(p,s) # define _NX_STAT(p,s) nx_stat(p,s)
# define _NX_GETERRNO(r) (-(r)) # define _NX_GETERRNO(r) (-(r))
# define _NX_SETERRNO(r) set_errno(-(r)) # define _NX_SETERRNO(r) set_errno(-(r))
@ -95,6 +96,7 @@
# define _NX_READ(f,b,s) read(f,b,s) # define _NX_READ(f,b,s) read(f,b,s)
# define _NX_WRITE(f,b,s) write(f,b,s) # define _NX_WRITE(f,b,s) write(f,b,s)
# define _NX_SEEK(f,o,w) lseek(f,o,w) # define _NX_SEEK(f,o,w) lseek(f,o,w)
# define _NX_IOCTL(f,r,a) ioctl(f,r,a)
# define _NX_STAT(p,s) stat(p,s) # define _NX_STAT(p,s) stat(p,s)
# define _NX_GETERRNO(r) errno # define _NX_GETERRNO(r) errno
# define _NX_SETERRNO(r) # define _NX_SETERRNO(r)
@ -1248,6 +1250,25 @@ int file_truncate(FAR struct file *filep, off_t length);
int file_ioctl(FAR struct file *filep, int req, unsigned long arg); int file_ioctl(FAR struct file *filep, int req, unsigned long arg);
/****************************************************************************
* Name: nx_ioctl
*
* Description:
* nx_ioctl() is similar to the standard 'ioctl' interface except that is
* not a cancellation point and it does not modify the errno variable.
*
* nx_ioctl() is an internal NuttX interface and should not be called from
* applications.
*
* Returned Value:
* Returns a non-negative number on success; A negated errno value is
* returned on any failure (see comments ioctl() for a list of appropriate
* errno values).
*
****************************************************************************/
int nx_ioctl(int fd, int req, unsigned long arg);
/**************************************************************************** /****************************************************************************
* Name: file_vfcntl * Name: file_vfcntl
* *
@ -1290,6 +1311,29 @@ int file_vfcntl(FAR struct file *filep, int cmd, va_list ap);
int file_fcntl(FAR struct file *filep, int cmd, ...); int file_fcntl(FAR struct file *filep, int cmd, ...);
/****************************************************************************
* Name: nx_fcntl and nx_vfcntl
*
* Description:
* nx_fcntl() is similar to the standard 'fcntl' interface except that is
* not a cancellation point and it does not modify the errno variable.
*
* nx_vfcntl() is identical except that it accepts a va_list as an argument
* versus taking a variable length list of arguments.
*
* nx_fcntl() and nx_vfcntl are internal NuttX interface and should not be
* called from applications.
*
* Returned Value:
* Returns a non-negative number on success; A negated errno value is
* returned on any failure (see comments fcntl() for a list of appropriate
* errno values).
*
****************************************************************************/
int nx_vfcntl(int fd, int cmd, va_list ap);
int nx_fcntl(int fd, int cmd, ...);
/**************************************************************************** /****************************************************************************
* Name: file_poll * Name: file_poll
* *