diff --git a/include/nuttx/streams.h b/include/nuttx/streams.h index 8b63e8cd4c7..d10ad464009 100644 --- a/include/nuttx/streams.h +++ b/include/nuttx/streams.h @@ -39,6 +39,8 @@ typedef CODE int (*lib_getc_t)(FAR struct lib_instream_s *this); struct lib_outstream_s; typedef CODE void (*lib_putc_t)(FAR struct lib_outstream_s *this, int ch); +typedef CODE int (*lib_puts_t)(FAR struct lib_outstream_s *this, + FAR const void *buf, int len); typedef CODE int (*lib_flush_t)(FAR struct lib_outstream_s *this); struct lib_instream_s @@ -51,6 +53,7 @@ struct lib_instream_s struct lib_outstream_s { lib_putc_t put; /* Put one character to the outstream */ + lib_puts_t puts; /* Writes the string to the outstream */ lib_flush_t flush; /* Flush any buffered characters in the outstream */ int nput; /* Total number of characters put. Written * by put method, readable by user */ diff --git a/libs/libc/stdio/lib_memoutstream.c b/libs/libc/stdio/lib_memoutstream.c index 2fba9b00f2c..d035eb28619 100644 --- a/libs/libc/stdio/lib_memoutstream.c +++ b/libs/libc/stdio/lib_memoutstream.c @@ -31,13 +31,15 @@ ****************************************************************************/ /**************************************************************************** - * Name: memoutstream_putc + * Name: memoutstream_puts ****************************************************************************/ -static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch) +static int memoutstream_puts(FAR struct lib_outstream_s *this, + FAR const void *buf, int len) { FAR struct lib_memoutstream_s *mthis = (FAR struct lib_memoutstream_s *)this; + int ncopy; DEBUGASSERT(this); @@ -46,12 +48,26 @@ static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch) * created so it is okay to write past the end of the buflen by one. */ - if (this->nput < mthis->buflen) + ncopy = mthis->buflen - this->nput >= len ? + len : mthis->buflen - this->nput; + if (ncopy > 0) { - mthis->buffer[this->nput] = ch; - this->nput++; + memcpy(mthis->buffer + this->nput, buf, ncopy); + this->nput += ncopy; mthis->buffer[this->nput] = '\0'; } + + return ncopy; +} + +/**************************************************************************** + * Name: memoutstream_putc + ****************************************************************************/ + +static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + char tmp = ch; + (void)memoutstream_puts(this, &tmp, 1); } /**************************************************************************** @@ -79,6 +95,7 @@ void lib_memoutstream(FAR struct lib_memoutstream_s *outstream, FAR char *bufstart, int buflen) { outstream->public.put = memoutstream_putc; + outstream->public.puts = memoutstream_puts; outstream->public.flush = lib_noflush; outstream->public.nput = 0; /* Will be buffer index */ outstream->buffer = bufstart; /* Start of buffer */ diff --git a/libs/libc/stdio/lib_rawsostream.c b/libs/libc/stdio/lib_rawsostream.c index e584900017c..9af34ad923b 100644 --- a/libs/libc/stdio/lib_rawsostream.c +++ b/libs/libc/stdio/lib_rawsostream.c @@ -36,42 +36,47 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: rawoutstream_puts + ****************************************************************************/ + +static int rawoutstream_puts(FAR struct lib_outstream_s *this, + FAR const void *buf, int len) +{ + FAR struct lib_rawoutstream_s *rthis = + (FAR struct lib_rawoutstream_s *)this; + int nwritten = 0; + int ret; + + while (1) + { + ret = _NX_WRITE(rthis->fd, (FAR const char *)buf + nwritten, + len - nwritten); + if (ret <= 0) + { + if (_NX_GETERRNO(ret) == EINTR) + { + continue; + } + + break; + } + + this->nput += ret; + nwritten += ret; + } + + return nwritten > 0 ? nwritten : ret; +} + /**************************************************************************** * Name: rawoutstream_putc ****************************************************************************/ static void rawoutstream_putc(FAR struct lib_outstream_s *this, int ch) { - FAR struct lib_rawoutstream_s *rthis = - (FAR struct lib_rawoutstream_s *)this; - char buffer = ch; - int nwritten; - int errcode; - - DEBUGASSERT(this && rthis->fd >= 0); - - /* Loop until the character is successfully transferred or until an - * irrecoverable error occurs. - */ - - do - { - nwritten = _NX_WRITE(rthis->fd, &buffer, 1); - if (nwritten == 1) - { - this->nput++; - return; - } - - /* The only expected error is EINTR, meaning that the write operation - * was awakened by a signal. Zero or values > 1 would not be valid - * return values from _NX_WRITE(). - */ - - errcode = _NX_GETERRNO(nwritten); - DEBUGASSERT(nwritten < 0); - } - while (errcode == EINTR); + char tmp = ch; + (void)rawoutstream_puts(this, &tmp, 1); } /**************************************************************************** @@ -98,6 +103,7 @@ static void rawoutstream_putc(FAR struct lib_outstream_s *this, int ch) void lib_rawoutstream(FAR struct lib_rawoutstream_s *outstream, int fd) { outstream->public.put = rawoutstream_putc; + outstream->public.puts = rawoutstream_puts; outstream->public.flush = lib_noflush; outstream->public.nput = 0; outstream->fd = fd; diff --git a/libs/libc/stdio/lib_stdoutstream.c b/libs/libc/stdio/lib_stdoutstream.c index beb4157b374..903acb216b2 100644 --- a/libs/libc/stdio/lib_stdoutstream.c +++ b/libs/libc/stdio/lib_stdoutstream.c @@ -32,36 +32,49 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: stdoutstream_puts + ****************************************************************************/ + +static int stdoutstream_puts(FAR struct lib_outstream_s *this, + FAR const void *buf, int len) +{ + FAR struct lib_stdoutstream_s *sthis = + (FAR struct lib_stdoutstream_s *)this; + int nwritten = 0; + int ret; + + DEBUGASSERT(this && sthis->stream); + + while (1) + { + ret = fwrite((FAR char *)buf + nwritten, + len - nwritten, 1, sthis->stream); + if (ret <= 0) + { + if (_NX_GETERRNO(ret) == EINTR) + { + continue; + } + + break; + } + + this->nput += ret; + nwritten += ret; + } + + return nwritten > 0 ? nwritten : ret; +} + /**************************************************************************** * Name: stdoutstream_putc ****************************************************************************/ static void stdoutstream_putc(FAR struct lib_outstream_s *this, int ch) { - FAR struct lib_stdoutstream_s *sthis = - (FAR struct lib_stdoutstream_s *)this; - int result; - - DEBUGASSERT(this && sthis->stream); - - /* Loop until the character is successfully transferred or an irrecoverable - * error occurs. - */ - - do - { - result = fputc(ch, sthis->stream); - if (result != EOF) - { - this->nput++; - return; - } - - /* EINTR (meaning that fputc was interrupted by a signal) is the only - * recoverable error. - */ - } - while (get_errno() == EINTR); + char tmp = ch; + (void)stdoutstream_puts(this, &tmp, 1); } /**************************************************************************** @@ -105,7 +118,8 @@ void lib_stdoutstream(FAR struct lib_stdoutstream_s *outstream, { /* Select the put operation */ - outstream->public.put = stdoutstream_putc; + outstream->public.put = stdoutstream_putc; + outstream->public.puts = stdoutstream_puts; /* Select the correct flush operation. This flush is only called when * a newline is encountered in the output stream. However, we do not