mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 01:05:54 +08:00
fs: allocate file/socket dynamically
MIRTOS-273 Change-Id: I8aea63eaf0275f47f21fc8d5482b51ffecd5c906 Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
@@ -69,18 +69,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,18 +84,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,18 +68,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,18 +86,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,18 +79,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefssinfo);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,17 +79,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n", i, inode->i_crefssinfo);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,18 +84,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode != NULL)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefssinfo);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,18 +68,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,18 +86,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,18 +68,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,29 +63,29 @@
|
||||
#ifdef CONFIG_DUMP_ON_EXIT
|
||||
static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
{
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
FAR struct filelist *filelist;
|
||||
#ifdef CONFIG_FILE_STREAM
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
#endif
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FILE_STREAM
|
||||
filep = tcb->group->tg_streamlist->sl_head;
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
* assumed.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0
|
||||
#if !defined(CONFIG_DEV_CONSOLE)
|
||||
# undef USE_SERIALDRIVER
|
||||
# undef USE_EARLYSERIALINIT
|
||||
# undef CONFIG_DEV_LOWCONSOLE
|
||||
@@ -202,13 +202,8 @@ void up_addregion(void);
|
||||
|
||||
/* Defined in xyz_serial.c */
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void up_earlyserialinit(void);
|
||||
void up_serialinit(void);
|
||||
#else
|
||||
# define up_earlyserialinit()
|
||||
# define up_serialinit()
|
||||
#endif
|
||||
|
||||
/* Defined in xyz_watchdog.c */
|
||||
|
||||
|
||||
@@ -85,18 +85,22 @@ static void _xtensa_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,18 +68,22 @@ static void _z16_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,18 +70,22 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
FAR struct file_struct *filep;
|
||||
#endif
|
||||
int i;
|
||||
int j;
|
||||
|
||||
sinfo(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
|
||||
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
for (i = 0; i < filelist->fl_rows; i++)
|
||||
{
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
struct inode *inode = filelist->fl_files[i][j].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sinfo(" fd=%d refcount=%d\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,6 @@
|
||||
# error "Mountpoint support is disabled"
|
||||
#endif
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS < 4
|
||||
# error "Not enough file descriptors"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_FS_ROMFS
|
||||
# error "ROMFS support not enabled"
|
||||
#endif
|
||||
|
||||
+235
-92
File diff suppressed because it is too large
Load Diff
+269
-34
@@ -30,6 +30,7 @@
|
||||
#include <assert.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
@@ -57,6 +58,50 @@ static int _files_semtake(FAR struct filelist *list)
|
||||
|
||||
#define _files_semgive(list) nxsem_post(&list->fl_sem)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: files_extend
|
||||
****************************************************************************/
|
||||
|
||||
static int files_extend(FAR struct filelist *list, size_t row)
|
||||
{
|
||||
FAR struct file **tmp;
|
||||
int i;
|
||||
|
||||
if (row <= list->fl_rows)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = kmm_realloc(list->fl_files, sizeof(FAR struct file *) * row);
|
||||
DEBUGASSERT(tmp);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
i = list->fl_rows;
|
||||
do
|
||||
{
|
||||
tmp[i] = kmm_zalloc(sizeof(struct file) *
|
||||
CONFIG_NFCHUNK_DESCRIPTORS);
|
||||
if (tmp[i] == NULL)
|
||||
{
|
||||
while (--i >= list->fl_rows)
|
||||
{
|
||||
kmm_free(tmp[i]);
|
||||
}
|
||||
|
||||
kmm_free(tmp);
|
||||
return -ENFILE;
|
||||
}
|
||||
}
|
||||
while (++i < row);
|
||||
|
||||
list->fl_files = tmp;
|
||||
list->fl_rows = row;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -100,6 +145,7 @@ void files_initlist(FAR struct filelist *list)
|
||||
void files_releaselist(FAR struct filelist *list)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
DEBUGASSERT(list);
|
||||
|
||||
@@ -108,11 +154,18 @@ void files_releaselist(FAR struct filelist *list)
|
||||
* because there should not be any references in this context.
|
||||
*/
|
||||
|
||||
for (i = CONFIG_NFILE_DESCRIPTORS; i > 0; i--)
|
||||
for (i = list->fl_rows - 1; i >= 0; i--)
|
||||
{
|
||||
file_close(&list->fl_files[i - 1]);
|
||||
for (j = CONFIG_NFCHUNK_DESCRIPTORS - 1; j >= 0; j--)
|
||||
{
|
||||
file_close(&list->fl_files[i][j]);
|
||||
}
|
||||
|
||||
kmm_free(list->fl_files[i]);
|
||||
}
|
||||
|
||||
kmm_free(list->fl_files);
|
||||
|
||||
/* Destroy the semaphore */
|
||||
|
||||
nxsem_destroy(&list->fl_sem);
|
||||
@@ -133,6 +186,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos,
|
||||
FAR struct filelist *list;
|
||||
int ret;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
/* Get the file descriptor list. It should not be NULL in this context. */
|
||||
|
||||
@@ -147,21 +201,188 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos,
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = minfd; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
/* Calcuate minfd whether is in list->fl_files.
|
||||
* if not, allocate a new filechunk.
|
||||
*/
|
||||
|
||||
i = minfd / CONFIG_NFCHUNK_DESCRIPTORS;
|
||||
if (i >= list->fl_rows)
|
||||
{
|
||||
if (!list->fl_files[i].f_inode)
|
||||
ret = files_extend(list, i + 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
list->fl_files[i].f_oflags = oflags;
|
||||
list->fl_files[i].f_pos = pos;
|
||||
list->fl_files[i].f_inode = inode;
|
||||
list->fl_files[i].f_priv = priv;
|
||||
_files_semgive(list);
|
||||
return i;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find free file */
|
||||
|
||||
j = minfd % CONFIG_NFCHUNK_DESCRIPTORS;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!list->fl_files[i][j].f_inode)
|
||||
{
|
||||
list->fl_files[i][j].f_oflags = oflags;
|
||||
list->fl_files[i][j].f_pos = pos;
|
||||
list->fl_files[i][j].f_inode = inode;
|
||||
list->fl_files[i][j].f_priv = priv;
|
||||
_files_semgive(list);
|
||||
return i * CONFIG_NFCHUNK_DESCRIPTORS + j;
|
||||
}
|
||||
}
|
||||
while (++j < CONFIG_NFCHUNK_DESCRIPTORS);
|
||||
|
||||
j = 0;
|
||||
}
|
||||
while (++i < list->fl_rows);
|
||||
|
||||
/* The space of file array isn't enough, allocate a new filechunk */
|
||||
|
||||
ret = files_extend(list, i + 1);
|
||||
if (ret >= 0)
|
||||
{
|
||||
list->fl_files[i][0].f_oflags = oflags;
|
||||
list->fl_files[i][0].f_pos = pos;
|
||||
list->fl_files[i][0].f_inode = inode;
|
||||
list->fl_files[i][0].f_priv = priv;
|
||||
ret = i * CONFIG_NFCHUNK_DESCRIPTORS;
|
||||
}
|
||||
|
||||
_files_semgive(list);
|
||||
return -EMFILE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: files_duplist
|
||||
*
|
||||
* Description:
|
||||
* Duplicate parent task's file descriptors.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
ret = _files_semtake(plist);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Probably canceled */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < plist->fl_rows; i++)
|
||||
{
|
||||
for (j = 0; j < CONFIG_NFCHUNK_DESCRIPTORS; j++)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
#ifdef CONFIG_FDCLONE_STDIO
|
||||
|
||||
/* Determine how many file descriptors to clone. If
|
||||
* CONFIG_FDCLONE_DISABLE is set, no file descriptors will be
|
||||
* cloned. If CONFIG_FDCLONE_STDIO is set, only the first
|
||||
* three descriptors (stdin, stdout, and stderr) will be
|
||||
* cloned. Otherwise all file descriptors will be cloned.
|
||||
*/
|
||||
|
||||
if (i * CONFIG_NFCHUNK_DESCRIPTORS + j >= 3)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
filep = &plist->fl_files[i][j];
|
||||
if (filep->f_inode == NULL || (filep->f_oflags & O_CLOEXEC) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = files_extend(clist, i + 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Yes... duplicate it for the child */
|
||||
|
||||
ret = file_dup2(filep, &clist->fl_files[i][j]);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
_files_semgive(plist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fs_getfilep
|
||||
*
|
||||
* Description:
|
||||
* Given a file descriptor, return the corresponding instance of struct
|
||||
* file.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor
|
||||
* filep - The location to return the struct file instance
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fs_getfilep(int fd, FAR struct file **filep)
|
||||
{
|
||||
FAR struct filelist *list;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
*filep = (FAR struct file *)NULL;
|
||||
|
||||
list = nxsched_get_files();
|
||||
|
||||
/* The file list can be NULL under two cases: (1) One is an obscure
|
||||
* cornercase: When memory management debug output is enabled. Then
|
||||
* there may be attempts to write to stdout from malloc before the group
|
||||
* data has been allocated. The other other is (2) if this is a kernel
|
||||
* thread. Kernel threads have no allocated file descriptors.
|
||||
*/
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if ((unsigned int)fd >= CONFIG_NFCHUNK_DESCRIPTORS * list->fl_rows)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
/* The descriptor is in a valid range to file descriptor... Get the
|
||||
* thread-specific file list.
|
||||
*/
|
||||
|
||||
/* And return the file pointer from the list */
|
||||
|
||||
ret = _files_semtake(list);
|
||||
if (ret >= 0)
|
||||
{
|
||||
*filep = &list->fl_files[fd / CONFIG_NFCHUNK_DESCRIPTORS]
|
||||
[fd % CONFIG_NFCHUNK_DESCRIPTORS];
|
||||
_files_semgive(list);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -187,17 +408,17 @@ int nx_dup2(int fd1, int fd2)
|
||||
FAR struct filelist *list;
|
||||
int ret;
|
||||
|
||||
if (fd1 < 0 || fd1 >= CONFIG_NFILE_DESCRIPTORS ||
|
||||
fd2 < 0 || fd2 >= CONFIG_NFILE_DESCRIPTORS)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
/* Get the file descriptor list. It should not be NULL in this context. */
|
||||
|
||||
list = nxsched_get_files();
|
||||
DEBUGASSERT(list != NULL);
|
||||
|
||||
if (fd1 < 0 || fd1 >= CONFIG_NFCHUNK_DESCRIPTORS * list->fl_rows ||
|
||||
fd2 < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
ret = _files_semtake(list);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -206,16 +427,25 @@ int nx_dup2(int fd1, int fd2)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Perform the dup2 operation */
|
||||
|
||||
ret = file_dup2(&list->fl_files[fd1], &list->fl_files[fd2]);
|
||||
_files_semgive(list);
|
||||
if (ret < 0)
|
||||
if (fd2 >= CONFIG_NFCHUNK_DESCRIPTORS * list->fl_rows)
|
||||
{
|
||||
return ret;
|
||||
ret = files_extend(list, fd2 / CONFIG_NFCHUNK_DESCRIPTORS + 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
_files_semgive(list);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return fd2;
|
||||
/* Perform the dup2 operation */
|
||||
|
||||
ret = file_dup2(&list->fl_files[fd1 / CONFIG_NFCHUNK_DESCRIPTORS]
|
||||
[fd1 % CONFIG_NFCHUNK_DESCRIPTORS],
|
||||
&list->fl_files[fd2 / CONFIG_NFCHUNK_DESCRIPTORS]
|
||||
[fd2 % CONFIG_NFCHUNK_DESCRIPTORS]);
|
||||
_files_semgive(list);
|
||||
|
||||
return ret < 0 ? ret : fd2;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -275,23 +505,28 @@ int nx_close(int fd)
|
||||
list = nxsched_get_files();
|
||||
DEBUGASSERT(list != NULL);
|
||||
|
||||
/* If the file was properly opened, there should be an inode assigned */
|
||||
|
||||
if (fd < 0 || fd >= CONFIG_NFILE_DESCRIPTORS ||
|
||||
!list->fl_files[fd].f_inode)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
/* Perform the protected close operation */
|
||||
|
||||
ret = _files_semtake(list);
|
||||
if (ret >= 0)
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = file_close(&list->fl_files[fd]);
|
||||
_files_semgive(list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If the file was properly opened, there should be an inode assigned */
|
||||
|
||||
if (fd < 0 || fd >= list->fl_rows * CONFIG_NFCHUNK_DESCRIPTORS ||
|
||||
!list->fl_files[fd / CONFIG_NFCHUNK_DESCRIPTORS]
|
||||
[fd % CONFIG_NFCHUNK_DESCRIPTORS].f_inode)
|
||||
{
|
||||
_files_semgive(list);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
ret = file_close(&list->fl_files[fd / CONFIG_NFCHUNK_DESCRIPTORS]
|
||||
[fd % CONFIG_NFCHUNK_DESCRIPTORS]);
|
||||
_files_semgive(list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,12 +140,6 @@ FAR void *rammap(int fd, size_t length, off_t offset)
|
||||
|
||||
/* Allocate a region of memory of the specified size */
|
||||
|
||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||
{
|
||||
errcode = EBADF;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
alloc = (FAR uint8_t *)kumm_malloc(sizeof(struct fs_rammap_s) + length);
|
||||
if (!alloc)
|
||||
{
|
||||
|
||||
+46
-37
@@ -1080,6 +1080,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
|
||||
size_t copysize;
|
||||
size_t totalsize;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
DEBUGASSERT(group != NULL);
|
||||
|
||||
@@ -1102,27 +1103,32 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
|
||||
|
||||
/* Examine each open file descriptor */
|
||||
|
||||
for (i = 0, file = group->tg_filelist.fl_files;
|
||||
i < CONFIG_NFILE_DESCRIPTORS;
|
||||
i++, file++)
|
||||
for (i = 0; i < group->tg_filelist.fl_rows; i++)
|
||||
{
|
||||
/* Is there an inode associated with the file descriptor? */
|
||||
|
||||
if (file->f_inode && !INODE_IS_SOCKET(file->f_inode))
|
||||
for (j = 0, file = group->tg_filelist.fl_files[i];
|
||||
j < CONFIG_NFCHUNK_DESCRIPTORS;
|
||||
j++, file++)
|
||||
{
|
||||
linesize = snprintf(procfile->line, STATUS_LINELEN,
|
||||
"%3d %8ld %04x\n", i, (long)file->f_pos,
|
||||
file->f_oflags);
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer,
|
||||
remaining, &offset);
|
||||
/* Is there an inode associated with the file descriptor? */
|
||||
|
||||
totalsize += copysize;
|
||||
buffer += copysize;
|
||||
remaining -= copysize;
|
||||
|
||||
if (totalsize >= buflen)
|
||||
if (file->f_inode && !INODE_IS_SOCKET(file->f_inode))
|
||||
{
|
||||
return totalsize;
|
||||
linesize = snprintf(procfile->line, STATUS_LINELEN,
|
||||
"%3d %8ld %04x\n",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j,
|
||||
(long)file->f_pos,
|
||||
file->f_oflags);
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer,
|
||||
remaining, &offset);
|
||||
|
||||
totalsize += copysize;
|
||||
buffer += copysize;
|
||||
remaining -= copysize;
|
||||
|
||||
if (totalsize >= buflen)
|
||||
{
|
||||
return totalsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1145,30 +1151,33 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
|
||||
|
||||
/* Examine each open socket descriptor */
|
||||
|
||||
for (i = 0, file = group->tg_filelist.fl_files;
|
||||
i < CONFIG_NFILE_DESCRIPTORS;
|
||||
i++, file++)
|
||||
for (i = 0; i < group->tg_filelist.fl_rows; i++)
|
||||
{
|
||||
/* Is there an connection associated with the socket descriptor? */
|
||||
|
||||
if (file->f_inode && INODE_IS_SOCKET(file->f_inode))
|
||||
for (j = 0, file = group->tg_filelist.fl_files[i];
|
||||
j < CONFIG_NFCHUNK_DESCRIPTORS;
|
||||
j++, file++)
|
||||
{
|
||||
FAR struct socket *socket = file->f_priv;
|
||||
linesize = snprintf(procfile->line, STATUS_LINELEN,
|
||||
"%3d %3d %02x",
|
||||
i + CONFIG_NFILE_DESCRIPTORS,
|
||||
socket->s_type,
|
||||
socket->s_flags);
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer,
|
||||
remaining, &offset);
|
||||
/* Is there an connection associated with the socket descriptor? */
|
||||
|
||||
totalsize += copysize;
|
||||
buffer += copysize;
|
||||
remaining -= copysize;
|
||||
|
||||
if (totalsize >= buflen)
|
||||
if (file->f_inode && INODE_IS_SOCKET(file->f_inode))
|
||||
{
|
||||
return totalsize;
|
||||
FAR struct socket *socket = file->f_priv;
|
||||
linesize = snprintf(procfile->line, STATUS_LINELEN,
|
||||
"%3d %3d %02x",
|
||||
i * CONFIG_NFCHUNK_DESCRIPTORS + j,
|
||||
socket->s_type,
|
||||
socket->s_flags);
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer,
|
||||
remaining, &offset);
|
||||
|
||||
totalsize += copysize;
|
||||
buffer += copysize;
|
||||
remaining -= copysize;
|
||||
|
||||
if (totalsize >= buflen)
|
||||
{
|
||||
return totalsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
# Common file/socket descriptor support
|
||||
|
||||
CSRCS += fs_close.c fs_dup.c fs_dup2.c fs_fcntl.c
|
||||
CSRCS += fs_epoll.c fs_fstat.c fs_fstatfs.c fs_getfilep.c fs_ioctl.c
|
||||
CSRCS += fs_epoll.c fs_fstat.c fs_fstatfs.c fs_ioctl.c
|
||||
CSRCS += fs_lseek.c fs_mkdir.c fs_open.c fs_poll.c fs_read.c fs_rename.c
|
||||
CSRCS += fs_rmdir.c fs_statfs.c fs_stat.c fs_select.c fs_unlink.c fs_write.c
|
||||
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/****************************************************************************
|
||||
* fs/vfs/fs_getfilep.c
|
||||
*
|
||||
* Copyright (C) 2014, 2016-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/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fs_getfilep
|
||||
*
|
||||
* Description:
|
||||
* Given a file descriptor, return the corresponding instance of struct
|
||||
* file. NOTE that this function will currently fail if it is provided
|
||||
* with a socket descriptor.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor
|
||||
* filep - The location to return the struct file instance
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fs_getfilep(int fd, FAR struct file **filep)
|
||||
{
|
||||
FAR struct filelist *list;
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
*filep = (FAR struct file *)NULL;
|
||||
|
||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
/* The descriptor is in a valid range to file descriptor... Get the
|
||||
* thread-specific file list.
|
||||
*/
|
||||
|
||||
list = nxsched_get_files();
|
||||
|
||||
/* The file list can be NULL under two cases: (1) One is an obscure
|
||||
* cornercase: When memory management debug output is enabled. Then
|
||||
* there may be attempts to write to stdout from malloc before the group
|
||||
* data has been allocated. The other other is (2) if this is a kernel
|
||||
* thread. Kernel threads have no allocated file descriptors.
|
||||
*/
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* And return the file pointer from the list */
|
||||
|
||||
*filep = &list->fl_files[fd];
|
||||
return OK;
|
||||
}
|
||||
@@ -128,11 +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 > 127
|
||||
int16_t aio_fildes; /* File descriptor (should be int) */
|
||||
#else
|
||||
int8_t aio_fildes; /* File descriptor (should be int) */
|
||||
#endif
|
||||
int8_t aio_reqprio; /* Request priority offset (not used, should be int) */
|
||||
uint8_t aio_lio_opcode; /* Operation to be performed (should be int) */
|
||||
|
||||
|
||||
+2
-2
@@ -135,10 +135,10 @@
|
||||
#define _POSIX_MAX_INPUT 255
|
||||
#define _POSIX_NAME_MAX CONFIG_NAME_MAX
|
||||
#define _POSIX_NGROUPS_MAX 0
|
||||
#define _POSIX_OPEN_MAX CONFIG_NFILE_DESCRIPTORS
|
||||
#define _POSIX_OPEN_MAX INT_MAX
|
||||
#define _POSIX_PATH_MAX CONFIG_PATH_MAX
|
||||
#define _POSIX_PIPE_BUF 512
|
||||
#define _POSIX_STREAM_MAX CONFIG_NFILE_DESCRIPTORS
|
||||
#define _POSIX_STREAM_MAX INT_MAX
|
||||
#define _POSIX_TZNAME_MAX 3
|
||||
|
||||
#ifdef CONFIG_SMALL_MEMORY
|
||||
|
||||
+23
-3
@@ -377,12 +377,18 @@ struct file
|
||||
FAR void *f_priv; /* Per file driver private data */
|
||||
};
|
||||
|
||||
/* This defines a list of files indexed by the file descriptor */
|
||||
/* This defines a two layer array of files indexed by the file descriptor.
|
||||
* Each row of this array is fixed size: CONFIG_NFCHUNK_DESCRIPTORS.
|
||||
* You can get file instance in filelist by the follow methods:
|
||||
* (file descriptor / CONFIG_NFCHUNK_DESCRIPTORS) as row index and
|
||||
* (file descriptor % CONFIG_NFCHUNK_DESCRIPTORS) as column index.
|
||||
*/
|
||||
|
||||
struct filelist
|
||||
{
|
||||
sem_t fl_sem; /* Manage access to the file list */
|
||||
struct file fl_files[CONFIG_NFILE_DESCRIPTORS];
|
||||
sem_t fl_sem; /* Manage access to the file list */
|
||||
uint8_t fl_rows; /* The number of rows of fl_files array */
|
||||
FAR struct file **fl_files; /* The pointer of two layer file descriptors array */
|
||||
};
|
||||
|
||||
/* The following structure defines the list of files used for standard C I/O.
|
||||
@@ -713,6 +719,20 @@ void files_initlist(FAR struct filelist *list);
|
||||
|
||||
void files_releaselist(FAR struct filelist *list);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: files_duplist
|
||||
*
|
||||
* Description:
|
||||
* Duplicate parent task's file descriptors.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: file_dup
|
||||
*
|
||||
|
||||
@@ -81,13 +81,6 @@
|
||||
# define _NX_GETERRVAL(r) (-errno)
|
||||
#endif
|
||||
|
||||
/* Socket descriptors are the index into the TCB sockets list, offset by the
|
||||
* following amount. This offset is used to distinguish file descriptors from
|
||||
* socket descriptors
|
||||
*/
|
||||
|
||||
#define __SOCKFD_OFFSET CONFIG_NFILE_DESCRIPTORS
|
||||
|
||||
/* Capabilities of a socket */
|
||||
|
||||
#define SOCKCAP_NONBLOCKING (1 << 0) /* Bit 0: Socket supports non-blocking
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
/* Get the total number of descriptors that we will have to support */
|
||||
|
||||
#define FD_SETSIZE CONFIG_NFILE_DESCRIPTORS
|
||||
#define FD_SETSIZE 256
|
||||
|
||||
/* 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?
|
||||
|
||||
@@ -78,7 +78,7 @@ int posix_spawn_file_actions_addclose(FAR posix_spawn_file_actions_t *file_actio
|
||||
{
|
||||
FAR struct spawn_close_file_action_s *entry;
|
||||
|
||||
DEBUGASSERT(file_actions && fd >= 0 && fd < CONFIG_NFILE_DESCRIPTORS);
|
||||
DEBUGASSERT(file_actions && fd >= 0);
|
||||
|
||||
/* Allocate the action list entry */
|
||||
|
||||
|
||||
@@ -79,9 +79,7 @@ int posix_spawn_file_actions_adddup2(FAR posix_spawn_file_actions_t *file_action
|
||||
{
|
||||
FAR struct spawn_dup2_file_action_s *entry;
|
||||
|
||||
DEBUGASSERT(file_actions &&
|
||||
fd1 >= 0 && fd1 < CONFIG_NFILE_DESCRIPTORS &&
|
||||
fd2 >= 0 && fd2 < CONFIG_NFILE_DESCRIPTORS);
|
||||
DEBUGASSERT(file_actions && fd1 >= 0 && fd2 >= 0);
|
||||
|
||||
/* Allocate the action list entry */
|
||||
|
||||
|
||||
@@ -87,8 +87,7 @@ int posix_spawn_file_actions_addopen(FAR posix_spawn_file_actions_t *file_action
|
||||
size_t len;
|
||||
size_t alloc;
|
||||
|
||||
DEBUGASSERT(file_actions && path &&
|
||||
fd >= 0 && fd < CONFIG_NFILE_DESCRIPTORS);
|
||||
DEBUGASSERT(file_actions && path && fd >= 0);
|
||||
|
||||
/* Get the size of the action including storage for the path plus its NUL
|
||||
* terminating character.
|
||||
|
||||
@@ -224,7 +224,7 @@ long sysconf(int name)
|
||||
switch (name)
|
||||
{
|
||||
case _SC_OPEN_MAX:
|
||||
return CONFIG_NFILE_DESCRIPTORS;
|
||||
return _POSIX_OPEN_MAX;
|
||||
|
||||
case _SC_ATEXIT_MAX:
|
||||
#ifdef CONFIG_SCHED_EXIT_MAX
|
||||
|
||||
+2
-1
@@ -244,6 +244,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
||||
{
|
||||
FAR struct socket *psock = sockfd_socket(sockfd);
|
||||
FAR struct socket *newsock;
|
||||
FAR struct file *filep;
|
||||
int newfd;
|
||||
int errcode;
|
||||
int ret;
|
||||
@@ -261,7 +262,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
||||
* used in the wrong context.
|
||||
*/
|
||||
|
||||
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
|
||||
if (fs_getfilep(sockfd, &filep) == 0)
|
||||
{
|
||||
errcode = ENOTSOCK;
|
||||
}
|
||||
|
||||
+4
-1
@@ -44,6 +44,8 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -143,6 +145,7 @@ int psock_listen(FAR struct socket *psock, int backlog)
|
||||
int listen(int sockfd, int backlog)
|
||||
{
|
||||
FAR struct socket *psock = sockfd_socket(sockfd);
|
||||
FAR struct file *filep;
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
@@ -155,7 +158,7 @@ int listen(int sockfd, int backlog)
|
||||
* descriptor used in the wrong context.
|
||||
*/
|
||||
|
||||
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
|
||||
if (fs_getfilep(sockfd, &filep) == 0)
|
||||
{
|
||||
errcode = ENOTSOCK;
|
||||
}
|
||||
|
||||
+4
-4
@@ -1065,12 +1065,12 @@ config SDCLONE_DISABLE
|
||||
descriptors by task_create() when a new task is started. If
|
||||
set, all sockets will appear to be closed in the new task.
|
||||
|
||||
config NFILE_DESCRIPTORS
|
||||
int "Maximum number of file descriptors per task"
|
||||
default 16
|
||||
config NFCHUNK_DESCRIPTORS
|
||||
int "The number of file descriptors per row"
|
||||
default 8
|
||||
range 3 99999
|
||||
---help---
|
||||
The maximum number of file descriptors per task (one for each open)
|
||||
The number of file descriptors per row (one for each open)
|
||||
|
||||
config FILE_STREAM
|
||||
bool "Enable FILE stream"
|
||||
|
||||
@@ -25,94 +25,12 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "group/group.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Determine how many file descriptors to clone. If CONFIG_FDCLONE_DISABLE
|
||||
* is set, no file descriptors will be cloned. If CONFIG_FDCLONE_STDIO is
|
||||
* set, only the first three descriptors (stdin, stdout, and stderr) will
|
||||
* be cloned. Otherwise all file descriptors will be cloned.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_FDCLONE_STDIO) && CONFIG_NFILE_DESCRIPTORS > 3
|
||||
# define NFDS_TOCLONE 3
|
||||
#else
|
||||
# define NFDS_TOCLONE CONFIG_NFILE_DESCRIPTORS
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_dupfiles
|
||||
*
|
||||
* Description:
|
||||
* Duplicate parent task's file descriptors.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - tcb of the new task.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_FDCLONE_DISABLE
|
||||
static inline void sched_dupfiles(FAR struct task_tcb_s *tcb)
|
||||
{
|
||||
/* The parent task is the one at the head of the ready-to-run list */
|
||||
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR struct file *parent;
|
||||
FAR struct file *child;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(tcb && tcb->cmn.group && rtcb->group);
|
||||
|
||||
/* Duplicate the file descriptors. This will be either all of the
|
||||
* file descriptors or just the first three (stdin, stdout, and stderr)
|
||||
* if CONFIG_FDCLONE_STDIO is defined. NFSDS_TOCLONE is set
|
||||
* accordingly above.
|
||||
*/
|
||||
|
||||
/* Get pointers to the parent and child task file lists */
|
||||
|
||||
parent = rtcb->group->tg_filelist.fl_files;
|
||||
child = tcb->cmn.group->tg_filelist.fl_files;
|
||||
|
||||
/* Check each file in the parent file list */
|
||||
|
||||
for (i = 0; i < NFDS_TOCLONE; i++)
|
||||
{
|
||||
/* Check if this file is opened by the parent. We can tell if
|
||||
* if the file is open because it contain a reference to a non-NULL
|
||||
* i-node structure.
|
||||
*/
|
||||
|
||||
if (parent[i].f_inode &&
|
||||
(parent[i].f_oflags & O_CLOEXEC) == 0)
|
||||
{
|
||||
/* Yes... duplicate it for the child */
|
||||
|
||||
file_dup2(&parent[i], &child[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* !CONFIG_FDCLONE_DISABLE */
|
||||
# define sched_dupfiles(tcb)
|
||||
#endif /* !CONFIG_FDCLONE_DISABLE */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -138,6 +56,10 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb)
|
||||
int group_setuptaskfiles(FAR struct task_tcb_s *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group = tcb->cmn.group;
|
||||
#ifndef CONFIG_FDCLONE_DISABLE
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(group);
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
@@ -149,9 +71,17 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb)
|
||||
|
||||
files_initlist(&group->tg_filelist);
|
||||
|
||||
#ifndef CONFIG_FDCLONE_DISABLE
|
||||
DEBUGASSERT(rtcb->group);
|
||||
|
||||
/* Duplicate the parent task's file descriptors */
|
||||
|
||||
sched_dupfiles(tcb);
|
||||
ret = files_duplist(&rtcb->group->tg_filelist, &group->tg_filelist);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate file/socket streams for the new TCB */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user