apps/nshlib: Fix all places where cle() and readline() are used. readline() returns EOF on a failure. cle() returns a negated errno value. Checking only for EOF causes failues to be missed (and infinite loops ensuing).
This commit is contained in:
parent
891ea23356
commit
5cad41c973
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_login.c
|
* apps/nshlib/nsh_login.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2016, 2019 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
|
||||||
@ -171,16 +171,21 @@ int nsh_login(FAR struct console_stdio_s *pstate)
|
|||||||
fputs(g_userprompt, pstate->cn_outstream);
|
fputs(g_userprompt, pstate->cn_outstream);
|
||||||
fflush(pstate->cn_outstream);
|
fflush(pstate->cn_outstream);
|
||||||
|
|
||||||
|
username[0] = '\0';
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_CLE
|
#ifdef CONFIG_NSH_CLE
|
||||||
|
/* cle() returns a negated errno value on failure */
|
||||||
|
|
||||||
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
INSTREAM(pstate), OUTSTREAM(pstate));
|
INSTREAM(pstate), OUTSTREAM(pstate));
|
||||||
|
if (ret >= 0)
|
||||||
#else
|
#else
|
||||||
|
/* readline() returns EOF on 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));
|
||||||
#endif
|
|
||||||
|
|
||||||
username[0] = '\0';
|
|
||||||
if (ret != EOF)
|
if (ret != EOF)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Parse out the username */
|
/* Parse out the username */
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_session.c
|
* apps/nshlib/nsh_session.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011-2014, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011-2014, 2016, 2019 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
|
||||||
@ -142,33 +143,45 @@ int nsh_session(FAR struct console_stdio_s *pstate)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_CLE
|
#ifdef CONFIG_NSH_CLE
|
||||||
|
/* cle() normally returns the number of characters read, but will
|
||||||
|
* return a negated errno value on end of file or if an error occurs.
|
||||||
|
* Either will cause the session to terminate.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
INSTREAM(pstate), OUTSTREAM(pstate));
|
INSTREAM(pstate), OUTSTREAM(pstate));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session",
|
||||||
|
"cle", NSH_ERRNO_OF(-ret));
|
||||||
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
/* readline() normally returns the number of characters read, but will
|
||||||
|
* return EOF on end of file or if an error occurs. EOF
|
||||||
|
* will cause the session to terminate.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN,
|
ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
INSTREAM(pstate), OUTSTREAM(pstate));
|
INSTREAM(pstate), OUTSTREAM(pstate));
|
||||||
#endif
|
if (ret == EOF)
|
||||||
if (ret != EOF)
|
|
||||||
{
|
{
|
||||||
|
/* NOTE: readline() does not set the errno variable, but perhaps we
|
||||||
|
* will be lucky and it will still be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session",
|
||||||
|
"readline", NSH_ERRNO);
|
||||||
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Parse process the command */
|
/* Parse process the command */
|
||||||
|
|
||||||
(void)nsh_parse(vtbl, pstate->cn_line);
|
(void)nsh_parse(vtbl, pstate->cn_line);
|
||||||
fflush(pstate->cn_outstream);
|
fflush(pstate->cn_outstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Readline normally returns the number of characters read,
|
|
||||||
* but will return EOF on end of file or if an error occurs.
|
|
||||||
* EOF will cause the session to terminate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session",
|
|
||||||
"readline", NSH_ERRNO_OF(-ret));
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We do not get here, but this is necessary to keep some compilers happy.
|
/* We do not get here, but this is necessary to keep some compilers happy.
|
||||||
* But others will complain that this code is not reachable.
|
* But others will complain that this code is not reachable.
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_stdlogin.c
|
* apps/nshlib/nsh_stdlogin.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2016, 2019 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
|
||||||
@ -170,17 +170,22 @@ int nsh_stdlogin(FAR struct console_stdio_s *pstate)
|
|||||||
|
|
||||||
printf("%s", g_userprompt);
|
printf("%s", g_userprompt);
|
||||||
|
|
||||||
/* Get the reponse, handling all possible cases */
|
/* Get the response, handling all possible cases */
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_CLE
|
|
||||||
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
|
||||||
stdin, stdout);
|
|
||||||
#else
|
|
||||||
ret = std_readline(pstate->cn_line, CONFIG_NSH_LINELEN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
username[0] = '\0';
|
username[0] = '\0';
|
||||||
|
|
||||||
|
#ifdef CONFIG_NSH_CLE
|
||||||
|
/* cle() returns a negated errno value on failure */
|
||||||
|
|
||||||
|
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
|
stdin, stdout);
|
||||||
|
if (ret >= 0)
|
||||||
|
#else
|
||||||
|
/* readline() returns EOF on failure */
|
||||||
|
|
||||||
|
ret = std_readline(pstate->cn_line, CONFIG_NSH_LINELEN);
|
||||||
if (ret != EOF)
|
if (ret != EOF)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Parse out the username */
|
/* Parse out the username */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_stdsession.c
|
* apps/nshlib/nsh_stdsession.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2013-2014, 2016, 2019 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
|
||||||
@ -127,35 +127,45 @@ int nsh_session(FAR struct console_stdio_s *pstate)
|
|||||||
|
|
||||||
printf("%s", g_nshprompt);
|
printf("%s", g_nshprompt);
|
||||||
|
|
||||||
/* Get the next line of input. readline() returns EOF on end-of-file
|
/* Get the next line of input. */
|
||||||
* or any read failure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_CLE
|
#ifdef CONFIG_NSH_CLE
|
||||||
|
/* cle() normally returns the number of characters read, but will
|
||||||
|
* return a negated errno value on end of file or if an error occurs.
|
||||||
|
* Either will cause the session to terminate.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
stdin, stdout);
|
stdin, stdout);
|
||||||
#else
|
if (ret < 0)
|
||||||
ret = std_readline(pstate->cn_line, CONFIG_NSH_LINELEN);
|
|
||||||
#endif
|
|
||||||
if (ret != EOF)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
printf(g_fmtcmdfailed, "nsh_session", "cle", NSH_ERRNO_OF(-ret));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* readline () normally returns the number of characters read, but will
|
||||||
|
* return EOF on end of file or if an error occurs. Either will cause
|
||||||
|
* the session to terminate.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = std_readline(pstate->cn_line, CONFIG_NSH_LINELEN);
|
||||||
|
if (ret == EOF)
|
||||||
|
{
|
||||||
|
/* NOTE: readline() does not set the errno variable, but perhaps we
|
||||||
|
* will be lucky and it will still be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
printf(g_fmtcmdfailed, "nsh_session", "readline", NSH_ERRNO);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Parse process the command */
|
/* Parse process the command */
|
||||||
|
|
||||||
(void)nsh_parse(vtbl, pstate->cn_line);
|
(void)nsh_parse(vtbl, pstate->cn_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Readline normally returns the number of characters read,
|
|
||||||
* but will return EOF on end of file or if an error occurs.
|
|
||||||
* EOF will cause the session to terminate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(g_fmtcmdfailed, "nsh_session", "readline", NSH_ERRNO_OF(-ret));
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We do not get here, but this is necessary to keep some compilers happy.
|
/* We do not get here, but this is necessary to keep some compilers happy.
|
||||||
* But others will complain that this code is not reachable.
|
* But others will complain that this code is not reachable.
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_telnetd.c
|
* apps/nshlib/nsh_telnetd.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2013, 2016-2017 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2013, 2016-2017, 2019 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
|
||||||
@ -151,40 +152,54 @@ static int nsh_telnetmain(int argc, char *argv[])
|
|||||||
fflush(pstate->cn_outstream);
|
fflush(pstate->cn_outstream);
|
||||||
|
|
||||||
/* Get the next line of input from the Telnet client */
|
/* Get the next line of input from the Telnet client */
|
||||||
|
|
||||||
#ifdef CONFIG_TELNET_CHARACTER_MODE
|
#ifdef CONFIG_TELNET_CHARACTER_MODE
|
||||||
#ifdef CONFIG_NSH_CLE
|
#ifdef CONFIG_NSH_CLE
|
||||||
|
/* cle() returns a negated errno value on failure (errno is not set) */
|
||||||
|
|
||||||
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
ret = cle(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
INSTREAM(pstate), OUTSTREAM(pstate));
|
INSTREAM(pstate), OUTSTREAM(pstate));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_telnetmain",
|
||||||
|
"cle", NSH_ERRNO_OF(-ret));
|
||||||
|
nsh_exit(vtbl, 1);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
/* readline() returns EOF on failure (errno is not set) */
|
||||||
|
|
||||||
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 == EOF)
|
||||||
|
{
|
||||||
|
/* NOTE: readline() does not set the errno variable, but perhaps we
|
||||||
|
* will be lucky and it will still be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_telnetmain",
|
||||||
|
"readline", NSH_ERRNO);
|
||||||
|
nsh_exit(vtbl, 1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
/* fgets() returns NULL on failure (errno will be set) */
|
||||||
|
|
||||||
if (fgets(pstate->cn_line, CONFIG_NSH_LINELEN,
|
if (fgets(pstate->cn_line, CONFIG_NSH_LINELEN,
|
||||||
INSTREAM(pstate)) != NULL)
|
INSTREAM(pstate)) == NULL)
|
||||||
{
|
{
|
||||||
|
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_telnetmain",
|
||||||
|
"fgets", NSH_ERRNO);
|
||||||
|
nsh_exit(vtbl, 1);
|
||||||
|
}
|
||||||
|
|
||||||
ret = strlen(pstate->cn_line);
|
ret = strlen(pstate->cn_line);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = EOF;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret != EOF)
|
|
||||||
{
|
|
||||||
/* Parse process the received Telnet command */
|
/* Parse process the received Telnet command */
|
||||||
|
|
||||||
(void)nsh_parse(vtbl, pstate->cn_line);
|
(void)nsh_parse(vtbl, pstate->cn_line);
|
||||||
fflush(pstate->cn_outstream);
|
fflush(pstate->cn_outstream);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_telnetmain",
|
|
||||||
"cle/readline/fgets", NSH_ERRNO);
|
|
||||||
nsh_exit(vtbl, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user