Flush buffer after newline in putc, fputc, and puts (but not fputs)

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3607 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-05-14 17:37:47 +00:00
parent 6e4aa998e8
commit a854f248b4
5 changed files with 64 additions and 18 deletions

20
TODO
View File

@ -1,4 +1,4 @@
NuttX TODO List (Last updated May 6, 2011)
NuttX TODO List (Last updated May 14, 2011)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
nuttx/
@ -12,7 +12,7 @@ nuttx/
(5) Binary loaders (binfmt/)
(15) Network (net/, drivers/net)
(2) USB (drivers/usbdev, drivers/usbhost)
(5) Libraries (lib/)
(6) Libraries (lib/)
(13) File system/Generic drivers (fs/, drivers/)
(1) Graphics subystem (graphics/)
(1) Pascal add-on (pcode/)
@ -371,6 +371,22 @@ o Libraries (lib/)
Priority: Low (unless you are using mixed C-buffered I/O with fgets and
fgetc, for example).
Description: if CONFIG_STDIO_LINEBUFFER is defined, then fputs() should flush
the buffer on each newline encountered in the input stream. At
present, it does not flush at all! This is because fputs() is
based on fwrite() which handles binary data.
I suppose one could easily check if the last character is '\n'
and then flush in fputs() for that case. But that is imperfect
logic. It would work for the most frequent cases like puts("abcdef\n")
but not in all cases. For example, puts("abc\ndef") should flush
"abc\n" to output but keep "def" buffered. I can't get that behavior
using lib_fwrite() to implement fputs() (unless lib_fwrite were
extended to handle binary or text data with newlines).
Status: Open
Priority: Low (unless you doing lots of puts or fputs output and the
current buffer handling does not meet your needs).
Description: Need some minimal termios support... at a minimum, enough to
switch between raw and "normal" modes to support behavior like
that needed for readline().

View File

@ -89,6 +89,18 @@ int fputc(int c, FAR FILE *stream)
unsigned char buf = (unsigned char)c;
if (lib_fwrite(&buf, 1, stream) > 0)
{
/* Flush the buffer if a newline is output */
#ifdef CONFIG_STDIO_LINEBUFFER
if (c == '\n')
{
int ret = lib_fflush(stream, true);
if (ret < 0)
{
return EOF;
}
}
#endif
return c;
}
else

View File

@ -108,19 +108,20 @@ int fputs(FAR const char *s, FAR FILE *stream)
ntowrite = strlen(s);
if (ntowrite == 0)
{
nput = 0;
}
{
nput = 0;
}
else
{
/* Write the string */
{
/* Write the string */
nwritten = lib_fwrite(s, ntowrite, stream);
if (nwritten > 0)
{
nput = nwritten;
}
}
nwritten = lib_fwrite(s, ntowrite, stream);
if (nwritten > 0)
{
nput = nwritten;
}
}
}
return nput;
}

View File

@ -1136,6 +1136,8 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap)
#ifdef CONFIG_STDIO_LINEBUFFER
if (*src == '\n')
{
/* Should return an error on a failure to flush */
(void)obj->flush(obj);
}
#endif

View File

@ -84,31 +84,46 @@
* Name: puts
*
* Description:
* puts() writes the string s and a trailing newline to
* stdout.
* puts() writes the string s and a trailing newline to stdout.
*
****************************************************************************/
int puts(FAR const char *s)
{
FILE *stream = stdout;
int nwritten;
int nput = EOF;
/* Write the string (the next two steps must be atomic) */
lib_take_semaphore(stdout);
lib_take_semaphore(stream);
/* Write the string without its trailing '\0' */
nwritten = fputs(s, stdout);
nwritten = fputs(s, stream);
if (nwritten > 0)
{
/* Followed by a newline */
char newline = '\n';
if (lib_fwrite(&newline, 1, stdout) > 0)
if (lib_fwrite(&newline, 1, stream) > 0)
{
nput = nwritten + 1;
/* Flush the buffer after the newline is output */
#ifdef CONFIG_STDIO_LINEBUFFER
{
int ret = lib_fflush(stream, true);
if (ret < 0)
{
nput = EOF;
}
}
#endif
}
}
lib_give_semaphore(stdout);
return nput;
}