summaryrefslogtreecommitdiff
path: root/apps/nshlib/nsh_parse.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-01-11 09:50:54 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-01-11 09:50:54 -0600
commita31974f5f25547a6f4e4aadf5056602905b72b87 (patch)
tree83a6b76c362cad736c00ef7829373bcdde242c2d /apps/nshlib/nsh_parse.c
parent9a3db48a553a6d62d9954d6b20327e95505578cc (diff)
downloadnuttx-a31974f5f25547a6f4e4aadf5056602905b72b87.tar.gz
nuttx-a31974f5f25547a6f4e4aadf5056602905b72b87.tar.bz2
nuttx-a31974f5f25547a6f4e4aadf5056602905b72b87.zip
Back quoted NSH arguments now functional
Diffstat (limited to 'apps/nshlib/nsh_parse.c')
-rw-r--r--apps/nshlib/nsh_parse.c438
1 files changed, 356 insertions, 82 deletions
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index 10ac3a258..97c87a7a1 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -45,6 +45,10 @@
#include <errno.h>
#include <debug.h>
+#ifdef CONFIG_NSH_CMDPARMS
+# include <sys/stat.h>
+#endif
+
#include <apps/nsh.h>
#include "nsh.h"
@@ -53,6 +57,37 @@
/****************************************************************************
* 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
@@ -70,10 +105,26 @@ struct cmdarg_s
};
#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
****************************************************************************/
+#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
static void nsh_releaseargs(struct cmdarg_s *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,
int argc, FAR char *argv[], FAR const char *redirfile,
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
static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl);
-static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl,
- FAR char **ppcmd, FAR char **saveptr);
+static int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
+ FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist);
#endif
#ifndef CONFIG_NSH_DISABLEBG
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
-#ifdef CONFIG_NSH_FUNCPARMS
+#ifdef CONFIG_NSH_CMDPARMS
static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
FAR const char *redirfile);
#endif
@@ -173,6 +235,48 @@ const char g_fmtsignalrecvd[] = "nsh: %s: Interrupted by signal\n";
****************************************************************************/
/****************************************************************************
+ * 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
****************************************************************************/
@@ -204,6 +308,7 @@ static void nsh_releaseargs(struct cmdarg_s *arg)
{
free(arg->argv[i]);
}
+
free(arg);
}
#endif
@@ -559,14 +664,201 @@ errout:
}
/****************************************************************************
+ * 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
****************************************************************************/
-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 *pend = NULL;
- const char *term;
+ FAR char *pbegin = *saveptr;
+ FAR char *pend = NULL;
+ FAR char *allocation = NULL;
+ FAR char *argument = NULL;
+ FAR const char *term;
#ifndef CONFIG_DISABLE_ENVIRON
bool quoted = false;
#endif
@@ -614,17 +906,14 @@ static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr)
pbegin = NULL;
}
-#ifdef CONFIG_NSH_FUNCPARMS
+#ifdef CONFIG_NSH_CMDPARMS
/* Are we being asked to use the output from another command or program
* as an input parameters for this command?
*/
else if (*pbegin == '`')
{
- FAR char *tmpfile;
- int ret;
-
- /* Yes, find the terminated backquote */
+ /* Yes, find the terminating backquote */
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';
*saveptr = pend;
- /* 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;
- }
+ /* Then execute the command to get the paramter value */
- /* 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!";
+ argument = nsh_cmdparm(vtbl, pbegin, &allocation);
}
#endif
@@ -780,11 +1027,27 @@ static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr)
}
}
#endif
+ /* The argument to be returned is simply the beginning of the
+ * delimited string.
+ */
+
+ argument = 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 beginning of the token. */
+ /* Return the parsed argument. */
- return pbegin;
+ return argument;
}
/****************************************************************************
@@ -825,7 +1088,7 @@ static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl)
#ifndef CONFIG_NSH_DISABLESCRIPT
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;
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 */
- *ppcmd = nsh_argument(vtbl, saveptr);
+ *ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (!*ppcmd)
{
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 */
- *ppcmd = nsh_argument(vtbl, saveptr);
+ *ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (*ppcmd)
{
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 */
- *ppcmd = nsh_argument(vtbl, saveptr);
+ *ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (*ppcmd)
{
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 */
- *ppcmd = nsh_argument(vtbl, saveptr);
+ *ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (*ppcmd)
{
nsh_output(vtbl, g_fmtarginvalid, "fi");
@@ -965,7 +1228,7 @@ errout:
#ifndef CONFIG_NSH_DISABLEBG
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;
@@ -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) */
- cmd = nsh_argument(vtbl, saveptr);
+ cmd = nsh_argument(vtbl, saveptr, memlist);
if (cmd && strcmp(cmd, "-d") == 0)
{
- FAR char *val = nsh_argument(vtbl, saveptr);
+ FAR char *val = nsh_argument(vtbl, saveptr, memlist);
if (val)
{
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");
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:
* 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`
*
@@ -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,
FAR const char *redirfile)
{
+ NSH_MEMLIST_TYPE memlist;
FAR char *argv[MAX_ARGV_ENTRIES];
FAR char *saveptr;
FAR char *cmd;
@@ -1041,6 +1305,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
/* Initialize parser state */
memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
+ NSH_MEMLIST_INIT(memlist);
/* If any options like nice, redirection, or backgrounding are attempted,
* 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
- /* The function is never backgrounded . Remember the current backgrouding
+ /* The command is never backgrounded . Remember the current backgrounding
* 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 */
saveptr = cmdline;
- cmd = nsh_argument(vtbl, &saveptr);
+ cmd = nsh_argument(vtbl, &saveptr, &memlist);
/* Check if any command was provided -OR- if command processing is
* currently disabled.
@@ -1077,10 +1342,11 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
#endif
{
/* An empty line is not an error and an unprocessed command cannot
- * generate an error, but neither should they change the last
- * command status.
+ * generate an error, but neither should it change the last command
+ * status.
*/
+ NSH_MEMLIST_FREE(&memlist);
return OK;
}
@@ -1097,7 +1363,7 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
argv[0] = cmd;
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])
{
break;
@@ -1123,6 +1389,8 @@ static int nsh_parse_funcparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
vtbl->np.np_bg = bgsave;
#endif
vtbl->np.np_redirect = redirsave;
+
+ NSH_MEMLIST_FREE(&memlist);
return ret;
}
#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)
{
+ NSH_MEMLIST_TYPE memlist;
FAR char *argv[MAX_ARGV_ENTRIES];
FAR char *saveptr;
FAR char *cmd;
@@ -1150,6 +1419,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
/* Initialize parser state */
memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
+ NSH_MEMLIST_INIT(memlist);
#ifndef CONFIG_NSH_DISABLEBG
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 */
saveptr = cmdline;
- cmd = nsh_argument(vtbl, &saveptr);
+ cmd = nsh_argument(vtbl, &saveptr, &memlist);
/* Handler if-then-else-fi */
#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);
}
#endif
@@ -1176,8 +1447,9 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
/* Handle nice */
#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);
}
#endif
@@ -1193,10 +1465,11 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
#endif
{
/* An empty line is not an error and an unprocessed command cannot
- * generate an error, but neither should they change the last
- * command status.
+ * generate an error, but neither should it change the last command
+ * status.
*/
+ NSH_MEMLIST_FREE(&memlist);
return OK;
}
@@ -1216,7 +1489,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
argv[0] = cmd;
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])
{
break;
@@ -1285,6 +1558,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
}
#endif
+ NSH_MEMLIST_FREE(&memlist);
return ret;
}