Back quoted NSH arguments now functional
This commit is contained in:
parent
d499f287ad
commit
65b4921b23
@ -769,4 +769,6 @@
|
|||||||
* apps/nshlib/nsh_parse.c: Add initial support of commands enclosed
|
* apps/nshlib/nsh_parse.c: Add initial support of commands enclosed
|
||||||
in back quotes as command arguments. Functionality still incomplete
|
in back quotes as command arguments. Functionality still incomplete
|
||||||
on initial commit (2014-1-10).
|
on initial commit (2014-1-10).
|
||||||
|
* Logic to support commands enclosed in back quotes is functional
|
||||||
|
but not thoroughly tested (2014-1-11).
|
||||||
|
|
||||||
|
@ -277,11 +277,11 @@ config NSH_DISABLE_SEMICOLON
|
|||||||
command separated by a semicolon. You can disable this feature to
|
command separated by a semicolon. You can disable this feature to
|
||||||
save a little memory on FLASH challenged platforms.
|
save a little memory on FLASH challenged platforms.
|
||||||
|
|
||||||
config NSH_FUNCPARMS
|
config NSH_CMDPARMS
|
||||||
bool "Enable function parameters"
|
bool "Enable commands as parameters"
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
If selected, then the output from cmds, from file applications, and
|
If selected, then the output from commands, from file applications, and
|
||||||
from NSH built-in commands can be used as arguments to other
|
from NSH built-in commands can be used as arguments to other
|
||||||
commands. The entity to be executed is identified by enclosing the
|
commands. The entity to be executed is identified by enclosing the
|
||||||
command line in back quotes. For example,
|
command line in back quotes. For example,
|
||||||
@ -292,14 +292,15 @@ config NSH_FUNCPARMS
|
|||||||
environment variable BAR. The value of the environment variable FOO
|
environment variable BAR. The value of the environment variable FOO
|
||||||
is then set output of myprogram on stdout.
|
is then set output of myprogram on stdout.
|
||||||
|
|
||||||
This feature is disabled by default.
|
Because this feature commits significant resourse, it is disabled by
|
||||||
|
default.
|
||||||
|
|
||||||
config NSH_TMPDIR
|
config NSH_TMPDIR
|
||||||
string "Temporary file directory"
|
string "Temporary file directory"
|
||||||
default "/tmp"
|
default "/tmp"
|
||||||
depends on NSH_FUNCPARMS
|
depends on NSH_CMDPARMS
|
||||||
---help---
|
---help---
|
||||||
If NSH_FUNCPARMS is selected, then function output will be retained
|
If NSH_CMDPARMS is selected, then function output will be retained
|
||||||
in a temporary file. In that case, this string must be provided to
|
in a temporary file. In that case, this string must be provided to
|
||||||
specify the full path to a directory where temporary files can be
|
specify the full path to a directory where temporary files can be
|
||||||
created. This would be a good application of RAM disk: To provide
|
created. This would be a good application of RAM disk: To provide
|
||||||
@ -312,21 +313,21 @@ config NSH_MAXARGUMENTS
|
|||||||
The maximum number of NSH command arguments.
|
The maximum number of NSH command arguments.
|
||||||
Default: 6
|
Default: 6
|
||||||
|
|
||||||
config NSH_ENVCAT
|
config NSH_ARGCAT
|
||||||
bool "Concatenation of environment variables"
|
bool "Concatenation of argument strings"
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
Support concatenation of strings with environment variables. For
|
Support concatenation of strings with environment variables or command
|
||||||
example:
|
output. For example:
|
||||||
|
|
||||||
set FOO XYZ
|
set FOO XYZ
|
||||||
set BAR 123
|
set BAR 123
|
||||||
set FOOBAR ABC_${FOO}_${BAR}
|
set FOOBAR ABC_${FOO}_${BAR}
|
||||||
|
|
||||||
would set the environment variable FOO to XYZ, BAR to 123 and FOOBAR
|
would set the environment variable FOO to XYZ, BAR to 123 and FOOBAR
|
||||||
to ABC_XYZ_123. If NSH_ENV, then a slightly small FLASH footprint
|
to ABC_XYZ_123. If NSH_ARGCAT is not selected, then a slightly small
|
||||||
results but then also only simple environment variables like $FOO
|
FLASH footprint results but then also only simple environment
|
||||||
can be used on the command line.
|
variables like $FOO can be used on the command line.
|
||||||
|
|
||||||
config NSH_NESTDEPTH
|
config NSH_NESTDEPTH
|
||||||
int "Maximum command nesting"
|
int "Maximum command nesting"
|
||||||
|
@ -65,6 +65,30 @@ Command Overview
|
|||||||
Multiple commands per line. NSH will accept multiple commands per
|
Multiple commands per line. NSH will accept multiple commands per
|
||||||
command line with each command separated with the semi-colon character (;).
|
command line with each command separated with the semi-colon character (;).
|
||||||
|
|
||||||
|
If CONFIG_NSH_CMDPARMS is selected, then the output from commands, from
|
||||||
|
file applications, and from NSH built-in commands can be used as arguments
|
||||||
|
to other commands. The entity to be executed is identified by enclosing
|
||||||
|
the command line in back quotes. For example,
|
||||||
|
|
||||||
|
set FOO `myprogram $BAR`
|
||||||
|
|
||||||
|
Will execute the program named myprogram passing it the value of the
|
||||||
|
environment variable BAR. The value of the environment variable FOO
|
||||||
|
is then set output of myprogram on stdout. Because this feature commits
|
||||||
|
significant resources, it is disabled by default.
|
||||||
|
|
||||||
|
If CONFIG_NSH_ARGCAT is selected, the support concatenation of strings
|
||||||
|
with environment variables or command output. For example:
|
||||||
|
|
||||||
|
set FOO XYZ
|
||||||
|
set BAR 123
|
||||||
|
set FOOBAR ABC_${FOO}_${BAR}
|
||||||
|
|
||||||
|
would set the environment variable FOO to XYZ, BAR to 123 and FOOBAR
|
||||||
|
to ABC_XYZ_123. If NSH_ARGCAT is not selected, then a slightly small
|
||||||
|
FLASH footprint results but then also only simple environment
|
||||||
|
variables like $FOO can be used on the command line.
|
||||||
|
|
||||||
Conditional Command Execution
|
Conditional Command Execution
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -1007,6 +1031,42 @@ NSH-Specific Configuration Settings
|
|||||||
feature to save a little memory on FLASH challenged platforms.
|
feature to save a little memory on FLASH challenged platforms.
|
||||||
Default: n
|
Default: n
|
||||||
|
|
||||||
|
* CONFIG_NSH_CMDPARMS
|
||||||
|
If selected, then the output from commands, from file applications, and
|
||||||
|
from NSH built-in commands can be used as arguments to other
|
||||||
|
commands. The entity to be executed is identified by enclosing the
|
||||||
|
command line in back quotes. For example,
|
||||||
|
|
||||||
|
set FOO `myprogram $BAR`
|
||||||
|
|
||||||
|
Will execute the program named myprogram passing it the value of the
|
||||||
|
environment variable BAR. The value of the environment variable FOO
|
||||||
|
is then set output of myprogram on stdout. Because this feature commits
|
||||||
|
significant resources, it is disabled by default.
|
||||||
|
|
||||||
|
* CONFIG_NSH_TMPDIR
|
||||||
|
If CONFIG_NSH_CMDPARMS is selected, then function output will be retained
|
||||||
|
in a temporary file. In that case, this string must be provided to
|
||||||
|
specify the full path to a directory where temporary files can be
|
||||||
|
created. This would be a good application of RAM disk: To provide
|
||||||
|
temporary storage for function output.
|
||||||
|
|
||||||
|
* CONFIG_NSH_MAXARGUMENTS
|
||||||
|
The maximum number of NSH command arguments. Default: 6
|
||||||
|
|
||||||
|
* CONFIG_NSH_ARGCAT
|
||||||
|
Support concatenation of strings with environment variables or command
|
||||||
|
output. For example:
|
||||||
|
|
||||||
|
set FOO XYZ
|
||||||
|
set BAR 123
|
||||||
|
set FOOBAR ABC_${FOO}_${BAR}
|
||||||
|
|
||||||
|
would set the environment variable FOO to XYZ, BAR to 123 and FOOBAR
|
||||||
|
to ABC_XYZ_123. If NSH_ARGCAT is not selected, then a slightly small
|
||||||
|
FLASH footprint results but then also only simple environment
|
||||||
|
variables like $FOO can be used on the command line.
|
||||||
|
|
||||||
* CONFIG_NSH_NESTDEPTH
|
* CONFIG_NSH_NESTDEPTH
|
||||||
The maximum number of nested if-then[-else]-fi sequences that
|
The maximum number of nested if-then[-else]-fi sequences that
|
||||||
are permissable. Default: 3
|
are permissable. Default: 3
|
||||||
|
@ -72,14 +72,14 @@
|
|||||||
# undef CONFIG_NSH_TELNET
|
# undef CONFIG_NSH_TELNET
|
||||||
# undef CONFIG_NSH_FILE_APPS
|
# undef CONFIG_NSH_FILE_APPS
|
||||||
# undef CONFIG_NSH_TELNET
|
# undef CONFIG_NSH_TELNET
|
||||||
# undef CONFIG_NSH_FUNCPARMS
|
# undef CONFIG_NSH_CMDPARMS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If CONFIG_NSH_FUNCPARMS is selected, then the path to a directory to
|
/* If CONFIG_NSH_CMDPARMS is selected, then the path to a directory to
|
||||||
* hold temporary files must be provided.
|
* hold temporary files must be provided.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_NSH_FUNCPARMS) && !defined(CONFIG_NSH_TMPDIR)
|
#if defined(CONFIG_NSH_CMDPARMS) && !defined(CONFIG_NSH_TMPDIR)
|
||||||
# define CONFIG_NSH_TMPDIR "/tmp"
|
# define CONFIG_NSH_TMPDIR "/tmp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -173,7 +173,6 @@ static void dd_outfcloseblk(struct dd_s *dd)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: dd_outfclosech
|
* Name: dd_outfclosech
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -325,7 +324,7 @@ static int dd_readch(struct dd_s *dd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: dd_infopen
|
* Name: dd_filetype
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||||
@ -391,6 +390,7 @@ static inline int dd_infopen(const char *name, struct dd_s *dd)
|
|||||||
dd->infread = dd_readblk;
|
dd->infread = dd_readblk;
|
||||||
dd->infclose = dd_infcloseblk;
|
dd->infclose = dd_infcloseblk;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -403,6 +403,7 @@ static inline int dd_infopen(const char *name, struct dd_s *dd)
|
|||||||
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -450,6 +451,7 @@ static inline int dd_outfopen(const char *name, struct dd_s *dd)
|
|||||||
dd->outfwrite = dd_writech; /* Character oriented write */
|
dd->outfwrite = dd_writech; /* Character oriented write */
|
||||||
dd->outfclose = dd_outfclosech;
|
dd->outfclose = dd_outfclosech;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -461,6 +463,7 @@ static inline int dd_outfopen(const char *name, struct dd_s *dd)
|
|||||||
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
|
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -614,22 +617,27 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
dd.sector++;
|
dd.sector++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
errout_with_outf:
|
errout_with_outf:
|
||||||
DD_INCLOSE(&dd);
|
DD_INCLOSE(&dd);
|
||||||
|
|
||||||
errout_with_inf:
|
errout_with_inf:
|
||||||
DD_OUTCLOSE(&dd);
|
DD_OUTCLOSE(&dd);
|
||||||
free(dd.buffer);
|
free(dd.buffer);
|
||||||
|
|
||||||
errout_with_paths:
|
errout_with_paths:
|
||||||
if (infile)
|
if (infile)
|
||||||
{
|
{
|
||||||
free(infile);
|
free(infile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outfile)
|
if (outfile)
|
||||||
{
|
{
|
||||||
free(outfile);
|
free(outfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
|
# include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <apps/nsh.h>
|
#include <apps/nsh.h>
|
||||||
|
|
||||||
#include "nsh.h"
|
#include "nsh.h"
|
||||||
@ -53,6 +57,37 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
/* If CONFIG_NSH_CMDPARMS or CONFIG_NSH_ARGCAT is enabled, then we will need
|
||||||
|
* retain a list of memory allocations to be freed at the completion of
|
||||||
|
* command processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef HAVE_MEMLIST
|
||||||
|
#if defined(CONFIG_NSH_CMDPARMS) || defined(CONFIG_NSH_ARGCAT)
|
||||||
|
# define HAVE_MEMLIST 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_MEMLIST) && !defined(CONFIG_NSH_MAXALLOCS)
|
||||||
|
# ifdef CONFIG_NSH_ARGCAT
|
||||||
|
# define CONFIG_NSH_MAXALLOCS (2*CONFIG_NSH_MAXARGUMENTS)
|
||||||
|
# else
|
||||||
|
# define CONFIG_NSH_MAXALLOCS CONFIG_NSH_MAXARGUMENTS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allocation list helper macros */
|
||||||
|
|
||||||
|
#ifdef HAVE_MEMLIST
|
||||||
|
# define NSH_MEMLIST_TYPE struct nsh_memlist_s
|
||||||
|
# define NSH_MEMLIST_INIT(m) memset(&(m), 0, sizeof(struct nsh_memlist_s));
|
||||||
|
# define NSH_MEMLIST_ADD(m,a) nsh_memlist_add(m,a)
|
||||||
|
# define NSH_MEMLIST_FREE(m) nsh_memlist_free(m)
|
||||||
|
#else
|
||||||
|
# define NSH_MEMLIST_TYPE uint8_t
|
||||||
|
# define NSH_MEMLIST_INIT(m) do { (m) = 0; } while (0)
|
||||||
|
# define NSH_MEMLIST_ADD(m,a)
|
||||||
|
# define NSH_MEMLIST_FREE(m,a)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
@ -70,10 +105,26 @@ struct cmdarg_s
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This structure describes the allocation list */
|
||||||
|
|
||||||
|
#ifdef HAVE_MEMLIST
|
||||||
|
struct nsh_memlist_s
|
||||||
|
{
|
||||||
|
int nallocs; /* Number of allocations */
|
||||||
|
FAR char *allocations[CONFIG_NSH_MAXALLOCS];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_MEMLIST
|
||||||
|
static void nsh_memlist_add(FAR struct nsh_memlist_s *memlist,
|
||||||
|
FAR char *address);
|
||||||
|
static void nsh_memlist_free(FAR struct nsh_memlist_s *memlist);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
static void nsh_releaseargs(struct cmdarg_s *arg);
|
static void nsh_releaseargs(struct cmdarg_s *arg);
|
||||||
static pthread_addr_t nsh_child(pthread_addr_t arg);
|
static pthread_addr_t nsh_child(pthread_addr_t arg);
|
||||||
@ -85,20 +136,31 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result);
|
|||||||
static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
|
static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
|
||||||
int argc, FAR char *argv[], FAR const char *redirfile,
|
int argc, FAR char *argv[], FAR const char *redirfile,
|
||||||
int oflags);
|
int oflags);
|
||||||
static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr);
|
|
||||||
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
|
static FAR char *nsh_filecat(FAR struct nsh_vtbl_s *vtbl, FAR char *s1,
|
||||||
|
FAR const char *filename);
|
||||||
|
static FAR char *nsh_cmdparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
||||||
|
FAR char **allocation);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_NSH_ARGCAT
|
||||||
|
static int nsh_strcat(FAR char *s1, FAR const char *s2);
|
||||||
|
#endif
|
||||||
|
static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr,
|
||||||
|
FAR NSH_MEMLIST_TYPE *memlist);
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl);
|
static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl);
|
||||||
static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl,
|
static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **ppcmd, FAR char **saveptr);
|
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr);
|
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_FUNCPARMS
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
||||||
FAR const char *redirfile);
|
FAR const char *redirfile);
|
||||||
#endif
|
#endif
|
||||||
@ -172,6 +234,48 @@ const char g_fmtsignalrecvd[] = "nsh: %s: Interrupted by signal\n";
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_memlist_add
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_MEMLIST
|
||||||
|
static void nsh_memlist_add(FAR struct nsh_memlist_s *memlist,
|
||||||
|
FAR char *address)
|
||||||
|
{
|
||||||
|
if (memlist)
|
||||||
|
{
|
||||||
|
int index = memlist->nallocs;
|
||||||
|
if (index < CONFIG_NSH_MAXALLOCS)
|
||||||
|
{
|
||||||
|
memlist->allocations[index] = address;
|
||||||
|
memlist->nallocs = index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_memlist_free
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_MEMLIST
|
||||||
|
static void nsh_memlist_free(FAR struct nsh_memlist_s *memlist)
|
||||||
|
{
|
||||||
|
if (memlist)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for (index = 0; index < memlist->nallocs; index++)
|
||||||
|
{
|
||||||
|
free(memlist->allocations[index]);
|
||||||
|
memlist->allocations[index] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memlist->nallocs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nsh_releaseargs
|
* Name: nsh_releaseargs
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -204,6 +308,7 @@ static void nsh_releaseargs(struct cmdarg_s *arg)
|
|||||||
{
|
{
|
||||||
free(arg->argv[i]);
|
free(arg->argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(arg);
|
free(arg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -558,15 +663,202 @@ errout:
|
|||||||
return nsh_saveresult(vtbl, true);
|
return nsh_saveresult(vtbl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_filecat
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
|
static FAR char *nsh_filecat(FAR struct nsh_vtbl_s *vtbl, FAR char *s1,
|
||||||
|
FAR const char *filename)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
size_t s1size = 0;
|
||||||
|
size_t allocsize;
|
||||||
|
ssize_t nbytesread;
|
||||||
|
FAR char *argument;
|
||||||
|
int index;
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Get the size of the string */
|
||||||
|
|
||||||
|
if (s1)
|
||||||
|
{
|
||||||
|
s1size = (size_t)strlen(s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the size of file */
|
||||||
|
|
||||||
|
ret = stat(filename, &buf);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdfailed, "``", "stat", NSH_ERRNO);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the total allocation size */
|
||||||
|
|
||||||
|
allocsize = s1size + (size_t)buf.st_size + 1;
|
||||||
|
argument = (FAR char *)realloc(s1, allocsize);
|
||||||
|
if (!argument)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdoutofmemory, "``");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the source file for reading */
|
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdfailed, "``", "open", NSH_ERRNO);
|
||||||
|
goto errout_with_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now copy the file. Loop until the entire file has been transferred to
|
||||||
|
* the allocated string (after the original contents of s1size bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (index = s1size; index < allocsize - 1; )
|
||||||
|
{
|
||||||
|
/* Loop until we successfully read something , we encounter the
|
||||||
|
* end-of-file, or until a read error occurs
|
||||||
|
*/
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nbytesread = read(fd, &argument[index], IOBUFFERSIZE);
|
||||||
|
if (nbytesread == 0)
|
||||||
|
{
|
||||||
|
/* Unexpected end of file -- Break out of the loop */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (nbytesread < 0)
|
||||||
|
{
|
||||||
|
/* EINTR is not an error (but will still stop the copy) */
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
if (errno == EINTR)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtsignalrecvd, "``");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Read error */
|
||||||
|
|
||||||
|
nsh_output(vtbl, g_fmtcmdfailed, "``", "read", NSH_ERRNO);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto errout_with_fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (nbytesread <= 0);
|
||||||
|
|
||||||
|
/* Update the index based upon the number of bytes read */
|
||||||
|
|
||||||
|
index += nbytesread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure that the new string is null terminated */
|
||||||
|
|
||||||
|
argument[index] = '\0';
|
||||||
|
return argument;
|
||||||
|
|
||||||
|
errout_with_fd:
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
errout_with_alloc:
|
||||||
|
free(argument);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_cmdparm
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
|
static FAR char *nsh_cmdparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
||||||
|
FAR char **allocation)
|
||||||
|
{
|
||||||
|
FAR char *tmpfile;
|
||||||
|
FAR char *argument;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* We cannot process the command argument if there is no allocation pointer */
|
||||||
|
|
||||||
|
if (!allocation)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a unique file name using the task ID */
|
||||||
|
|
||||||
|
tmpfile = NULL;
|
||||||
|
ret = asprintf(&tmpfile, "%s/TMP%d.dat", CONFIG_NSH_TMPDIR, getpid());
|
||||||
|
if (ret < 0 || !tmpfile)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdoutofmemory, "``");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute the command that will re-direct the output of the command to
|
||||||
|
* the temporary file. This is a simple command that can't handle most
|
||||||
|
* options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = nsh_parse_funcparm(vtbl, cmdline, tmpfile);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
/* Report the failure */
|
||||||
|
|
||||||
|
nsh_output(vtbl, g_fmtcmdfailed, "``", "exec", NSH_ERRNO);
|
||||||
|
free(tmpfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Concatenate the file contents with the current allocation */
|
||||||
|
|
||||||
|
argument = nsh_filecat(vtbl, *allocation, tmpfile);
|
||||||
|
*allocation = argument;
|
||||||
|
|
||||||
|
/* We can now unlink the tmpfile and free the tmpfile string */
|
||||||
|
|
||||||
|
ret = unlink(tmpfile);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdfailed, "``", "unlink", NSH_ERRNO);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmpfile);
|
||||||
|
return argument;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_strcat
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NSH_ARGCAT
|
||||||
|
static int nsh_strcat(FAR char *s1, FAR const char *s2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nsh_argument
|
* Name: nsh_argument
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr)
|
static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr,
|
||||||
|
FAR NSH_MEMLIST_TYPE *memlist)
|
||||||
{
|
{
|
||||||
FAR char *pbegin = *saveptr;
|
FAR char *pbegin = *saveptr;
|
||||||
FAR char *pend = NULL;
|
FAR char *pend = NULL;
|
||||||
const char *term;
|
FAR char *allocation = NULL;
|
||||||
|
FAR char *argument = NULL;
|
||||||
|
FAR const char *term;
|
||||||
#ifndef CONFIG_DISABLE_ENVIRON
|
#ifndef CONFIG_DISABLE_ENVIRON
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
#endif
|
#endif
|
||||||
@ -614,17 +906,14 @@ static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr)
|
|||||||
pbegin = NULL;
|
pbegin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_FUNCPARMS
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
/* Are we being asked to use the output from another command or program
|
/* Are we being asked to use the output from another command or program
|
||||||
* as an input parameters for this command?
|
* as an input parameters for this command?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (*pbegin == '`')
|
else if (*pbegin == '`')
|
||||||
{
|
{
|
||||||
FAR char *tmpfile;
|
/* Yes, find the terminating backquote */
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Yes, find the terminated backquote */
|
|
||||||
|
|
||||||
for (++pbegin, pend = pbegin; *pend && *pend != '`'; pend++);
|
for (++pbegin, pend = pbegin; *pend && *pend != '`'; pend++);
|
||||||
|
|
||||||
@ -645,51 +934,9 @@ static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr)
|
|||||||
*pend++ = '\0';
|
*pend++ = '\0';
|
||||||
*saveptr = pend;
|
*saveptr = pend;
|
||||||
|
|
||||||
/* Create a unique file name using the task ID */
|
/* Then execute the command to get the paramter value */
|
||||||
|
|
||||||
tmpfile = NULL;
|
argument = nsh_cmdparm(vtbl, pbegin, &allocation);
|
||||||
ret = asprintf(&tmpfile, "%s/TMP%d.dat", CONFIG_NSH_TMPDIR, getpid());
|
|
||||||
if (ret < 0 || !tmpfile)
|
|
||||||
{
|
|
||||||
nsh_output(vtbl, g_fmtcmdoutofmemory, "``");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute the command that will re-direct the output of the command
|
|
||||||
* to the temporary file. This is a simple command that can't handle
|
|
||||||
* most options.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = nsh_parse_funcparm(vtbl, pbegin, tmpfile);
|
|
||||||
if (ret != OK)
|
|
||||||
{
|
|
||||||
/* Report the failure */
|
|
||||||
#warning Logic Missing
|
|
||||||
|
|
||||||
free(tmpfile);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mmap() the file contain the output from the command so that
|
|
||||||
* we can refer to it like any string.
|
|
||||||
*/
|
|
||||||
#warning Logic Missing
|
|
||||||
|
|
||||||
/* setup so that we can unmap the memory region and close the
|
|
||||||
* file after the command completes.
|
|
||||||
*/
|
|
||||||
#warning Logic Missing
|
|
||||||
|
|
||||||
/* We can not unlink the tmpfile and free the tmpfile string */
|
|
||||||
|
|
||||||
ret = unlink(tmpfile);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, "``", "unlink", NSH_ERRNO);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(tmpfile);
|
|
||||||
return "OH NO!";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -780,11 +1027,27 @@ static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* The argument to be returned is simply the beginning of the
|
||||||
|
* delimited string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
argument = pbegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the beginning of the token. */
|
|
||||||
|
|
||||||
return pbegin;
|
/* If any memory was allocated for this argument, make sure that it is
|
||||||
|
* added to the list of memory to be freed at the end of commend
|
||||||
|
* processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (allocation)
|
||||||
|
{
|
||||||
|
NSH_MEMLIST_ADD(memlist, allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the parsed argument. */
|
||||||
|
|
||||||
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -825,7 +1088,7 @@ static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl)
|
|||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr)
|
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist)
|
||||||
{
|
{
|
||||||
struct nsh_parser_s *np = &vtbl->np;
|
struct nsh_parser_s *np = &vtbl->np;
|
||||||
FAR char *cmd = *ppcmd;
|
FAR char *cmd = *ppcmd;
|
||||||
@ -839,7 +1102,7 @@ static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
{
|
{
|
||||||
/* Get the cmd following the if */
|
/* Get the cmd following the if */
|
||||||
|
|
||||||
*ppcmd = nsh_argument(vtbl, saveptr);
|
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (!*ppcmd)
|
if (!*ppcmd)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtarginvalid, "if");
|
nsh_output(vtbl, g_fmtarginvalid, "if");
|
||||||
@ -876,7 +1139,7 @@ static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
{
|
{
|
||||||
/* Get the cmd following the then -- there shouldn't be one */
|
/* Get the cmd following the then -- there shouldn't be one */
|
||||||
|
|
||||||
*ppcmd = nsh_argument(vtbl, saveptr);
|
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (*ppcmd)
|
if (*ppcmd)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtarginvalid, "then");
|
nsh_output(vtbl, g_fmtarginvalid, "then");
|
||||||
@ -896,7 +1159,7 @@ static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
{
|
{
|
||||||
/* Get the cmd following the else -- there shouldn't be one */
|
/* Get the cmd following the else -- there shouldn't be one */
|
||||||
|
|
||||||
*ppcmd = nsh_argument(vtbl, saveptr);
|
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (*ppcmd)
|
if (*ppcmd)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtarginvalid, "else");
|
nsh_output(vtbl, g_fmtarginvalid, "else");
|
||||||
@ -916,7 +1179,7 @@ static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
{
|
{
|
||||||
/* Get the cmd following the fi -- there should be one */
|
/* Get the cmd following the fi -- there should be one */
|
||||||
|
|
||||||
*ppcmd = nsh_argument(vtbl, saveptr);
|
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (*ppcmd)
|
if (*ppcmd)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtarginvalid, "fi");
|
nsh_output(vtbl, g_fmtarginvalid, "fi");
|
||||||
@ -965,7 +1228,7 @@ errout:
|
|||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr)
|
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist)
|
||||||
{
|
{
|
||||||
FAR char *cmd = *ppcmd;
|
FAR char *cmd = *ppcmd;
|
||||||
|
|
||||||
@ -984,10 +1247,10 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
|
|
||||||
/* Get the cmd (or -d option of nice command) */
|
/* Get the cmd (or -d option of nice command) */
|
||||||
|
|
||||||
cmd = nsh_argument(vtbl, saveptr);
|
cmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (cmd && strcmp(cmd, "-d") == 0)
|
if (cmd && strcmp(cmd, "-d") == 0)
|
||||||
{
|
{
|
||||||
FAR char *val = nsh_argument(vtbl, saveptr);
|
FAR char *val = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
char *endptr;
|
char *endptr;
|
||||||
@ -998,7 +1261,7 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
nsh_output(vtbl, g_fmtarginvalid, "nice");
|
nsh_output(vtbl, g_fmtarginvalid, "nice");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
cmd = nsh_argument(vtbl, saveptr);
|
cmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,7 +1280,7 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function parses and executes a simple NSH command. Output is
|
* This function parses and executes a simple NSH command. Output is
|
||||||
* always redirected. Function function supports function paramers like
|
* always redirected. This function supports command parameters like
|
||||||
*
|
*
|
||||||
* set FOO `hello`
|
* set FOO `hello`
|
||||||
*
|
*
|
||||||
@ -1026,10 +1289,11 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_FUNCPARMS
|
#ifdef CONFIG_NSH_CMDPARMS
|
||||||
static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
||||||
FAR const char *redirfile)
|
FAR const char *redirfile)
|
||||||
{
|
{
|
||||||
|
NSH_MEMLIST_TYPE memlist;
|
||||||
FAR char *argv[MAX_ARGV_ENTRIES];
|
FAR char *argv[MAX_ARGV_ENTRIES];
|
||||||
FAR char *saveptr;
|
FAR char *saveptr;
|
||||||
FAR char *cmd;
|
FAR char *cmd;
|
||||||
@ -1041,6 +1305,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
/* Initialize parser state */
|
/* Initialize parser state */
|
||||||
|
|
||||||
memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
|
memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
|
||||||
|
NSH_MEMLIST_INIT(memlist);
|
||||||
|
|
||||||
/* If any options like nice, redirection, or backgrounding are attempted,
|
/* If any options like nice, redirection, or backgrounding are attempted,
|
||||||
* these will not be recognized and will just be passed through as
|
* these will not be recognized and will just be passed through as
|
||||||
@ -1048,7 +1313,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
/* The function is never backgrounded . Remember the current backgrouding
|
/* The command is never backgrounded . Remember the current backgrounding
|
||||||
* state
|
* state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1064,7 +1329,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
/* Parse out the command at the beginning of the line */
|
/* Parse out the command at the beginning of the line */
|
||||||
|
|
||||||
saveptr = cmdline;
|
saveptr = cmdline;
|
||||||
cmd = nsh_argument(vtbl, &saveptr);
|
cmd = nsh_argument(vtbl, &saveptr, &memlist);
|
||||||
|
|
||||||
/* Check if any command was provided -OR- if command processing is
|
/* Check if any command was provided -OR- if command processing is
|
||||||
* currently disabled.
|
* currently disabled.
|
||||||
@ -1077,10 +1342,11 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* An empty line is not an error and an unprocessed command cannot
|
/* An empty line is not an error and an unprocessed command cannot
|
||||||
* generate an error, but neither should they change the last
|
* generate an error, but neither should it change the last command
|
||||||
* command status.
|
* status.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,7 +1363,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
argv[0] = cmd;
|
argv[0] = cmd;
|
||||||
for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
|
for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
|
||||||
{
|
{
|
||||||
argv[argc] = nsh_argument(vtbl, &saveptr);
|
argv[argc] = nsh_argument(vtbl, &saveptr, &memlist);
|
||||||
if (!argv[argc])
|
if (!argv[argc])
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -1123,6 +1389,8 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
vtbl->np.np_bg = bgsave;
|
vtbl->np.np_bg = bgsave;
|
||||||
#endif
|
#endif
|
||||||
vtbl->np.np_redirect = redirsave;
|
vtbl->np.np_redirect = redirsave;
|
||||||
|
|
||||||
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1137,6 +1405,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
|||||||
|
|
||||||
static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
||||||
{
|
{
|
||||||
|
NSH_MEMLIST_TYPE memlist;
|
||||||
FAR char *argv[MAX_ARGV_ENTRIES];
|
FAR char *argv[MAX_ARGV_ENTRIES];
|
||||||
FAR char *saveptr;
|
FAR char *saveptr;
|
||||||
FAR char *cmd;
|
FAR char *cmd;
|
||||||
@ -1150,6 +1419,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
/* Initialize parser state */
|
/* Initialize parser state */
|
||||||
|
|
||||||
memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
|
memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
|
||||||
|
NSH_MEMLIST_INIT(memlist);
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
vtbl->np.np_bg = false;
|
vtbl->np.np_bg = false;
|
||||||
@ -1162,13 +1432,14 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
/* Parse out the command at the beginning of the line */
|
/* Parse out the command at the beginning of the line */
|
||||||
|
|
||||||
saveptr = cmdline;
|
saveptr = cmdline;
|
||||||
cmd = nsh_argument(vtbl, &saveptr);
|
cmd = nsh_argument(vtbl, &saveptr, &memlist);
|
||||||
|
|
||||||
/* Handler if-then-else-fi */
|
/* Handler if-then-else-fi */
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
if (nsh_ifthenelse(vtbl, &cmd, &saveptr) != 0)
|
if (nsh_ifthenelse(vtbl, &cmd, &saveptr, &memlist) != 0)
|
||||||
{
|
{
|
||||||
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return nsh_saveresult(vtbl, true);
|
return nsh_saveresult(vtbl, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1176,8 +1447,9 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
/* Handle nice */
|
/* Handle nice */
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
if (nsh_nice(vtbl, &cmd, &saveptr) != 0)
|
if (nsh_nice(vtbl, &cmd, &saveptr, &memlist) != 0)
|
||||||
{
|
{
|
||||||
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return nsh_saveresult(vtbl, true);
|
return nsh_saveresult(vtbl, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1193,10 +1465,11 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* An empty line is not an error and an unprocessed command cannot
|
/* An empty line is not an error and an unprocessed command cannot
|
||||||
* generate an error, but neither should they change the last
|
* generate an error, but neither should it change the last command
|
||||||
* command status.
|
* status.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1216,7 +1489,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
argv[0] = cmd;
|
argv[0] = cmd;
|
||||||
for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
|
for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
|
||||||
{
|
{
|
||||||
argv[argc] = nsh_argument(vtbl, &saveptr);
|
argv[argc] = nsh_argument(vtbl, &saveptr, &memlist);
|
||||||
if (!argv[argc])
|
if (!argv[argc])
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -1285,6 +1558,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user