libc/stdio: Preallocate the stdin, stdout and stderr
to handle the uninitialized stdin/stdout/stderr gracefully report here: https://github.com/apache/incubator-nuttx/issues/2203 Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
1dad55d4be
commit
84b90e00f0
@ -178,36 +178,61 @@ int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get the stream list from the TCB */
|
||||
|
||||
#ifdef CONFIG_MM_KERNEL_HEAP
|
||||
slist = tcb->group->tg_streamlist;
|
||||
#else
|
||||
slist = &tcb->group->tg_streamlist;
|
||||
#endif
|
||||
|
||||
/* Allocate FILE structure */
|
||||
|
||||
#ifdef CONFIG_STDIO_DISABLE_BUFFERING
|
||||
stream = group_zalloc(tcb->group, sizeof(FILE));
|
||||
if (stream == NULL)
|
||||
if (fd >= 3)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
stream = group_zalloc(tcb->group, sizeof(FILE));
|
||||
if (stream == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Add FILE structure to the stream list */
|
||||
|
||||
ret = nxsem_wait(&slist->sl_sem);
|
||||
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;
|
||||
}
|
||||
|
||||
nxsem_post(&slist->sl_sem);
|
||||
|
||||
/* Initialize the semaphore the manages access to the buffer */
|
||||
|
||||
lib_sem_initialize(stream);
|
||||
}
|
||||
#else
|
||||
stream = group_malloc(tcb->group, sizeof(FILE) +
|
||||
CONFIG_STDIO_BUFFER_SIZE);
|
||||
if (stream == NULL)
|
||||
else
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
stream = &slist->sl_std[fd];
|
||||
}
|
||||
|
||||
/* Zero the structure */
|
||||
|
||||
memset(stream, 0, sizeof(FILE));
|
||||
|
||||
/* Initialize the semaphore the manages access to the buffer */
|
||||
|
||||
lib_sem_initialize(stream);
|
||||
|
||||
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
/* Set up pointers */
|
||||
|
||||
stream->fs_bufstart = (FAR unsigned char *)(stream + 1);
|
||||
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;
|
||||
@ -229,34 +254,6 @@ int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
|
||||
stream->fs_fd = fd;
|
||||
stream->fs_oflags = oflags;
|
||||
|
||||
/* Get the stream list from the TCB */
|
||||
|
||||
#ifdef CONFIG_MM_KERNEL_HEAP
|
||||
slist = tcb->group->tg_streamlist;
|
||||
#else
|
||||
slist = &tcb->group->tg_streamlist;
|
||||
#endif
|
||||
|
||||
/* Add FILE structure to the stream list */
|
||||
|
||||
ret = nxsem_wait(&slist->sl_sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_mem;
|
||||
}
|
||||
|
||||
if (slist->sl_tail)
|
||||
{
|
||||
slist->sl_tail->fs_next = stream;
|
||||
slist->sl_tail = stream;
|
||||
}
|
||||
else
|
||||
{
|
||||
slist->sl_head = stream;
|
||||
slist->sl_tail = stream;
|
||||
}
|
||||
|
||||
nxsem_post(&slist->sl_sem);
|
||||
if (filep != NULL)
|
||||
{
|
||||
*filep = stream;
|
||||
@ -264,9 +261,6 @@ int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_mem:
|
||||
group_free(tcb->group, stream);
|
||||
|
||||
errout:
|
||||
if (filep != NULL)
|
||||
{
|
||||
|
@ -469,6 +469,9 @@ struct file_struct
|
||||
FAR unsigned char *fs_bufend; /* Pointer to 1 past end of buffer */
|
||||
FAR unsigned char *fs_bufpos; /* Current position in buffer */
|
||||
FAR unsigned char *fs_bufread; /* Pointer to 1 past last buffered read char. */
|
||||
# if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
unsigned char fs_buffer[CONFIG_STDIO_BUFFER_SIZE];
|
||||
# endif
|
||||
#endif
|
||||
uint16_t fs_oflags; /* Open mode flags */
|
||||
uint8_t fs_flags; /* Stream flags */
|
||||
@ -481,6 +484,7 @@ struct file_struct
|
||||
struct streamlist
|
||||
{
|
||||
sem_t sl_sem; /* For thread safety */
|
||||
struct file_struct sl_std[3];
|
||||
FAR struct file_struct *sl_head;
|
||||
FAR struct file_struct *sl_tail;
|
||||
};
|
||||
|
@ -78,9 +78,9 @@
|
||||
|
||||
/* The first three _iob entries are reserved for standard I/O */
|
||||
|
||||
#define stdin (nxsched_get_streams()->sl_head)
|
||||
#define stdout (nxsched_get_streams()->sl_head->fs_next)
|
||||
#define stderr (nxsched_get_streams()->sl_head->fs_next->fs_next)
|
||||
#define stdin (&nxsched_get_streams()->sl_std[0])
|
||||
#define stdout (&nxsched_get_streams()->sl_std[1])
|
||||
#define stderr (&nxsched_get_streams()->sl_std[2])
|
||||
|
||||
/* Path to the directory where temporary files can be created */
|
||||
|
||||
|
@ -85,6 +85,15 @@ void lib_stream_initialize(FAR struct task_group_s *group)
|
||||
_SEM_INIT(&list->sl_sem, 0, 1);
|
||||
list->sl_head = NULL;
|
||||
list->sl_tail = NULL;
|
||||
|
||||
/* Initialize stdin, stdout and stderr stream */
|
||||
|
||||
list->sl_std[0].fs_fd = -1;
|
||||
lib_sem_initialize(&list->sl_std[0]);
|
||||
list->sl_std[1].fs_fd = -1;
|
||||
lib_sem_initialize(&list->sl_std[1]);
|
||||
list->sl_std[2].fs_fd = -1;
|
||||
lib_sem_initialize(&list->sl_std[2]);
|
||||
}
|
||||
#endif /* CONFIG_FILE_STREAM */
|
||||
|
||||
@ -147,6 +156,14 @@ void lib_stream_release(FAR struct task_group_s *group)
|
||||
group_free(group, stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy stdin, stdout and stderr stream */
|
||||
|
||||
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
|
||||
_SEM_DESTROY(&list->sl_std[0].fs_sem);
|
||||
_SEM_DESTROY(&list->sl_std[1].fs_sem);
|
||||
_SEM_DESTROY(&list->sl_std[2].fs_sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FILE_STREAM */
|
||||
|
Loading…
Reference in New Issue
Block a user