From c5f9b8768e05d4af246a9e42dfc4da0d5b44e373 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 7 Jan 2014 16:27:45 -0600 Subject: [PATCH] Add type rsize_t and function gets_s() --- ChangeLog | 3 + TODO | 5 +- include/stdio.h | 3 +- include/sys/types.h | 24 +++++++- libc/stdio/Make.defs | 30 +++++----- libc/stdio/lib_gets_s.c | 128 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 173 insertions(+), 20 deletions(-) create mode 100644 libc/stdio/lib_gets_s.c diff --git a/ChangeLog b/ChangeLog index 182d3d2874..7fa7fde76e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6383,4 +6383,7 @@ (2014-1-7). * arch/arm/src/a1x/a1x_serial.c: Correct handling of the BUSY interrupt (2014-1-7). + * include/sys/types.h: Add a bogus rsize_t type (2014-1-7). + * libc/stdio/lib_gets_s.c: Add a quick'n'dirty implementation of + gets_s() which replaces gets() in C11 (2014-1-7). diff --git a/TODO b/TODO index f24f043140..047c368f72 100644 --- a/TODO +++ b/TODO @@ -472,7 +472,10 @@ o Kernel Build sched/sched_removereadytorun.c. That would eliminate 59% of the syscalls." Status: Open Priority: Low-Medium. Right now, I do not know if these syscalls are a - real performance issue or not. + real performance issue or not. The above statistics were collected + from a an atypical application (the OS test), and does an excessive + amount of console output. There is probably no issue with more typical + embedded applications. Title: ARMv6/7-M SYSCALL PERFORMANCE IMPROVEMENT Description: Currently the code issues an SVCall to go from user- to kernel-mode diff --git a/include/stdio.h b/include/stdio.h index c250cffea0..6641b71303 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/stdio.h * - * Copyright (C) 2007-2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -124,6 +124,7 @@ int fsetpos(FAR FILE *stream, FAR fpos_t *pos); long ftell(FAR FILE *stream); size_t fwrite(FAR const void *ptr, size_t size, size_t n_items, FAR FILE *stream); FAR char *gets(FAR char *s); +FAR char *gets_s(FAR char *s, rsize_t n); int ungetc(int c, FAR FILE *stream); /* Operations on the stdout stream, buffers, paths, and the whole printf-family */ diff --git a/include/sys/types.h b/include/sys/types.h index 8a3f97d337..7b579744ac 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/sys/types.h * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -132,12 +132,30 @@ typedef unsigned int mode_t; */ #ifdef CONFIG_SMALL_MEMORY + +#define SIZE_MAX UINT16_MAX typedef uint16_t size_t; + +#define SSIZE_MAX INT16_MAX +#define SSIZE_MIN INT16_MIN typedef int16_t ssize_t; -#else + +#define RSIZE_MAX UINT16_MAX +typedef uint16_t rsize_t; + +#else /* CONFIG_SMALL_MEMORY */ + +#define SIZE_MAX UINT32_MAX typedef uint32_t size_t; + +#define SSIZE_MAX INT32_MAX +#define SSIZE_MIN INT32_MIN typedef int32_t ssize_t; -#endif + +#define RSIZE_MAX UINT32_MAX +typedef uint32_t rsize_t; + +#endif /* CONFIG_SMALL_MEMORY */ /* uid_t is used for user IDs * gid_t is used for group IDs. diff --git a/libc/stdio/Make.defs b/libc/stdio/Make.defs index f04dfb2157..2a6ea85636 100644 --- a/libc/stdio/Make.defs +++ b/libc/stdio/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # libc/stdio/Make.defs # -# Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2014 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -37,13 +37,13 @@ # This first group of C files do not depend on having file descriptors or # C streams. -CSRCS += lib_fileno.c lib_printf.c lib_syslog.c lib_lowsyslog.c \ - lib_sprintf.c lib_asprintf.c lib_snprintf.c lib_libsprintf.c \ - lib_vsprintf.c lib_avsprintf.c lib_vsnprintf.c lib_libvsprintf.c \ - lib_dprintf.c lib_vdprintf.c \ - lib_meminstream.c lib_memoutstream.c lib_lowinstream.c \ - lib_lowoutstream.c lib_zeroinstream.c lib_nullinstream.c \ - lib_nulloutstream.c lib_sscanf.c +CSRCS += lib_fileno.c lib_printf.c lib_syslog.c lib_lowsyslog.c +CSRCS += lib_sprintf.c lib_asprintf.c lib_snprintf.c lib_libsprintf.c +CSRCS += lib_vsprintf.c lib_avsprintf.c lib_vsnprintf.c lib_libvsprintf.c +CSRCS += lib_dprintf.c lib_vdprintf.c +CSRCS += lib_meminstream.c lib_memoutstream.c lib_lowinstream.c +CSRCS += lib_lowoutstream.c lib_zeroinstream.c lib_nullinstream.c +CSRCS += lib_nulloutstream.c lib_sscanf.c # The remaining sources files depend upon file descriptors @@ -55,13 +55,13 @@ CSRCS += lib_rawinstream.c lib_rawoutstream.c ifneq ($(CONFIG_NFILE_STREAMS),0) -CSRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c \ - lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c lib_fgets.c \ - lib_gets.c lib_fwrite.c lib_libfwrite.c lib_fflush.c \ - lib_libflushall.c lib_libfflush.c lib_rdflush.c lib_wrflush.c \ - lib_fputc.c lib_puts.c lib_fputs.c lib_ungetc.c lib_vprintf.c \ - lib_fprintf.c lib_vfprintf.c lib_stdinstream.c lib_stdoutstream.c \ - lib_perror.c lib_feof.c lib_ferror.c lib_clearerr.c +CSRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c +CSRCS += lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c lib_fgets.c +CSRCS += lib_gets_s.c lib_gets.c lib_fwrite.c lib_libfwrite.c lib_fflush.c +CSRCS += lib_libflushall.c lib_libfflush.c lib_rdflush.c lib_wrflush.c +CSRCS += lib_fputc.c lib_puts.c lib_fputs.c lib_ungetc.c lib_vprintf.c +CSRCS += lib_fprintf.c lib_vfprintf.c lib_stdinstream.c lib_stdoutstream.c +CSRCS += lib_perror.c lib_feof.c lib_ferror.c lib_clearerr.c endif endif diff --git a/libc/stdio/lib_gets_s.c b/libc/stdio/lib_gets_s.c new file mode 100644 index 0000000000..95816b0804 --- /dev/null +++ b/libc/stdio/lib_gets_s.c @@ -0,0 +1,128 @@ +/**************************************************************************** + * libc/stdio/lib_gets_s.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gets + * + * Description: + * gets() reads a line from stdin into the buffer pointed to by s until + * either a terminating newline or EOF, which it replaces with '\0'. Reads + * at most n-1 characters from stdin into the array pointed to by str until + * new-line character, end-of-file condition, or read error. A null + * character is written immediately after the last character read into the + * array, or to str[0] if no characters were read. + * + * If n is zero or is greater than RSIZE_MAX, a null character is written + * to str[0] but the function reads and discards characters from stdin + * until new-line character, end-of-file condition, or read error (not + * implemented). + * + * If n-1 characters have been read, continues reading and discarding the + * characters from stdin until new-line character, end-of-file condition, + * or read error (not implemented). + * + **************************************************************************/ + +FAR char *gets_s(FAR char *s, rsize_t n) +{ + /* gets is equivalent to fgets using stdin. So let fgets do most of the + * work. + */ + + FAR char *ret = fgets(s, n, stdin); + if (ret) + { + /* A subtle difference from fgets is that gets_s replaces end-of-line + * markers with null terminators. We will do that as a second step + * (with some loss in performance). + */ + + int len = strlen(ret); + if (len > 0 && ret[len-1] == '\n') + { + ret[len-1] = '\0'; + } + } + + return ret; +}