Fix a readline bug. If a NUL is received, it would return end-of-file

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5633 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2013-02-10 00:46:27 +00:00
parent b8c07cfa53
commit 142c478747
8 changed files with 37 additions and 30 deletions

View File

@@ -517,3 +517,8 @@
match NuttX name change. match NuttX name change.
* apps/examples/ostest/restart.c: Add a test case to verify * apps/examples/ostest/restart.c: Add a test case to verify
task_restart(). task_restart().
* apps/system/readline.c: readline() now returns EOF on any failure
(instead of a negated errno value). This is because the underlying
read is based on logic similar to getc. The value zero was being
confused with a NUL. So if a NUL was received, the NSH session
would terminate because it thought it was the end of file.

View File

@@ -6,6 +6,7 @@
config EXAMPLES_CDCACM config EXAMPLES_CDCACM
bool "CDC/ACM example" bool "CDC/ACM example"
default n default n
depends on CDCACM
---help--- ---help---
Enable the USB CDC/ACM class driver example Enable the USB CDC/ACM class driver example

View File

@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* examples/ftpc/ftpc_main.c * examples/ftpc/ftpc_main.c
* *
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -431,14 +431,13 @@ int ftpc_main(int argc, char **argv, char **envp)
ret = readline(g_line, CONFIG_FTPC_LINELEN, stdin, stdout); ret = readline(g_line, CONFIG_FTPC_LINELEN, stdin, stdout);
/* Readline normally returns the number of characters read, /* Readline normally returns the number of characters read,
* but will return 0 on end of file or a negative value * but will return EOF on end of file or if an error occurs.
* if an error occurs. Either will cause the session to * Either will cause the session to terminate.
* terminate.
*/ */
if (ret <= 0) if (ret == EOF)
{ {
printf("ERROR: readline failed: %d\n", ret); printf("ERROR: readline failed: %d\n", errno);
return 1; return 1;
} }
#endif #endif

View File

@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* examples/usbterm/usbterm_main.c * examples/usbterm/usbterm_main.c
* *
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -325,12 +325,11 @@ int usbterm_main(int argc, char *argv[])
ret = readline(g_usbterm.outbuffer, CONFIG_EXAMPLES_USBTERM_BUFLEN, stdin, stdout); ret = readline(g_usbterm.outbuffer, CONFIG_EXAMPLES_USBTERM_BUFLEN, stdin, stdout);
/* Readline normally returns the number of characters read, /* Readline normally returns the number of characters read,
* but will return 0 on end of file or a negative value * but will return EOF on end of file or if an error occurs. Either
* if an error occurs. Either will cause the session to * will cause the session to terminate.
* terminate.
*/ */
if (ret <= 0) if (ret == EOF)
{ {
printf("ERROR: readline failed: %d\n", ret); printf("ERROR: readline failed: %d\n", ret);
return 1; return 1;

View File

@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* apps/include/readline.h * apps/include/readline.h
* *
* Copyright (C) 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -85,8 +85,8 @@ extern "C" {
* *
* Returned values: * Returned values:
* On success, the (positive) number of bytes transferred is returned. * On success, the (positive) number of bytes transferred is returned.
* A length of zero would indicated an end of file condition. An failure, * EOF is returned to indicate either an end of file condition or a
* a negated errno value is returned. * failure.
* *
**************************************************************************/ **************************************************************************/

View File

@@ -42,8 +42,6 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <apps/readline.h>
#include "nsh.h" #include "nsh.h"
#include "nsh_console.h" #include "nsh_console.h"

View File

@@ -129,11 +129,13 @@ int nsh_session(FAR struct console_stdio_s *pstate)
fputs(g_nshprompt, pstate->cn_outstream); fputs(g_nshprompt, pstate->cn_outstream);
fflush(pstate->cn_outstream); fflush(pstate->cn_outstream);
/* Get the next line of input */ /* Get the next line of input. readline() returns EOF on end-of-file
* or any read failure.
*/
ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN, ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN,
INSTREAM(pstate), OUTSTREAM(pstate)); INSTREAM(pstate), OUTSTREAM(pstate));
if (ret > 0) if (ret != EOF)
{ {
/* Parse process the command */ /* Parse process the command */
@@ -142,9 +144,8 @@ int nsh_session(FAR struct console_stdio_s *pstate)
} }
/* Readline normally returns the number of characters read, /* Readline normally returns the number of characters read,
* but will return 0 on end of file or a negative value * but will return EOF on end of file or if an error occurs.
* if an error occurs. Either will cause the session to * EOF will cause the session to terminate.
* terminate.
*/ */
else else

View File

@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* apps/system/readline/readline.c * apps/system/readline/readline.c
* *
* Copyright (C) 2007-2008, 2011-2012 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2008, 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -136,9 +136,9 @@ static inline int readline_rawgetc(int infd)
if (nread == 0) if (nread == 0)
{ {
/* Return zero on end-of-file */ /* Return EOF on end-of-file */
return 0; return EOF;
} }
/* Check if an error occurred */ /* Check if an error occurred */
@@ -152,7 +152,9 @@ static inline int readline_rawgetc(int infd)
int errcode = errno; int errcode = errno;
if (errcode != EINTR) if (errcode != EINTR)
{ {
return -errcode; /* Return EOF on any errors that we cannot handle */
return EOF;
} }
} }
} }
@@ -233,8 +235,8 @@ static inline void readline_consolewrite(int outfd, FAR const char *buffer, size
* *
* Returned values: * Returned values:
* On success, the (positive) number of bytes transferred is returned. * On success, the (positive) number of bytes transferred is returned.
* A length of zero would indicate an end of file condition. On failure, * EOF is returned to indicate either an end of file condition or a
* a negated errno value is returned. * failure.
* *
**************************************************************************/ **************************************************************************/
@@ -281,13 +283,15 @@ ssize_t readline(FAR char *buf, int buflen, FILE *instream, FILE *outstream)
for(;;) for(;;)
{ {
/* Get the next character */ /* Get the next character. readline_rawgetc() returns EOF on any
* errors or at the end of file.
*/
int ch = readline_rawgetc(infd); int ch = readline_rawgetc(infd);
/* Check for end-of-file or read error */ /* Check for end-of-file or read error */
if (ch <= 0) if (ch == EOF)
{ {
/* Did we already received some data? */ /* Did we already received some data? */
@@ -302,7 +306,7 @@ ssize_t readline(FAR char *buf, int buflen, FILE *instream, FILE *outstream)
return nch; return nch;
} }
return ch; return EOF;
} }
/* Are we processing a VT100 escape sequence */ /* Are we processing a VT100 escape sequence */