mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +08:00
stdio: Merge fs_fdopen into fdopen to simplify the code logi
since fs_fdopen could avoid call the kernel specific function now Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
@@ -60,12 +60,6 @@ if(CONFIG_PSEUDOFS_FILE)
|
|||||||
list(APPEND SRCS fs_pseudofile.c)
|
list(APPEND SRCS fs_pseudofile.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Stream support
|
|
||||||
|
|
||||||
if(CONFIG_FILE_STREAM)
|
|
||||||
list(APPEND SRCS fs_fdopen.c)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Support for eventfd
|
# Support for eventfd
|
||||||
|
|
||||||
if(CONFIG_EVENT_FD)
|
if(CONFIG_EVENT_FD)
|
||||||
|
|||||||
@@ -39,12 +39,6 @@ ifeq ($(CONFIG_PSEUDOFS_FILE),y)
|
|||||||
CSRCS += fs_pseudofile.c
|
CSRCS += fs_pseudofile.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Stream support
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_FILE_STREAM),y)
|
|
||||||
CSRCS += fs_fdopen.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Support for eventfd
|
# Support for eventfd
|
||||||
|
|
||||||
ifeq ($(CONFIG_EVENT_FD),y)
|
ifeq ($(CONFIG_EVENT_FD),y)
|
||||||
|
|||||||
@@ -1,219 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* fs/vfs/fs_fdopen.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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
|
||||||
#include <nuttx/semaphore.h>
|
|
||||||
#include <nuttx/fs/fs.h>
|
|
||||||
#include <nuttx/lib/lib.h>
|
|
||||||
#include <nuttx/tls.h>
|
|
||||||
|
|
||||||
#include "inode/inode.h"
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: fs_checkfd
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Check if the file descriptor is valid for the provided TCB and if it
|
|
||||||
* supports the requested access.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline int fs_checkfd(FAR struct tcb_s *tcb, int fd, int oflags)
|
|
||||||
{
|
|
||||||
FAR struct file *filep;
|
|
||||||
FAR struct inode *inode;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(tcb && tcb->group);
|
|
||||||
|
|
||||||
/* Get the file structure corresponding to the file descriptor. */
|
|
||||||
|
|
||||||
ret = fs_getfilep(fd, &filep);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the inode associated with the file descriptor. This should
|
|
||||||
* normally be the case if fd >= 0. But not in the case where the
|
|
||||||
* called attempts to explicitly stdin with fdopen(0) but stdin has
|
|
||||||
* been closed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
inode = filep->f_inode;
|
|
||||||
if (!inode)
|
|
||||||
{
|
|
||||||
/* No inode -- descriptor does not correspond to an open file */
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure that the inode supports the requested access. In
|
|
||||||
* the case of fdopen, we are not actually creating the file -- in
|
|
||||||
* particular w and w+ do not truncate the file and any files have
|
|
||||||
* already been created.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (inode_checkflags(inode, oflags) != OK)
|
|
||||||
{
|
|
||||||
/* Cannot support the requested access */
|
|
||||||
|
|
||||||
return -EACCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Looks good to me */
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: fs_fdopen
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function does the core operations for fopen and fdopen.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
|
|
||||||
FAR struct file_struct **filep)
|
|
||||||
{
|
|
||||||
FAR struct streamlist *slist;
|
|
||||||
FAR FILE *stream;
|
|
||||||
int ret = OK;
|
|
||||||
|
|
||||||
/* A NULL TCB pointer means to use this threads TCB. This is a little
|
|
||||||
* hack the let's this function be called from user-space (via a syscall)
|
|
||||||
* without having access to the TCB.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!tcb)
|
|
||||||
{
|
|
||||||
tcb = nxsched_self();
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGASSERT(tcb && tcb->group);
|
|
||||||
|
|
||||||
/* Do we have a good descriptor of some sort? */
|
|
||||||
|
|
||||||
ret = fs_checkfd(tcb, fd, oflags);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
/* No... return the reported error */
|
|
||||||
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the stream list from the TCB */
|
|
||||||
|
|
||||||
slist = &tcb->group->tg_info->ta_streamlist;
|
|
||||||
|
|
||||||
/* Allocate FILE structure */
|
|
||||||
|
|
||||||
if (fd >= 3)
|
|
||||||
{
|
|
||||||
stream = group_zalloc(tcb->group, sizeof(FILE));
|
|
||||||
if (stream == NULL)
|
|
||||||
{
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add FILE structure to the stream list */
|
|
||||||
|
|
||||||
ret = nxmutex_lock(&slist->sl_lock);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
group_free(tcb->group, stream);
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slist->sl_tail)
|
|
||||||
{
|
|
||||||
slist->sl_tail->fs_next = stream;
|
|
||||||
slist->sl_tail = stream;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
slist->sl_head = stream;
|
|
||||||
slist->sl_tail = stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
nxmutex_unlock(&slist->sl_lock);
|
|
||||||
|
|
||||||
/* Initialize the mutex the manages access to the buffer */
|
|
||||||
|
|
||||||
nxrmutex_init(&stream->fs_lock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stream = &slist->sl_std[fd];
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(CONFIG_STDIO_DISABLE_BUFFERING) && CONFIG_STDIO_BUFFER_SIZE > 0
|
|
||||||
/* Set up pointers */
|
|
||||||
|
|
||||||
stream->fs_bufstart = stream->fs_buffer;
|
|
||||||
stream->fs_bufend = stream->fs_bufstart + CONFIG_STDIO_BUFFER_SIZE;
|
|
||||||
stream->fs_bufpos = stream->fs_bufstart;
|
|
||||||
stream->fs_bufread = stream->fs_bufstart;
|
|
||||||
stream->fs_flags = __FS_FLAG_UBF; /* Fake setvbuf and fclose */
|
|
||||||
|
|
||||||
# ifdef CONFIG_STDIO_LINEBUFFER
|
|
||||||
/* Setup buffer flags */
|
|
||||||
|
|
||||||
stream->fs_flags |= __FS_FLAG_LBF; /* Line buffering */
|
|
||||||
|
|
||||||
# endif /* CONFIG_STDIO_LINEBUFFER */
|
|
||||||
#endif /* !CONFIG_STDIO_DISABLE_BUFFERING && CONFIG_STDIO_BUFFER_SIZE > 0 */
|
|
||||||
|
|
||||||
/* Save the file description and open flags. Setting the
|
|
||||||
* file descriptor locks this stream.
|
|
||||||
*/
|
|
||||||
|
|
||||||
stream->fs_fd = fd;
|
|
||||||
stream->fs_oflags = oflags;
|
|
||||||
|
|
||||||
*filep = stream;
|
|
||||||
return OK;
|
|
||||||
|
|
||||||
errout:
|
|
||||||
*filep = NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1174,20 +1174,6 @@ int find_mtddriver(FAR const char *pathname, FAR struct inode **ppinode);
|
|||||||
|
|
||||||
int close_mtddriver(FAR struct inode *pinode);
|
int close_mtddriver(FAR struct inode *pinode);
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: fs_fdopen
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function does the core operations for fopen and fdopen. It is
|
|
||||||
* used by the OS to clone stdin, stdout, stderr
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_FILE_STREAM
|
|
||||||
int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
|
|
||||||
FAR struct file_struct **filep);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: lib_flushall
|
* Name: lib_flushall
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -273,10 +273,6 @@ SYSCALL_LOOKUP(munmap, 2)
|
|||||||
SYSCALL_LOOKUP(nx_mkfifo, 3)
|
SYSCALL_LOOKUP(nx_mkfifo, 3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FILE_STREAM
|
|
||||||
SYSCALL_LOOKUP(fs_fdopen, 4)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||||
SYSCALL_LOOKUP(mount, 5)
|
SYSCALL_LOOKUP(mount, 5)
|
||||||
SYSCALL_LOOKUP(mkdir, 2)
|
SYSCALL_LOOKUP(mkdir, 2)
|
||||||
|
|||||||
+72
-15
@@ -65,6 +65,7 @@
|
|||||||
|
|
||||||
FAR FILE *fdopen(int fd, FAR const char *mode)
|
FAR FILE *fdopen(int fd, FAR const char *mode)
|
||||||
{
|
{
|
||||||
|
FAR struct streamlist *list = lib_get_streams();
|
||||||
FAR FILE *filep = NULL;
|
FAR FILE *filep = NULL;
|
||||||
int oflags;
|
int oflags;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -72,14 +73,76 @@ FAR FILE *fdopen(int fd, FAR const char *mode)
|
|||||||
/* Map the open mode string to open flags */
|
/* Map the open mode string to open flags */
|
||||||
|
|
||||||
oflags = lib_mode2oflags(mode);
|
oflags = lib_mode2oflags(mode);
|
||||||
if (oflags >= 0)
|
if (oflags < 0)
|
||||||
{
|
{
|
||||||
ret = fs_fdopen(fd, oflags, NULL, &filep);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate FILE structure */
|
||||||
|
|
||||||
|
if (fd >= 3)
|
||||||
|
{
|
||||||
|
filep = lib_zalloc(sizeof(FILE));
|
||||||
|
if (filep == NULL)
|
||||||
|
{
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add FILE structure to the stream list */
|
||||||
|
|
||||||
|
ret = nxmutex_lock(&list->sl_lock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
set_errno(-ret);
|
lib_free(filep);
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (list->sl_tail)
|
||||||
|
{
|
||||||
|
list->sl_tail->fs_next = filep;
|
||||||
|
list->sl_tail = filep;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list->sl_head = filep;
|
||||||
|
list->sl_tail = filep;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxmutex_unlock(&list->sl_lock);
|
||||||
|
|
||||||
|
/* Initialize the mutex the manages access to the buffer */
|
||||||
|
|
||||||
|
nxrmutex_init(&filep->fs_lock);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filep = &list->sl_std[fd];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_STDIO_DISABLE_BUFFERING) && CONFIG_STDIO_BUFFER_SIZE > 0
|
||||||
|
/* Set up pointers */
|
||||||
|
|
||||||
|
filep->fs_bufstart = filep->fs_buffer;
|
||||||
|
filep->fs_bufend = filep->fs_bufstart + CONFIG_STDIO_BUFFER_SIZE;
|
||||||
|
filep->fs_bufpos = filep->fs_bufstart;
|
||||||
|
filep->fs_bufread = filep->fs_bufstart;
|
||||||
|
filep->fs_flags = __FS_FLAG_UBF; /* Fake setvbuf and fclose */
|
||||||
|
|
||||||
|
# ifdef CONFIG_STDIO_LINEBUFFER
|
||||||
|
/* Setup buffer flags */
|
||||||
|
|
||||||
|
filep->fs_flags |= __FS_FLAG_LBF; /* Line buffering */
|
||||||
|
|
||||||
|
# endif /* CONFIG_STDIO_LINEBUFFER */
|
||||||
|
#endif /* !CONFIG_STDIO_DISABLE_BUFFERING && CONFIG_STDIO_BUFFER_SIZE > 0 */
|
||||||
|
|
||||||
|
/* Save the file description and open flags. Setting the
|
||||||
|
* file descriptor locks this stream.
|
||||||
|
*/
|
||||||
|
|
||||||
|
filep->fs_fd = fd;
|
||||||
|
filep->fs_oflags = oflags;
|
||||||
|
|
||||||
#ifdef CONFIG_FDSAN
|
#ifdef CONFIG_FDSAN
|
||||||
android_fdsan_exchange_owner_tag(fd, 0,
|
android_fdsan_exchange_owner_tag(fd, 0,
|
||||||
@@ -88,6 +151,10 @@ FAR FILE *fdopen(int fd, FAR const char *mode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return filep;
|
return filep;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
set_errno(-ret);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -99,7 +166,6 @@ FAR FILE *fopen(FAR const char *path, FAR const char *mode)
|
|||||||
FAR FILE *filep = NULL;
|
FAR FILE *filep = NULL;
|
||||||
int oflags;
|
int oflags;
|
||||||
int fd;
|
int fd;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Map the open mode string to open flags */
|
/* Map the open mode string to open flags */
|
||||||
|
|
||||||
@@ -120,26 +186,17 @@ FAR FILE *fopen(FAR const char *path, FAR const char *mode)
|
|||||||
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
{
|
{
|
||||||
ret = fs_fdopen(fd, oflags, NULL, &filep);
|
filep = fdopen(fd, mode);
|
||||||
if (ret < 0)
|
if (filep == NULL)
|
||||||
{
|
{
|
||||||
/* Don't forget to close the file descriptor if any other
|
/* Don't forget to close the file descriptor if any other
|
||||||
* failures are reported by fdopen().
|
* failures are reported by fdopen().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
set_errno(-ret);
|
|
||||||
filep = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FDSAN
|
|
||||||
android_fdsan_exchange_owner_tag(fd, 0,
|
|
||||||
android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_FILE,
|
|
||||||
(uintptr_t)filep));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return filep;
|
return filep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
"fchmod","sys/stat.h","","int","int","mode_t"
|
"fchmod","sys/stat.h","","int","int","mode_t"
|
||||||
"fchown","unistd.h","","int","int","uid_t","gid_t"
|
"fchown","unistd.h","","int","int","uid_t","gid_t"
|
||||||
"fcntl","fcntl.h","","int","int","int","...","int"
|
"fcntl","fcntl.h","","int","int","int","...","int"
|
||||||
"fs_fdopen","nuttx/fs/fs.h","defined(CONFIG_FILE_STREAM)","int","int","int","FAR struct tcb_s *","FAR struct file_struct **"
|
|
||||||
"fstat","sys/stat.h","","int","int","FAR struct stat *"
|
"fstat","sys/stat.h","","int","int","FAR struct stat *"
|
||||||
"fstatfs","sys/statfs.h","","int","int","FAR struct statfs *"
|
"fstatfs","sys/statfs.h","","int","int","FAR struct statfs *"
|
||||||
"fsync","unistd.h","","int","int"
|
"fsync","unistd.h","","int","int"
|
||||||
|
|||||||
|
Reference in New Issue
Block a user