nsh: Accept the command line arguments like sh

Usage: nsh [<script-path>|-c <command>]

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: Ifb76b27e7fd09d26b1f6e48c391fed0972018041
This commit is contained in:
Xiang Xiao
2020-08-17 18:28:50 +08:00
committed by David Sidrane
parent 78e8090842
commit 9d80399bd5
14 changed files with 203 additions and 182 deletions

View File

@@ -191,7 +191,7 @@ static int nxterm_task(int argc, char **argv)
/* If the console front end is selected, then run it on this thread */
#ifdef CONFIG_NSH_CONSOLE
nsh_consolemain(0, NULL);
nsh_consolemain(argc, argv);
#endif
printf("nxterm_task: Unlinking the NX console device\n");

View File

@@ -384,7 +384,7 @@ int main(int argc, FAR char *argv[])
pid = task_create("NSH Console", CONFIG_EXAMPLES_PTYTEST_DAEMONPRIO,
CONFIG_EXAMPLES_PTYTEST_STACKSIZE, nsh_consolemain,
NULL);
argv);
if (pid < 0)
{
/* Can't do output because stdout and stderr are redirected */

View File

@@ -48,6 +48,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Tab completion cannot be supported if there is no console echo */
#ifndef CONFIG_READLINE_ECHO

View File

@@ -850,7 +850,8 @@ int nsh_loginscript(FAR struct nsh_vtbl_s *vtbl);
/* Basic session and message handling */
struct console_stdio_s;
int nsh_session(FAR struct console_stdio_s *pstate, bool login);
int nsh_session(FAR struct console_stdio_s *pstate,
bool login, int argc, FAR char *argv[]);
int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
/****************************************************************************

View File

@@ -325,7 +325,7 @@ int nsh_consolemain(int argc, FAR char *argv[])
/* Execute the session */
nsh_session(pstate, true);
nsh_session(pstate, true, argc, argv);
/* We lost the connection. Wait for the keyboard to
* be re-connected.

View File

@@ -1,7 +1,8 @@
/****************************************************************************
* apps/nshlib/nsh_console.c
*
* Copyright (C) 2007-2009, 2011-2013, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011-2013, 2015 Gregory Nutt.
* All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -181,7 +182,7 @@ static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl,
if (nsh_openifnotopen(pstate) != 0)
{
return (ssize_t)ERROR;
return ERROR;
}
/* Write the data to the output stream */

View File

@@ -52,6 +52,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Method access macros */
#define nsh_clone(v) (v)->clone(v)
@@ -70,8 +71,9 @@
# define nsh_output vtbl->output
#endif
/* Size of info to be saved in call to nsh_redirect */
/* See struct serialsave_s in nsh_console.c */
/* Size of info to be saved in call to nsh_redirect
* See struct serialsave_s in nsh_console.c
*/
#define SAVE_SIZE (2 * sizeof(int) + 2 * sizeof(FILE*))
@@ -107,6 +109,7 @@
/****************************************************************************
* Public Types
****************************************************************************/
/* This describes a generic console front-end */
struct nsh_vtbl_s
@@ -129,7 +132,7 @@ struct nsh_vtbl_s
FAR char *(*linebuffer)(FAR struct nsh_vtbl_s *vtbl);
void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save);
void (*undirect)(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save);
void (*exit)(FAR struct nsh_vtbl_s *vtbl, int exitstatus) noreturn_function;
void (*exit)(FAR struct nsh_vtbl_s *vtbl, int status) noreturn_function;
#ifdef NSH_HAVE_IOBUFFER
/* Common buffer for file I/O. */

View File

@@ -112,7 +112,7 @@ int nsh_consolemain(int argc, FAR char *argv[])
/* Execute the session */
ret = nsh_session(pstate, true);
ret = nsh_session(pstate, true, argc, argv);
/* Exit upon return */

View File

@@ -42,6 +42,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef CONFIG_NSH_CLE
# include "system/cle.h"
@@ -79,10 +80,11 @@
*
****************************************************************************/
int nsh_session(FAR struct console_stdio_s *pstate, bool login)
int nsh_session(FAR struct console_stdio_s *pstate,
bool login, int argc, FAR char *argv[])
{
FAR struct nsh_vtbl_s *vtbl;
int ret;
int ret = EXIT_FAILURE;
DEBUGASSERT(pstate);
vtbl = &pstate->cn_vtbl;
@@ -126,6 +128,8 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
#endif
}
if (argc < 2)
{
/* Then enter the command line parsing loop */
for (; ; )
@@ -138,14 +142,14 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
nsh_usbtrace();
#endif
/* Get the next line of input. readline() returns EOF on end-of-file
* or any read failure.
/* Get the next line of input. readline() returns EOF
* on end-of-file or any read failure.
*/
#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.
* 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, g_nshprompt, CONFIG_NSH_LINELEN,
@@ -162,8 +166,8 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
fputs(g_nshprompt, 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
/* 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.
*/
@@ -171,13 +175,14 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
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.
/* 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;
ret = EXIT_SUCCESS;
break;
}
#endif
@@ -186,10 +191,29 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
nsh_parse(vtbl, pstate->cn_line);
fflush(pstate->cn_outstream);
}
/* We do not get here, but this is necessary to keep some compilers happy.
* But others will complain that this code is not reachable.
*/
return EXIT_SUCCESS;
}
else if (strcmp(argv[1], "-h") == 0)
{
ret = nsh_output(vtbl, "Usage: %s [<script-path>|-c <command>]\n",
argv[0]);
}
else if (strcmp(argv[1], "-c") != 0)
{
#if defined(CONFIG_NFILE_STREAMS) && !defined(CONFIG_NSH_DISABLESCRIPT)
/* Execute the shell script */
ret = nsh_script(vtbl, argv[0], argv[1]);
#endif
}
else if (argc >= 3)
{
/* Parse process the command */
ret = nsh_parse(vtbl, argv[2]);
#ifdef CONFIG_NFILE_STREAMS
fflush(pstate->cn_outstream);
#endif
}
return ret;
}

View File

@@ -41,6 +41,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef CONFIG_NSH_CLE
# include "system/cle.h"
@@ -71,15 +72,13 @@
* Input Parameters:
* pstate - Abstracts the underlying session.
*
* Returned Values:
* EXIT_SUCCESS only
*
****************************************************************************/
int nsh_session(FAR struct console_stdio_s *pstate, bool login)
int nsh_session(FAR struct console_stdio_s *pstate,
bool login, int argc, FAR char *argv[])
{
FAR struct nsh_vtbl_s *vtbl;
int ret;
int ret = EXIT_FAILURE;
DEBUGASSERT(pstate);
vtbl = &pstate->cn_vtbl;
@@ -116,6 +115,8 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
#endif
}
if (argc < 2)
{
/* Then enter the command line parsing loop */
for (; ; )
@@ -132,36 +133,38 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
#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.
* 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, g_nshprompt, CONFIG_NSH_LINELEN,
stdin, stdout);
if (ret < 0)
{
printf(g_fmtcmdfailed, "nsh_session", "cle", NSH_ERRNO_OF(-ret));
return EXIT_SUCCESS;
printf(g_fmtcmdfailed,
"nsh_session", "cle", NSH_ERRNO_OF(-ret));
continue;
}
#else
/* Display the prompt string */
printf("%s", g_nshprompt);
/* 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.
/* 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.
/* 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;
ret = EXIT_SUCCESS;
break;
}
#endif
@@ -169,10 +172,29 @@ int nsh_session(FAR struct console_stdio_s *pstate, bool login)
nsh_parse(vtbl, pstate->cn_line);
}
/* We do not get here, but this is necessary to keep some compilers happy.
* But others will complain that this code is not reachable.
*/
return EXIT_SUCCESS;
}
else if (strcmp(argv[1], "-h") == 0)
{
ret = nsh_output(vtbl, "Usage: %s [<script-path>|-c <command>]\n",
argv[0]);
}
else if (strcmp(argv[1], "-c") != 0)
{
#if defined(CONFIG_NFILE_STREAMS) && !defined(CONFIG_NSH_DISABLESCRIPT)
/* Execute the shell script */
ret = nsh_script(vtbl, argv[0], argv[1]);
#endif
}
else if (argc >= 3)
{
/* Parse process the command */
ret = nsh_parse(vtbl, argv[2]);
#ifdef CONFIG_NFILE_STREAMS
fflush(pstate->cn_outstream);
#endif
}
return ret;
}

View File

@@ -73,40 +73,13 @@
int nsh_system(int argc, FAR char *argv[])
{
FAR struct console_stdio_s *pstate = nsh_newconsole();
FAR struct nsh_vtbl_s *vtbl;
int ret = EXIT_FAILURE;
int ret;
DEBUGASSERT(pstate != NULL);
vtbl = &pstate->cn_vtbl;
if (argc < 2)
{
/* Execute the interactive shell */
/* Execute the session */
ret = nsh_session(pstate, false);
}
else if (strcmp(argv[1], "-h") == 0)
{
ret = nsh_output(vtbl, "Usage: %s [<script-path>|-c <command>]\n",
argv[0]);
}
else if (strcmp(argv[1], "-c") != 0)
{
#if CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT)
/* Execute the shell script */
ret = nsh_script(vtbl, argv[0], argv[1]);
#endif
}
else if (argc >= 3)
{
/* Parse process the command */
ret = nsh_parse(vtbl, argv[2]);
#if CONFIG_NFILE_STREAMS > 0
fflush(pstate->cn_outstream);
#endif
}
ret = nsh_session(pstate, false, argc, argv);
/* Exit upon return */

View File

@@ -99,6 +99,7 @@ static inline int date_month(FAR const char *abbrev)
return i;
}
}
return ERROR;
}
#endif
@@ -108,7 +109,8 @@ static inline int date_month(FAR const char *abbrev)
****************************************************************************/
#ifndef CONFIG_NSH_DISABLE_DATE
static inline int date_showtime(FAR struct nsh_vtbl_s *vtbl, FAR const char *name)
static inline int date_showtime(FAR struct nsh_vtbl_s *vtbl,
FAR const char *name)
{
static const char format[] = "%a, %b %d %H:%M:%S %Y";
struct timespec ts;
@@ -152,8 +154,8 @@ static inline int date_showtime(FAR struct nsh_vtbl_s *vtbl, FAR const char *nam
****************************************************************************/
#ifndef CONFIG_NSH_DISABLE_DATE
static inline int date_settime(FAR struct nsh_vtbl_s *vtbl, FAR const char *name,
FAR char *newtime)
static inline int date_settime(FAR struct nsh_vtbl_s *vtbl,
FAR const char *name, FAR char *newtime)
{
struct timespec ts;
struct tm tm;
@@ -165,6 +167,7 @@ static inline int date_settime(FAR struct nsh_vtbl_s *vtbl, FAR const char *name
memset(&tm, 0, sizeof(tm));
/* Only this date format is supported: MMM DD HH:MM:SS YYYY */
/* Get the month abbreviation */
token = strtok_r(newtime, " \t", &saveptr);
@@ -179,7 +182,9 @@ static inline int date_settime(FAR struct nsh_vtbl_s *vtbl, FAR const char *name
goto errout_bad_parm;
}
/* Get the day of the month. NOTE: Accepts day-of-month up to 31 for all months */
/* Get the day of the month.
* NOTE: Accepts day-of-month up to 31 for all months
*/
token = strtok_r(NULL, " \t", &saveptr);
if (token == NULL)
@@ -330,7 +335,8 @@ int cmd_time(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
ret = clock_gettime(TIME_CLOCK, &end);
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "clock_gettime", NSH_ERRNO);
nsh_error(vtbl, g_fmtcmdfailed,
argv[0], "clock_gettime", NSH_ERRNO);
ret = ERROR;
}
else
@@ -370,7 +376,6 @@ int cmd_date(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
FAR char *newtime = NULL;
FAR const char *errfmt;
bool badarg = false;
int option;
int ret;
@@ -385,20 +390,11 @@ int cmd_date(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
newtime = optarg;
}
else /* option = '?' */
{
/* We need to parse to the end anyway so that getopt stays healthy */
badarg = true;
}
}
/* If a bad argument was encountered then exit with an error */
if (badarg)
{
errfmt = g_fmtarginvalid;
goto errout;
}
}
/* optind < argc-1 means that there are additional, unexpected arguments on
* th command-line

View File

@@ -346,7 +346,7 @@ int nsh_consolemain(int argc, FAR char *argv[])
/* Execute the session */
nsh_session(pstate, true);
nsh_session(pstate, true, argc, argv);
/* Switch to /dev/null because we probably no longer have a
* valid console device.

View File

@@ -165,7 +165,7 @@ int main(int argc, FAR char *argv[])
#ifdef CONFIG_NSH_CONSOLE
/* If the serial console front end is selected, run it on this thread */
ret = nsh_consolemain(0, NULL);
ret = nsh_consolemain(argc, argv);
/* nsh_consolemain() should not return. So if we get here, something
* is wrong.