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:
parent
62c2b1abba
commit
b1c8c84e81
@ -60,12 +60,6 @@ if(CONFIG_PSEUDOFS_FILE)
|
||||
list(APPEND SRCS fs_pseudofile.c)
|
||||
endif()
|
||||
|
||||
# Stream support
|
||||
|
||||
if(CONFIG_FILE_STREAM)
|
||||
list(APPEND SRCS fs_fdopen.c)
|
||||
endif()
|
||||
|
||||
# Support for eventfd
|
||||
|
||||
if(CONFIG_EVENT_FD)
|
||||
|
@ -39,12 +39,6 @@ ifeq ($(CONFIG_PSEUDOFS_FILE),y)
|
||||
CSRCS += fs_pseudofile.c
|
||||
endif
|
||||
|
||||
# Stream support
|
||||
|
||||
ifeq ($(CONFIG_FILE_STREAM),y)
|
||||
CSRCS += fs_fdopen.c
|
||||
endif
|
||||
|
||||
# Support for eventfd
|
||||
|
||||
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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
|
@ -273,10 +273,6 @@ SYSCALL_LOOKUP(munmap, 2)
|
||||
SYSCALL_LOOKUP(nx_mkfifo, 3)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FILE_STREAM
|
||||
SYSCALL_LOOKUP(fs_fdopen, 4)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
SYSCALL_LOOKUP(mount, 5)
|
||||
SYSCALL_LOOKUP(mkdir, 2)
|
||||
|
@ -65,6 +65,7 @@
|
||||
|
||||
FAR FILE *fdopen(int fd, FAR const char *mode)
|
||||
{
|
||||
FAR struct streamlist *list = lib_get_streams();
|
||||
FAR FILE *filep = NULL;
|
||||
int oflags;
|
||||
int ret;
|
||||
@ -72,14 +73,76 @@ FAR FILE *fdopen(int fd, FAR const char *mode)
|
||||
/* Map the open mode string to open flags */
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
android_fdsan_exchange_owner_tag(fd, 0,
|
||||
@ -88,6 +151,10 @@ FAR FILE *fdopen(int fd, FAR const char *mode)
|
||||
#endif
|
||||
|
||||
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;
|
||||
int oflags;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
ret = fs_fdopen(fd, oflags, NULL, &filep);
|
||||
if (ret < 0)
|
||||
filep = fdopen(fd, mode);
|
||||
if (filep == NULL)
|
||||
{
|
||||
/* Don't forget to close the file descriptor if any other
|
||||
* failures are reported by fdopen().
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
"fchmod","sys/stat.h","","int","int","mode_t"
|
||||
"fchown","unistd.h","","int","int","uid_t","gid_t"
|
||||
"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 *"
|
||||
"fstatfs","sys/statfs.h","","int","int","FAR struct statfs *"
|
||||
"fsync","unistd.h","","int","int"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Reference in New Issue
Block a user