setvbuf: Add support for disabling I/O buffering. Initially cut; untested.

This commit is contained in:
Gregory Nutt
2017-02-09 09:24:44 -06:00
parent e6558df4ad
commit 1d290c2b37
72 changed files with 461 additions and 330 deletions
+12 -2
View File
@@ -5,12 +5,22 @@
comment "Standard C Library Options"
config STDIO_DISABLE_BUFFERING
bool "Disable I/O Buffering"
default n
---help---
Tiny systems may need to disable all support for I/O buffering in
order to minimum footprint.
config STDIO_BUFFER_SIZE
int "C STDIO buffer size"
default 64
depends on !STDIO_DISABLE_BUFFERING
---help---
Size of buffers using within the C buffered I/O interfaces.
(printf, putchar, fwrite, etc.).
Size of buffers using within the C buffered I/O interfaces (printf,
putchar, fwrite, etc.). This function sets the initial I/O buffer
size. Zero disables I/O buffering. That size may be subsequently
modified using setvbuf().
config STDIO_LINEBUFFER
bool "STDIO line buffering"
+3 -3
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/libc.h
*
* Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-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
@@ -67,7 +67,7 @@
* protection.
*/
#if CONFIG_STDIO_BUFFER_SIZE <= 0
#ifdef CONFIG_STDIO_DISABLE_BUFFERING
# define lib_sem_initialize(s)
# define lib_take_semaphore(s)
# define lib_give_semaphore(s)
@@ -186,7 +186,7 @@ int lib_wrflush(FAR FILE *stream);
/* Defined in lib_sem.c */
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
void lib_sem_initialize(FAR struct file_struct *stream);
void lib_take_semaphore(FAR struct file_struct *stream);
void lib_give_semaphore(FAR struct file_struct *stream);
+5 -1
View File
@@ -35,9 +35,13 @@
# Add the internal C files to the build
CSRCS += lib_stream.c lib_filesem.c lib_utsname.c
CSRCS += lib_stream.c lib_utsname.c
CSRCS += lib_xorshift128.c lib_tea_encrypt.c lib_tea_decrypt.c
ifneq ($(CONFIG_STDIO_DISABLE_BUFFERING),y)
CSRCS += lib_filesem.c
endif
# Support for platforms that do not have long long types
CSRCS += lib_umul32.c lib_umul64.c lib_umul32x64.c
+4 -11
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/misc/lib_filesem.c
*
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2009, 2011, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -47,15 +47,7 @@
#include "libc.h"
#if CONFIG_STDIO_BUFFER_SIZE > 0
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/****************************************************************************
* Public Functions
@@ -142,4 +134,5 @@ void lib_give_semaphore(FAR struct file_struct *stream)
ASSERT(sem_post(&stream->fs_sem) == 0);
}
}
#endif /* CONFIG_STDIO_BUFFER_SIZE */
#endif /* CONFIG_STDIO_DISABLE_BUFFERING */
+5 -5
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/misc/lib_stream.c
*
* Copyright (C) 2007, 2011, 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2011, 2013-2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -109,7 +109,7 @@ void lib_stream_initialize(FAR struct task_group_s *group)
#endif /* CONFIG_NFILE_STREAMS > 0 */
/****************************************************************************
* Name: lib_stream_init
* Name: lib_stream_release
*
* Description:
* This function is called when a TCB is destroyed. Note that it does not
@@ -122,7 +122,7 @@ void lib_stream_initialize(FAR struct task_group_s *group)
void lib_stream_release(FAR struct task_group_s *group)
{
FAR struct streamlist *list;
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
int i;
#endif
@@ -139,9 +139,9 @@ void lib_stream_release(FAR struct task_group_s *group)
(void)sem_destroy(&list->sl_sem);
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/* Release each stream in the list */
#if CONFIG_STDIO_BUFFER_SIZE > 0
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
{
FAR struct file_struct *stream = &list->sl_streams[i];
@@ -177,6 +177,6 @@ void lib_stream_release(FAR struct task_group_s *group)
}
#endif
}
#endif /* CONFIG_NFILE_STREAMS > 0 */
#endif /* CONFIG_NFILE_STREAMS > 0 */
#endif /* (!CONFIG_BUILD_PROTECTED &&7 !CONFIG_BUILD_KERNEL) || __KERNEL__ */
+5 -1
View File
@@ -65,13 +65,17 @@ CSRCS += lib_rdflush.c lib_wrflush.c lib_fputc.c lib_puts.c lib_fputs.c
CSRCS += lib_ungetc.c lib_vprintf.c lib_fprintf.c lib_vfprintf.c
CSRCS += lib_stdinstream.c lib_stdoutstream.c lib_stdsistream.c
CSRCS += lib_stdsostream.c lib_perror.c lib_feof.c lib_ferror.c
CSRCS += lib_clearerr.c lib_setvbuf.c lib_libnoflush.c lib_libsnoflush.c
CSRCS += lib_clearerr.c lib_libnoflush.c lib_libsnoflush.c
endif
ifeq ($(CONFIG_FS_WRITABLE),y)
CSRCS += lib_tempnam.c lib_tmpnam.c
endif
ifneq ($(CONFIG_STDIO_DISABLE_BUFFERING),y)
CSRCS += lib_setvbuf.c
endif
endif
# Other support that depends on specific, configured features.
+3 -1
View File
@@ -107,7 +107,7 @@ int fclose(FAR FILE *stream)
}
}
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/* Destroy the semaphore */
sem_destroy(&stream->fs_sem);
@@ -123,6 +123,7 @@ int fclose(FAR FILE *stream)
/* Clear the whole structure */
memset(stream, 0, sizeof(FILE));
#else
#if CONFIG_NUNGET_CHARS > 0
/* Reset the number of ungetc characters */
@@ -133,6 +134,7 @@ int fclose(FAR FILE *stream)
stream->fs_oflags = 0;
#endif
/* Setting the file descriptor to -1 makes the stream available for reuse */
stream->fs_fd = -1;
+11 -9
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_fseek.c
*
* Copyright (C) 2007, 2008, 2011, 2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2008, 2011, 2013, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -71,14 +71,7 @@
int fseek(FAR FILE *stream, long int offset, int whence)
{
#if CONFIG_STDIO_BUFFER_SIZE > 0
/* Flush any valid read/write data in the buffer (also verifies stream) */
if (lib_rdflush(stream) < 0 || lib_wrflush(stream) < 0)
{
return ERROR;
}
#else
#ifdef CONFIG_DEBUG_FEATURES
/* Verify that we were provided with a stream */
if (!stream)
@@ -88,6 +81,15 @@ int fseek(FAR FILE *stream, long int offset, int whence)
}
#endif
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/* Flush any valid read/write data in the buffer (also verifies stream) */
if (lib_rdflush(stream) < 0 || lib_wrflush(stream) < 0)
{
return ERROR;
}
#endif
/* On success or failure, discard any characters saved by ungetc() */
#if CONFIG_NUNGET_CHARS > 0
+3 -3
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_ftell.c
*
* Copyright (C) 2008, 2011, 2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2008, 2011, 2013, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -64,13 +64,13 @@
*
****************************************************************************/
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
static off_t lib_getrdoffset(FAR FILE *stream)
{
off_t rdoffset = 0;
lib_take_semaphore(stream);
if (stream->fs_bufread != stream->fs_bufstart)
if (stream->fs_bufstart != NULL && stream->fs_bufread != stream->fs_bufstart)
{
#if CONFIG_NUNGET_CHARS > 0
rdoffset = stream->fs_bufread - stream->fs_bufpos + stream->fs_nungotten;
+23 -7
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_libfflush.c
*
* Copyright (C) 2007-2008, 2011-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2008, 2011-2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -73,10 +73,11 @@
ssize_t lib_fflush(FAR FILE *stream, bool bforce)
{
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
FAR const unsigned char *src;
ssize_t bytes_written;
ssize_t nbuffer;
int ret;
/* Return EBADF if the file is not opened for writing */
@@ -89,9 +90,19 @@ ssize_t lib_fflush(FAR FILE *stream, bool bforce)
lib_take_semaphore(stream);
/* Check if there is an allocated I/O buffer */
if (stream->fs_bufstart == NULL)
{
/* No, then there can be nothing remaining in the buffer. */
ret = 0;
goto errout_with_sem;
}
/* Make sure that the buffer holds valid data */
if (stream->fs_bufpos != stream->fs_bufstart)
if (stream->fs_bufpos != stream->fs_bufstart)
{
/* Make sure that the buffer holds buffered write data. We do not
* support concurrent read/write buffer usage.
@@ -103,8 +114,8 @@ ssize_t lib_fflush(FAR FILE *stream, bool bforce)
* remaining in the buffer."
*/
lib_give_semaphore(stream);
return 0;
ret = 0;
goto errout_with_sem;
}
/* How many bytes of write data are used in the buffer now */
@@ -126,8 +137,8 @@ ssize_t lib_fflush(FAR FILE *stream, bool bforce)
*/
stream->fs_flags |= __FS_FLAG_ERROR;
lib_give_semaphore(stream);
return -get_errno();
ret = -get_errno();;
goto errout_with_sem;
}
/* Handle partial writes. fflush() must either return with
@@ -162,6 +173,11 @@ ssize_t lib_fflush(FAR FILE *stream, bool bforce)
lib_give_semaphore(stream);
return stream->fs_bufpos - stream->fs_bufstart;
errout_with_sem:
lib_give_semaphore(stream);
return ret;
#else
/* Return no bytes remaining in the buffer */
+132 -125
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_libfread.c
*
* Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011-2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -60,7 +60,7 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream)
{
FAR unsigned char *dest = (FAR unsigned char*)ptr;
ssize_t bytes_read;
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
int ret;
#endif
@@ -96,170 +96,177 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream)
}
#endif
#if CONFIG_STDIO_BUFFER_SIZE > 0
/* If the buffer is currently being used for write access, then
* flush all of the buffered write data. We do not support concurrent
* buffered read/write access.
*/
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/* Is there an I/O buffer? */
ret = lib_wrflush(stream);
if (ret < 0)
if (stream->bufstart != NULL)
{
lib_give_semaphore(stream);
return ret;
}
/* Now get any other needed chars from the buffer or the file. */
while (count > 0)
{
/* Is there readable data in the buffer? */
while ((count > 0) && (stream->fs_bufpos < stream->fs_bufread))
{
/* Yes, copy a byte into the user buffer */
*dest++ = *stream->fs_bufpos++;
count--;
}
/* The buffer is empty OR we have already supplied the number of
* bytes requested in the read. Check if we need to read
* more from the file.
/* If the buffer is currently being used for write access, then
* flush all of the buffered write data. We do not support concurrent
* buffered read/write access.
*/
if (count > 0)
ret = lib_wrflush(stream);
if (ret < 0)
{
size_t buffer_available;
lib_give_semaphore(stream);
return ret;
}
/* We need to read more data into the buffer from the file */
/* Now get any other needed chars from the buffer or the file. */
/* Mark the buffer empty */
while (count > 0)
{
/* Is there readable data in the buffer? */
stream->fs_bufpos = stream->fs_bufread = stream->fs_bufstart;
while ((count > 0) && (stream->fs_bufpos < stream->fs_bufread))
{
/* Yes, copy a byte into the user buffer */
/* How much space is available in the buffer? */
*dest++ = *stream->fs_bufpos++;
count--;
}
buffer_available = stream->fs_bufend - stream->fs_bufread;
/* Will the number of bytes that we need to read fit into
* the buffer space that is available? If the read size is
* larger than the buffer, then read some of the data
* directly into the user's buffer.
/* The buffer is empty OR we have already supplied the number of
* bytes requested in the read. Check if we need to read
* more from the file.
*/
if (count > buffer_available)
if (count > 0)
{
bytes_read = read(stream->fs_fd, dest, count);
if (bytes_read < 0)
size_t buffer_available;
/* We need to read more data into the buffer from the file */
/* Mark the buffer empty */
stream->fs_bufpos = stream->fs_bufread = stream->fs_bufstart;
/* How much space is available in the buffer? */
buffer_available = stream->fs_bufend - stream->fs_bufread;
/* Will the number of bytes that we need to read fit into
* the buffer space that is available? If the read size is
* larger than the buffer, then read some of the data
* directly into the user's buffer.
*/
if (count > buffer_available)
{
/* An error occurred on the read. The error code is
* in the 'errno' variable.
*/
goto errout_with_errno;
}
else if (bytes_read == 0)
{
/* We are at the end of the file. But we may already
* have buffered data. In that case, we will report
* the EOF indication later.
*/
goto shortread;
}
else
{
/* Some bytes were read. Adjust the dest pointer */
dest += bytes_read;
/* Were all of the requested bytes read? */
if ((size_t)bytes_read < count)
bytes_read = read(stream->fs_fd, dest, count);
if (bytes_read < 0)
{
/* No. We must be at the end of file. */
/* An error occurred on the read. The error code is
* in the 'errno' variable.
*/
goto errout_with_errno;
}
else if (bytes_read == 0)
{
/* We are at the end of the file. But we may already
* have buffered data. In that case, we will report
* the EOF indication later.
*/
goto shortread;
}
else
{
/* Yes. We are done. */
/* Some bytes were read. Adjust the dest pointer */
count = 0;
dest += bytes_read;
/* Were all of the requested bytes read? */
if ((size_t)bytes_read < count)
{
/* No. We must be at the end of file. */
goto shortread;
}
else
{
/* Yes. We are done. */
count = 0;
}
}
}
}
else
{
/* The number of bytes required to satisfy the read
* is less than or equal to the size of the buffer
* space that we have left. Read as much as we can
* into the buffer.
*/
bytes_read = read(stream->fs_fd, stream->fs_bufread, buffer_available);
if (bytes_read < 0)
{
/* An error occurred on the read. The error code is
* in the 'errno' variable.
*/
goto errout_with_errno;
}
else if (bytes_read == 0)
{
/* We are at the end of the file. But we may already
* have buffered data. In that case, we will report
* the EOF indication later.
*/
goto shortread;
}
else
{
/* Some bytes were read */
/* The number of bytes required to satisfy the read
* is less than or equal to the size of the buffer
* space that we have left. Read as much as we can
* into the buffer.
*/
stream->fs_bufread += bytes_read;
bytes_read = read(stream->fs_fd, stream->fs_bufread, buffer_available);
if (bytes_read < 0)
{
/* An error occurred on the read. The error code is
* in the 'errno' variable.
*/
goto errout_with_errno;
}
else if (bytes_read == 0)
{
/* We are at the end of the file. But we may already
* have buffered data. In that case, we will report
* the EOF indication later.
*/
goto shortread;
}
else
{
/* Some bytes were read */
stream->fs_bufread += bytes_read;
}
}
}
}
}
#else
/* Now get any other needed chars from the file. */
/* Now get any other needed chars from the file. */
while (count > 0)
{
bytes_read = read(stream->fs_fd, dest, count);
if (bytes_read < 0)
while (count > 0)
{
/* An error occurred on the read. The error code is
* in the 'errno' variable.
*/
bytes_read = read(stream->fs_fd, dest, count);
if (bytes_read < 0)
{
/* An error occurred on the read. The error code is
* in the 'errno' variable.
*/
goto errout_with_errno;
}
else if (bytes_read == 0)
{
/* We are at the end of the file. But we may already
* have buffered data. In that case, we will report
* the EOF indication later.
*/
goto errout_with_errno;
}
else if (bytes_read == 0)
{
/* We are at the end of the file. But we may already
* have buffered data. In that case, we will report
* the EOF indication later.
*/
break;
}
else
{
dest += bytes_read;
count -= bytes_read;
break;
}
else
{
dest += bytes_read;
count -= bytes_read;
}
}
}
#endif
/* Here after a successful (but perhaps short) read */
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
shortread:
#endif
bytes_read = dest - (FAR unsigned char *)ptr;
/* Set or clear the EOF indicator. If we get here because of a
+14 -3
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_libfwrite.c
*
* Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011, 2013-2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -57,12 +57,13 @@
****************************************************************************/
ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
{
FAR const unsigned char *start = ptr;
FAR const unsigned char *src = ptr;
ssize_t ret = ERROR;
unsigned char *dest;
int ret;
/* Make sure that writing to this stream is allowed */
@@ -72,12 +73,22 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
return ret;
}
/* Check if write access is permitted */
if ((stream->fs_oflags & O_WROK) == 0)
{
set_errno(EBADF);
goto errout;
}
/* If there is no I/O buffer, then output data immediately */
if (stream->fs_bufstart == NULL)
{
ret = write(stream->fs_fd, ptr, count);
goto errout;
}
/* Get exclusive access to the stream */
lib_take_semaphore(stream);
@@ -165,4 +176,4 @@ errout:
return ret;
}
#endif /* CONFIG_STDIO_BUFFER_SIZE */
#endif /* CONFIG_STDIO_DISABLE_BUFFERING */
+14 -4
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_rdflush.c
*
* Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2008, 2011, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -46,6 +46,8 @@
#include "libc.h"
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -59,15 +61,23 @@
*
****************************************************************************/
#if CONFIG_STDIO_BUFFER_SIZE > 0
int lib_rdflush(FAR FILE *stream)
{
if (!stream)
/* Sanity checking */
if (stream =- NULL)
{
set_errno(EBADF);
return ERROR;
}
/* Do nothing if there is no I/O buffer */
if (stream->fs_bufstart == NULL)
{
return OK;
}
/* Get exclusive access to the stream */
lib_take_semaphore(stream);
@@ -108,5 +118,5 @@ int lib_rdflush(FAR FILE *stream)
lib_give_semaphore(stream);
return OK;
}
#endif /* CONFIG_STDIO_BUFFER_SIZE */
#endif /* CONFIG_STDIO_DISABLE_BUFFERING */
+4 -25
View File
@@ -74,11 +74,6 @@
* by the setvbuf() function. The contents of the array at any time are
* unspecified.
*
* REVISIT: This initial version of setvbuf has some limitations and not
* all features features required by the specification are available.
* Specifically, this current implementation cannot support sisabling
* stream buffering if CONFIG_STDIO_BUFFER_SIZE > 0
*
* Parmeters:
* stream - the stream to flush
* buffer - the user allocate buffer. If NULL, will allocates a buffer of
@@ -95,7 +90,7 @@
int setvbuf(FAR FILE *stream, FAR char *buffer, int mode, size_t size)
{
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
FAR unsigned char *newbuf;
uint8_t flags;
int errcode;
@@ -127,18 +122,6 @@ int setvbuf(FAR FILE *stream, FAR char *buffer, int mode, size_t size)
goto errout;
}
#if 1 /* REVISIT: _IONBF not yet supported */
/* Not all features are be available. Without some additional logic,
* we cannot disable buffering if CONFIG_STDIO_BUFFER_SIZE > 0
*/
if (mode == _IONBF)
{
errcode = ENOSYS;
goto errout;
}
#endif
/* My assumption is that if size is zero for modes {_IOFBF, _IOLBF} the
* caller is only attempting to change the buffering mode. In this case,
* the existing buffer should be re-used (if there is one). If there is no
@@ -149,7 +132,7 @@ int setvbuf(FAR FILE *stream, FAR char *buffer, int mode, size_t size)
if ((mode == _IOFBF || mode == _IOLBF) && size == 0 &&
stream->fs_bufstart == NULL)
{
size = CONFIG_STDIO_BUFFER_SIZE;
size = BUFSIZE;
}
/* Make sure that we have exclusive access to the stream */
@@ -186,11 +169,7 @@ int setvbuf(FAR FILE *stream, FAR char *buffer, int mode, size_t size)
* successful.
*/
#if 1 /* REVISIT: _IONBF not yet supported */
flags = stream->fs_flags & ~(__FS_FLAG_LBF | __FS_FLAG_UBF);
#else
flags = stream->fs_flags & ~(__FS_FLAG_LBF | __FS_FLAG_NBF | __FS_FLAG_UBF);
#endif
/* Allocate a new buffer if one is needed or reuse the existing buffer it
* is appropriate to do so.
@@ -247,14 +226,12 @@ int setvbuf(FAR FILE *stream, FAR char *buffer, int mode, size_t size)
break;
case _IONBF:
#if 0 /* REVISIT: _IONBF not yet supported */
/* No buffer needed... We must be performing unbuffered I/O */
DEBUGASSERT(size == 0);
newbuf = NULL;
flags |= __FS_FLAG_NBF;
break;
#endif
default:
PANIC();
@@ -299,3 +276,5 @@ errout:
return ERROR;
#endif
}
#endif /* !CONFIG_STDIO_DISABLE_BUFFERING */
+16 -4
View File
@@ -82,11 +82,23 @@ static void stdoutstream_putc(FAR struct lib_outstream_s *this, int ch)
* Name: stdoutstream_flush
****************************************************************************/
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
static int stdoutstream_flush(FAR struct lib_outstream_s *this)
{
FAR struct lib_stdoutstream_s *sthis = (FAR struct lib_stdoutstream_s *)this;
return lib_fflush(sthis->stream, true);
FAR struct file *stream;
DEBUGASSERT(sthis != NULL && sthis->stream != NULL);
stream = sthis->stream;
if (stream->fs_bufstart != NULL)
{
return lib_fflush(sthis->stream, true);
}
else
{
return OK;
}
}
#endif
@@ -125,8 +137,8 @@ void lib_stdoutstream(FAR struct lib_stdoutstream_s *outstream,
* meaning.
*/
#if CONFIG_STDIO_BUFFER_SIZE > 0
if ((stream->fs_oflags & O_BINARY) == 0)
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
if (stream->fs_bufstart != NULL && (stream->fs_oflags & O_BINARY) == 0)
{
outstream->public.flush = stdoutstream_flush;
}
+17 -5
View File
@@ -82,11 +82,23 @@ static void stdsostream_putc(FAR struct lib_sostream_s *this, int ch)
* Name: stdsostream_flush
****************************************************************************/
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
static int stdsostream_flush(FAR struct lib_sostream_s *this)
{
FAR struct lib_stdsostream_s *sthis = (FAR struct lib_stdsostream_s *)this;
return lib_fflush(sthis->stream, true);
FAR struct lib_stdsostream_s *sthis = (FAR struct lib_stdoutstream_s *)this;
FAR struct file *stream;
DEBUGASSERT(sthis != NULL && sthis->stream != NULL);
stream = sthis->stream;
if (stream->fs_bufstart != NULL)
{
return lib_fflush(sthis->stream, true);
}
else
{
return OK;
}
}
#endif
@@ -138,8 +150,8 @@ void lib_stdsostream(FAR struct lib_stdsostream_s *outstream,
* meaning.
*/
#if CONFIG_STDIO_BUFFER_SIZE > 0
if ((stream->fs_oflags & O_BINARY) == 0)
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
if (stream->fs_bufstart != NULL && (stream->fs_oflags & O_BINARY) == 0)
{
outstream->public.flush = stdsostream_flush;
}
+11 -3
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_wrflush.c
*
* Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2011-2012, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -60,16 +60,23 @@
int lib_wrflush(FAR FILE *stream)
{
#if CONFIG_STDIO_BUFFER_SIZE > 0
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/* Verify that we were passed a valid (i.e., non-NULL) stream */
#ifdef CONFIG_DEBUG_FEATURES
if (!stream)
if (stream == NULL)
{
return -EINVAL;
}
#endif
/* Do nothing if there is no I/O buffer */
if (stream->fs_bufstart == NULL)
{
return OK;
}
/* Verify that the stream is opened for writing... lib_fflush will
* return an error if it is called for a stream that is not opened for
* writing. Check that first so that this function will not fail in
@@ -91,6 +98,7 @@ int lib_wrflush(FAR FILE *stream)
*/
return lib_fflush(stream, true);
#else
/* Verify that we were passed a valid (i.e., non-NULL) stream */