From eafaeb9398216dacb92de69683ccdda6007efb1d Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 20 Mar 2011 18:18:19 +0000 Subject: Move nuttx/examples to apps/examples git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3405 42af7a65-404d-4744-a932-0658087f49c3 --- apps/nshlib/nsh_main.c | 1299 ------------------------------------------------ 1 file changed, 1299 deletions(-) delete mode 100644 apps/nshlib/nsh_main.c (limited to 'apps/nshlib/nsh_main.c') diff --git a/apps/nshlib/nsh_main.c b/apps/nshlib/nsh_main.c deleted file mode 100644 index 9b23e6b79..000000000 --- a/apps/nshlib/nsh_main.c +++ /dev/null @@ -1,1299 +0,0 @@ -/**************************************************************************** - * apps/nshlib/nsh_main.c - * - * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_NSH_DISABLEBG -# include -#endif - -#ifdef CONFIG_NSH_BUILTIN_APPS -# include -#endif -#include - -#include "nsh.h" - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -/* Argument list size - * - * argv[0]: The command name. - * argv[1]: The beginning of argument (up to NSH_MAX_ARGUMENTS) - * argv[argc-3]: Possibly '>' or '>>' - * argv[argc-2]: Possibly - * argv[argc-1]: Possibly '&' (if pthreads are enabled) - * argv[argc]: NULL terminating pointer - * - * Maximum size is NSH_MAX_ARGUMENTS+5 - */ - -#ifndef CONFIG_NSH_DISABLEBG -# define MAX_ARGV_ENTRIES (NSH_MAX_ARGUMENTS+5) -#else -# define MAX_ARGV_ENTRIES (NSH_MAX_ARGUMENTS+4) -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct cmdmap_s -{ - const char *cmd; /* Name of the command */ - cmd_t handler; /* Function that handles the command */ - uint8_t minargs; /* Minimum number of arguments (including command) */ - uint8_t maxargs; /* Maximum number of arguments (including command) */ - const char *usage; /* Usage instructions for 'help' command */ -}; - -#ifndef CONFIG_NSH_DISABLEBG -struct cmdarg_s -{ - FAR struct nsh_vtbl_s *vtbl; /* For front-end interaction */ - int fd; /* FD for output redirection */ - int argc; /* Number of arguments in argv */ - FAR char *argv[MAX_ARGV_ENTRIES]; /* Argument list */ -}; -#endif - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLE_HELP - static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); -#endif - -#ifndef CONFIG_NSH_DISABLE_EXIT - static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); -#endif -static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const char g_delim[] = " \t\n"; -static const char g_redirect1[] = ">"; -static const char g_redirect2[] = ">>"; -static const char g_exitstatus[] = "$?"; -static const char g_success[] = "0"; -static const char g_failure[] = "1"; - -static const struct cmdmap_s g_cmdmap[] = -{ -#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST) - { "[", cmd_lbracket, 4, NSH_MAX_ARGUMENTS, " ]" }, -#endif - -#if CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_CAT - { "cat", cmd_cat, 2, NSH_MAX_ARGUMENTS, " [ [ ...]]" }, -# endif -#ifndef CONFIG_DISABLE_ENVIRON -# ifndef CONFIG_NSH_DISABLE_CD - { "cd", cmd_cd, 1, 2, "[|-|~|..]" }, -# endif -#endif -# ifndef CONFIG_NSH_DISABLE_CP - { "cp", cmd_cp, 3, 3, " " }, -# endif -#endif - -#if CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_LS - { "dd", cmd_dd, 3, 6, "if= of= [bs=] [count=] [skip=]" }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_ECHO -# ifndef CONFIG_DISABLE_ENVIRON - { "echo", cmd_echo, 0, NSH_MAX_ARGUMENTS, "[ [...]]" }, -# else - { "echo", cmd_echo, 0, NSH_MAX_ARGUMENTS, "[ [...]]" }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_EXEC - { "exec", cmd_exec, 2, 3, "" }, -#endif -#ifndef CONFIG_NSH_DISABLE_EXIT - { "exit", cmd_exit, 1, 1, NULL }, -#endif - -#ifndef CONFIG_NSH_DISABLE_FREE - { "free", cmd_free, 1, 1, NULL }, -#endif - -#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_GET - { "get", cmd_get, 4, 7, "[-b|-n] [-f ] -h " }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_HELP - { "help", cmd_help, 1, 1, NULL }, -#endif - -#ifdef CONFIG_NET -# ifndef CONFIG_NSH_DISABLE_IFCONFIG - { "ifconfig", cmd_ifconfig, 1, 1, NULL }, -# endif -#endif - -#ifndef CONFIG_DISABLE_SIGNALS -# ifndef CONFIG_NSH_DISABLE_SLEEP - { "kill", cmd_kill, 3, 3, "- " }, -# endif -#endif - -#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) -# ifndef CONFIG_NSH_DISABLE_LOSETUP - { "losetup", cmd_losetup, 3, 6, "[-d ] | [[-o ] [-r] ]" }, -# endif -#endif - -#if CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_LS - { "ls", cmd_ls, 1, 5, "[-lRs] " }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_MB - { "mb", cmd_mb, 2, 3, "[=][ ]" }, -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE) -# ifndef CONFIG_NSH_DISABLE_MKDIR - { "mkdir", cmd_mkdir, 2, 2, "" }, -# endif -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_FAT) -# ifndef CONFIG_NSH_DISABLE_MKFATFS - { "mkfatfs", cmd_mkfatfs, 2, 2, "" }, -# endif -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_MKFIFO - { "mkfifo", cmd_mkfifo, 2, 2, "" }, -# endif -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE) -# ifndef CONFIG_NSH_DISABLE_MKRD - { "mkrd", cmd_mkrd, 2, 6, "[-m ] [-s ] " }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_MH - { "mh", cmd_mh, 2, 3, "[=][ ]" }, -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE) -# ifndef CONFIG_NSH_DISABLE_MOUNT - { "mount", cmd_mount, 4, 5, "-t " }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_MW - { "mw", cmd_mw, 2, 3, "[=][ ]" }, -#endif - -#if defined(CONFIG_NET) && defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \ - !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS) -# ifndef CONFIG_NSH_DISABLE_PING - { "ping", cmd_ping, 2, 6, "[-c ] [-i ] " }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_PS - { "ps", cmd_ps, 1, 1, NULL }, -#endif - -#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_PUT - { "put", cmd_put, 4, 7, "[-b|-n] [-f ] -h " }, -# endif -#endif - -#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON) -# ifndef CONFIG_NSH_DISABLE_PWD - { "pwd", cmd_pwd, 1, 1, NULL }, -# endif -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE) -# ifndef CONFIG_NSH_DISABLE_RM - { "rm", cmd_rm, 2, 2, "" }, -# endif -# ifndef CONFIG_NSH_DISABLE_RMDIR - { "rmdir", cmd_rmdir, 2, 2, "" }, -# endif -#endif - -#ifndef CONFIG_DISABLE_ENVIRON -# ifndef CONFIG_NSH_DISABLE_SET - { "set", cmd_set, 3, 3, " " }, -# endif -#endif - -#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT) -# ifndef CONFIG_NSH_DISABLE_SH - { "sh", cmd_sh, 2, 2, "" }, -# endif -#endif - -#ifndef CONFIG_DISABLE_SIGNALS -# ifndef CONFIG_NSH_DISABLE_SLEEP - { "sleep", cmd_sleep, 2, 2, "" }, -# endif -#endif - -#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST) - { "test", cmd_test, 3, NSH_MAX_ARGUMENTS, "" }, -#endif - -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE) -# ifndef CONFIG_NSH_DISABLE_UMOUNT - { "umount", cmd_umount, 2, 2, "" }, -# endif -#endif - -#ifndef CONFIG_DISABLE_ENVIRON -# ifndef CONFIG_NSH_DISABLE_UNSET - { "unset", cmd_unset, 2, 2, "" }, -# endif -#endif - -#ifndef CONFIG_DISABLE_SIGNALS -# ifndef CONFIG_NSH_DISABLE_USLEEP - { "usleep", cmd_usleep, 2, 2, "" }, -# endif -#endif - -#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0 -# ifndef CONFIG_NSH_DISABLE_GET - { "wget", cmd_wget, 2, 4, "[-o ] " }, -# endif -#endif - -#ifndef CONFIG_NSH_DISABLE_XD - { "xd", cmd_xd, 3, 3, " " }, -#endif - { NULL, NULL, 1, 1, NULL } -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -const char g_nshgreeting[] = "\nNuttShell (NSH)\n"; -const char g_nshprompt[] = "nsh> "; -const char g_nshsyntax[] = "nsh: %s: syntax error\n"; -const char g_fmtargrequired[] = "nsh: %s: missing required argument(s)\n"; -const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n"; -const char g_fmtargrange[] = "nsh: %s: value out of range\n"; -const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n"; -const char g_fmtnosuch[] = "nsh: %s: no such %s: %s\n"; -const char g_fmttoomanyargs[] = "nsh: %s: too many arguments\n"; -const char g_fmtdeepnesting[] = "nsh: %s: nesting too deep\n"; -const char g_fmtcontext[] = "nsh: %s: not valid in this context\n"; -#ifdef CONFIG_NSH_STRERROR -const char g_fmtcmdfailed[] = "nsh: %s: %s failed: %s\n"; -#else -const char g_fmtcmdfailed[] = "nsh: %s: %s failed: %d\n"; -#endif -const char g_fmtcmdoutofmemory[] = "nsh: %s: out of memory\n"; -const char g_fmtinternalerror[] = "nsh: %s: Internal error\n"; -#ifndef CONFIG_DISABLE_SIGNALS -const char g_fmtsignalrecvd[] = "nsh: %s: Interrupted by signal\n"; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: cmd_help - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLE_HELP -static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) -{ - const struct cmdmap_s *ptr; - - nsh_output(vtbl, "NSH command forms:\n"); -#ifndef CONFIG_NSH_DISABLEBG - nsh_output(vtbl, " [nice [-d >]] [> |>> ] [&]\n"); -#else - nsh_output(vtbl, " [> |>> ]\n"); -#endif -#ifndef CONFIG_NSH_DISABLESCRIPT - nsh_output(vtbl, "OR\n"); - nsh_output(vtbl, " if \n"); - nsh_output(vtbl, " then\n"); - nsh_output(vtbl, " [sequence of ]\n"); - nsh_output(vtbl, " else\n"); - nsh_output(vtbl, " [sequence of ]\n"); - nsh_output(vtbl, " fi\n"); -#endif - nsh_output(vtbl, "Where is one of:\n"); - for (ptr = g_cmdmap; ptr->cmd; ptr++) - { - if (ptr->usage) - { - nsh_output(vtbl, " %s %s\n", ptr->cmd, ptr->usage); - } - else - { - nsh_output(vtbl, " %s\n", ptr->cmd); - } - } - return OK; -} -#endif - -/**************************************************************************** - * Name: cmd_unrecognized - ****************************************************************************/ - -static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) -{ - nsh_output(vtbl, g_fmtcmdnotfound, argv[0]); - return ERROR; -} - -/**************************************************************************** - * Name: cmd_exit - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLE_EXIT -static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) -{ - nsh_exit(vtbl); - return OK; -} -#endif - -/**************************************************************************** - * Name: nsh_execute - ****************************************************************************/ - -static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, int argc, char *argv[]) -{ - const struct cmdmap_s *cmdmap; - const char *cmd; - cmd_t handler = cmd_unrecognized; - int ret; - - /* The form of argv is: - * - * argv[0]: The command name. This is argv[0] when the arguments - * are, finally, received by the command vtblr - * argv[1]: The beginning of argument (up to NSH_MAX_ARGUMENTS) - * argv[argc]: NULL terminating pointer - */ - - cmd = argv[0]; - - /* See if the command is one that we understand */ - - for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) - { - if (strcmp(cmdmap->cmd, cmd) == 0) - { - /* Check if a valid number of arguments was provided. We - * do this simple, imperfect checking here so that it does - * not have to be performed in each command. - */ - - if (argc < cmdmap->minargs) - { - /* Fewer than the minimum number were provided */ - - nsh_output(vtbl, g_fmtargrequired, cmd); - return ERROR; - } - else if (argc > cmdmap->maxargs) - { - /* More than the maximum number were provided */ - - nsh_output(vtbl, g_fmttoomanyargs, cmd); - return ERROR; - } - else - { - /* A valid number of arguments were provided (this does - * not mean they are right). - */ - - handler = cmdmap->handler; - break; - } - } - } - - /* If the command was not found, then try to execute the command from - * a list of pre-built applications. - */ - -#ifdef CONFIG_NSH_BUILTIN_APPS - if (handler == cmd_unrecognized && nsh_execapp(vtbl, cmd, argv) == OK) - { - /* The pre-built application was successfully started -- return OK. - * If not, then fall through to execute the cmd_nrecognized handler. - */ - - return OK; - } -#endif - - ret = handler(vtbl, argc, argv); - return ret; -} - -/**************************************************************************** - * Name: nsh_releaseargs - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLEBG -static void nsh_releaseargs(struct cmdarg_s *arg) -{ - FAR struct nsh_vtbl_s *vtbl = arg->vtbl; - int i; - - /* If the output was redirected, then file descriptor should - * be closed. The created task has its one, independent copy of - * the file descriptor - */ - - if (vtbl->np.np_redirect) - { - (void)close(arg->fd); - } - - /* Released the cloned vtbl instance */ - - nsh_release(vtbl); - - /* Release the cloned args */ - - for (i = 0; i < arg->argc; i++) - { - free(arg->argv[i]); - } - free(arg); -} -#endif - -/**************************************************************************** - * Name: nsh_child - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLEBG -static pthread_addr_t nsh_child(pthread_addr_t arg) -{ - struct cmdarg_s *carg = (struct cmdarg_s *)arg; - int ret; - - dbg("BG %s\n", carg->argv[0]); - - /* Execute the specified command on the child thread */ - - ret = nsh_execute(carg->vtbl, carg->argc, carg->argv); - - /* Released the cloned arguments */ - - dbg("BG %s complete\n", carg->argv[0]); - nsh_releaseargs(carg); - return (void*)ret; -} -#endif - -/**************************************************************************** - * Name: nsh_cloneargs - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLEBG -static inline struct cmdarg_s *nsh_cloneargs(FAR struct nsh_vtbl_s *vtbl, - int fd, int argc, char *argv[]) -{ - struct cmdarg_s *ret = (struct cmdarg_s *)zalloc(sizeof(struct cmdarg_s)); - int i; - - if (ret) - { - ret->vtbl = vtbl; - ret->fd = fd; - ret->argc = argc; - - for (i = 0; i < argc; i++) - { - ret->argv[i] = strdup(argv[i]); - } - } - return ret; -} -#endif - -/**************************************************************************** - * Name: nsh_argument - ****************************************************************************/ - -char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr) -{ - char *pbegin = *saveptr; - char *pend = NULL; - const char *term; -#ifndef CONFIG_DISABLE_ENVIRON - bool quoted = false; -#endif - - /* Find the beginning of the next token */ - - for (; - *pbegin && strchr(g_delim, *pbegin) != NULL; - pbegin++); - - /* If we are at the end of the string with nothing - * but delimiters found, then return NULL. - */ - - if (!*pbegin) - { - return NULL; - } - - /* Does the token begin with '>' -- redirection of output? */ - - if (*pbegin == '>') - { - /* Yes.. does it begin with ">>"? */ - - if (*(pbegin + 1) == '>') - { - *saveptr = pbegin + 2; - pbegin = (char*)g_redirect2; - } - else - { - *saveptr = pbegin + 1; - pbegin = (char*)g_redirect1; - } - } - - /* Does the token begin with '#' -- comment */ - - else if (*pbegin == '#') - { - /* Return NULL meaning that we are at the end of the line */ - - *saveptr = pbegin; - pbegin = NULL; - } - else - { - /* Otherwise, we are going to have to parse to find the end of - * the token. Does the token begin with '"'? - */ - - if (*pbegin == '"') - { - /* Yes.. then only another '"' can terminate the string */ - - pbegin++; - term = "\""; -#ifndef CONFIG_DISABLE_ENVIRON - quoted = true; -#endif - } - else - { - /* No, then any of the usual terminators will terminate the argument */ - - term = g_delim; - } - - /* Find the end of the string */ - - for (pend = pbegin + 1; - *pend && strchr(term, *pend) == NULL; - pend++); - - /* pend either points to the end of the string or to - * the first delimiter after the string. - */ - - if (*pend) - { - /* Turn the delimiter into a null terminator */ - - *pend++ = '\0'; - } - - /* Save the pointer where we left off */ - - *saveptr = pend; - -#ifndef CONFIG_DISABLE_ENVIRON - /* Check for references to environment variables */ - - if (pbegin[0] == '$' && !quoted) - { - /* Check for built-in variables */ - - if (strcmp(pbegin, g_exitstatus) == 0) - { - if (vtbl->np.np_fail) - { - return (char*)g_failure; - } - else - { - return (char*)g_success; - } - } - - /* Not a built-in? Return the value of the environment variable with this name */ - - else - { - char *value = getenv(pbegin+1); - if (value) - { - return value; - } - else - { - return (char*)""; - } - } - } -#endif - } - - /* Return the beginning of the token. */ - - return pbegin; -} - -/**************************************************************************** - * Name: nsh_cmdenabled - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLESCRIPT -static inline bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl) -{ - struct nsh_parser_s *np = &vtbl->np; - bool ret = !np->np_st[np->np_ndx].ns_disabled; - if (ret) - { - switch (np->np_st[np->np_ndx].ns_state) - { - case NSH_PARSER_NORMAL : - case NSH_PARSER_IF: - default: - break; - - case NSH_PARSER_THEN: - ret = !np->np_st[np->np_ndx].ns_ifcond; - break; - - case NSH_PARSER_ELSE: - ret = np->np_st[np->np_ndx].ns_ifcond; - break; - } - } - return ret; -} -#endif - -/**************************************************************************** - * Name: nsh_ifthenelse - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLESCRIPT -static inline int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr) -{ - struct nsh_parser_s *np = &vtbl->np; - FAR char *cmd = *ppcmd; - bool disabled; - - if (cmd) - { - /* Check if the command is preceeded by "if" */ - - if (strcmp(cmd, "if") == 0) - { - /* Get the cmd following the if */ - - *ppcmd = nsh_argument(vtbl, saveptr); - if (!*ppcmd) - { - nsh_output(vtbl, g_fmtarginvalid, "if"); - goto errout; - } - - /* Verify that "if" is valid in this context */ - - if (np->np_st[np->np_ndx].ns_state != NSH_PARSER_NORMAL && - np->np_st[np->np_ndx].ns_state != NSH_PARSER_THEN && - np->np_st[np->np_ndx].ns_state != NSH_PARSER_ELSE) - { - nsh_output(vtbl, g_fmtcontext, "if"); - goto errout; - } - - /* Check if we have exceeded the maximum depth of nesting */ - - if (np->np_ndx >= CONFIG_NSH_NESTDEPTH-1) - { - nsh_output(vtbl, g_fmtdeepnesting, "if"); - goto errout; - } - - /* "Push" the old state and set the new state */ - - disabled = !nsh_cmdenabled(vtbl); - np->np_ndx++; - np->np_st[np->np_ndx].ns_state = NSH_PARSER_IF; - np->np_st[np->np_ndx].ns_disabled = disabled; - np->np_st[np->np_ndx].ns_ifcond = false; - } - else if (strcmp(cmd, "then") == 0) - { - /* Get the cmd following the then -- there shouldn't be one */ - - *ppcmd = nsh_argument(vtbl, saveptr); - if (*ppcmd) - { - nsh_output(vtbl, g_fmtarginvalid, "then"); - goto errout; - } - - /* Verify that "then" is valid in this context */ - - if (np->np_st[np->np_ndx].ns_state != NSH_PARSER_IF) - { - nsh_output(vtbl, g_fmtcontext, "then"); - goto errout; - } - np->np_st[np->np_ndx].ns_state = NSH_PARSER_THEN; - } - else if (strcmp(cmd, "else") == 0) - { - /* Get the cmd following the else -- there shouldn't be one */ - - *ppcmd = nsh_argument(vtbl, saveptr); - if (*ppcmd) - { - nsh_output(vtbl, g_fmtarginvalid, "else"); - goto errout; - } - - /* Verify that "then" is valid in this context */ - - if (np->np_st[np->np_ndx].ns_state != NSH_PARSER_THEN) - { - nsh_output(vtbl, g_fmtcontext, "else"); - goto errout; - } - np->np_st[np->np_ndx].ns_state = NSH_PARSER_ELSE; - } - else if (strcmp(cmd, "fi") == 0) - { - /* Get the cmd following the fi -- there should be one */ - - *ppcmd = nsh_argument(vtbl, saveptr); - if (*ppcmd) - { - nsh_output(vtbl, g_fmtarginvalid, "fi"); - goto errout; - } - - /* Verify that "fi" is valid in this context */ - - if (np->np_st[np->np_ndx].ns_state != NSH_PARSER_THEN && - np->np_st[np->np_ndx].ns_state != NSH_PARSER_ELSE) - { - nsh_output(vtbl, g_fmtcontext, "fi"); - goto errout; - } - - if (np->np_ndx < 1) /* Shouldn't happen */ - { - nsh_output(vtbl, g_fmtinternalerror, "if"); - goto errout; - } - - /* "Pop" the previous state */ - - np->np_ndx--; - } - else if (np->np_st[np->np_ndx].ns_state == NSH_PARSER_IF) - { - nsh_output(vtbl, g_fmtcontext, cmd); - goto errout; - } - } - return OK; - -errout: - np->np_ndx = 0; - np->np_st[0].ns_state = NSH_PARSER_NORMAL; - np->np_st[0].ns_disabled = false; - np->np_st[0].ns_ifcond = false; - return ERROR; -} -#endif - -/**************************************************************************** - * Name: nsh_saveresult - ****************************************************************************/ - -static inline int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result) -{ - struct nsh_parser_s *np = &vtbl->np; - -#ifndef CONFIG_NSH_DISABLESCRIPT - if (np->np_st[np->np_ndx].ns_state == NSH_PARSER_IF) - { - np->np_fail = false; - np->np_st[np->np_ndx].ns_ifcond = result; - return OK; - } - else -#endif - { - np->np_fail = result; - return result ? ERROR : OK; - } -} - -/**************************************************************************** - * Name: nsh_nice - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLEBG -static inline int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr) -{ - FAR char *cmd = *ppcmd; - - vtbl->np.np_nice = 0; - if (cmd) - { - /* Check if the command is preceded by "nice" */ - - if (strcmp(cmd, "nice") == 0) - { - /* Nicenesses range from -20 (most favorable scheduling) to 19 - * (least favorable). Default is 10. - */ - - vtbl->np.np_nice = 10; - - /* Get the cmd (or -d option of nice command) */ - - cmd = nsh_argument(vtbl, saveptr); - if (cmd && strcmp(cmd, "-d") == 0) - { - FAR char *val = nsh_argument(vtbl, saveptr); - if (val) - { - char *endptr; - vtbl->np.np_nice = (int)strtol(val, &endptr, 0); - if (vtbl->np.np_nice > 19 || vtbl->np.np_nice < -20 || - endptr == val || *endptr != '\0') - { - nsh_output(vtbl, g_fmtarginvalid, "nice"); - return ERROR; - } - cmd = nsh_argument(vtbl, saveptr); - } - } - - /* Return the real command name */ - - *ppcmd = cmd; - } - } - return OK; -} -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nsh_initialize - ****************************************************************************/ - -void nsh_initialize(void) -{ - /* Mount the /etc filesystem */ - - (void)nsh_romfsetc(); - - /* Perform architecture-specific initialization (if available) */ - - (void)nsh_archinitialize(); - - /* Bring up the network */ - - (void)nsh_netinit(); -} - -/**************************************************************************** - * Name: nsh_parse - ****************************************************************************/ - -int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) -{ - FAR char *argv[MAX_ARGV_ENTRIES]; - FAR char *saveptr; - FAR char *cmd; - FAR char *redirfile = NULL; - int fd = -1; - int oflags = 0; - int argc; - int ret; - - /* Initialize parser state */ - - memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *)); -#ifndef CONFIG_NSH_DISABLEBG - vtbl->np.np_bg = false; -#endif - vtbl->np.np_redirect = false; - - /* Parse out the command at the beginning of the line */ - - saveptr = cmdline; - cmd = nsh_argument(vtbl, &saveptr); - - /* Handler if-then-else-fi */ - -#ifndef CONFIG_NSH_DISABLESCRIPT - if (nsh_ifthenelse(vtbl, &cmd, &saveptr) != 0) - { - goto errout; - } -#endif - - /* Handle nice */ - -#ifndef CONFIG_NSH_DISABLEBG - if (nsh_nice(vtbl, &cmd, &saveptr) != 0) - { - goto errout; - } -#endif - - /* Check if any command was provided -OR- if command processing is - * currently disabled. - */ - -#ifndef CONFIG_NSH_DISABLESCRIPT - if (!cmd || !nsh_cmdenabled(vtbl)) -#else - if (!cmd) -#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. - */ - - return OK; - } - - /* Parse all of the arguments following the command name. The form - * of argv is: - * - * argv[0]: The command name. - * argv[1]: The beginning of argument (up to NSH_MAX_ARGUMENTS) - * argv[argc-3]: Possibly '>' or '>>' - * argv[argc-2]: Possibly - * argv[argc-1]: Possibly '&' - * argv[argc]: NULL terminating pointer - * - * Maximum size is NSH_MAX_ARGUMENTS+5 - */ - - argv[0] = cmd; - for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++) - { - argv[argc] = nsh_argument(vtbl, &saveptr); - if (!argv[argc]) - { - break; - } - } - argv[argc] = NULL; - - /* Check if the command should run in background */ - -#ifndef CONFIG_NSH_DISABLEBG - if (argc > 1 && strcmp(argv[argc-1], "&") == 0) - { - vtbl->np.np_bg = true; - argv[argc-1] = NULL; - argc--; - } -#endif - - - /* Check if the output was re-directed using > or >> */ - - if (argc > 2) - { - /* Check for redirection to a new file */ - - if (strcmp(argv[argc-2], g_redirect1) == 0) - { - vtbl->np.np_redirect = true; - oflags = O_WRONLY|O_CREAT|O_TRUNC; - redirfile = nsh_getfullpath(vtbl, argv[argc-1]); - argc -= 2; - } - - /* Check for redirection by appending to an existing file */ - - else if (strcmp(argv[argc-2], g_redirect2) == 0) - { - vtbl->np.np_redirect = true; - oflags = O_WRONLY|O_CREAT|O_APPEND; - redirfile = nsh_getfullpath(vtbl, argv[argc-1]); - argc -= 2; - } - } - - /* Redirected output? */ - - if (vtbl->np.np_redirect) - { - /* Open the redirection file. This file will eventually - * be closed by a call to either nsh_release (if the command - * is executed in the background) or by nsh_undirect if the - * command is executed in the foreground. - */ - - fd = open(redirfile, oflags, 0666); - nsh_freefullpath(redirfile); - redirfile = NULL; - - if (fd < 0) - { - nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO); - goto errout; - } - } - - /* Check if the maximum number of arguments was exceeded */ - - if (argc > NSH_MAX_ARGUMENTS) - { - nsh_output(vtbl, g_fmttoomanyargs, cmd); - } - - /* Handle the case where the command is executed in background. - * However is app is to be started as nuttapp new process will - * be created anyway, so skip this step. */ - -#ifndef CONFIG_NSH_DISABLEBG - if (vtbl->np.np_bg -#ifdef CONFIG_NSH_BUILTIN_APPS - && nuttapp_isavail(argv[0]) < 0 -#endif - ) - { - struct sched_param param; - struct nsh_vtbl_s *bkgvtbl; - struct cmdarg_s *args; - pthread_attr_t attr; - pthread_t thread; - - /* Get a cloned copy of the vtbl with reference count=1. - * after the command has been processed, the nsh_release() call - * at the end of nsh_child() will destroy the clone. - */ - - bkgvtbl = nsh_clone(vtbl); - if (!bkgvtbl) - { - goto errout_with_redirect; - } - - /* Create a container for the command arguments */ - - args = nsh_cloneargs(bkgvtbl, fd, argc, argv); - if (!args) - { - nsh_release(bkgvtbl); - goto errout_with_redirect; - } - - /* Handle redirection of output via a file descriptor */ - - if (vtbl->np.np_redirect) - { - (void)nsh_redirect(bkgvtbl, fd, NULL); - } - - /* Get the execution priority of this task */ - - ret = sched_getparam(0, ¶m); - if (ret != 0) - { - nsh_output(vtbl, g_fmtcmdfailed, cmd, "sched_getparm", NSH_ERRNO); - nsh_releaseargs(args); - nsh_release(bkgvtbl); - goto errout; - } - - /* Determine the priority to execute the command */ - - if (vtbl->np.np_nice != 0) - { - int priority = param.sched_priority - vtbl->np.np_nice; - if (vtbl->np.np_nice < 0) - { - int max_priority = sched_get_priority_max(SCHED_NSH); - if (priority > max_priority) - { - priority = max_priority; - } - } - else - { - int min_priority = sched_get_priority_min(SCHED_NSH); - if (priority < min_priority) - { - priority = min_priority; - } - } - param.sched_priority = priority; - } - - /* Set up the thread attributes */ - - (void)pthread_attr_init(&attr); - (void)pthread_attr_setschedpolicy(&attr, SCHED_NSH); - (void)pthread_attr_setschedparam(&attr, ¶m); - - /* Execute the command as a separate thread at the appropriate priority */ - - ret = pthread_create(&thread, &attr, nsh_child, (pthread_addr_t)args); - if (ret != 0) - { - nsh_output(vtbl, g_fmtcmdfailed, cmd, "pthread_create", NSH_ERRNO_OF(ret)); - nsh_releaseargs(args); - nsh_release(bkgvtbl); - goto errout; - } - nsh_output(vtbl, "%s [%d:%d]\n", cmd, thread, param.sched_priority); - } - else -#endif - { - uint8_t save[SAVE_SIZE]; - - /* Handle redirection of output via a file descriptor */ - - if (vtbl->np.np_redirect) - { - nsh_redirect(vtbl, fd, save); - } - - /* Then execute the command in "foreground" -- i.e., while the user waits - * for the next prompt. - */ - - ret = nsh_execute(vtbl, argc, argv); - - /* Restore the original output. Undirect will close the redirection - * file descriptor. - */ - - if (vtbl->np.np_redirect) - { - nsh_undirect(vtbl, save); - } - - if (ret < 0) - { - goto errout; - } - } - - /* Return success if the command succeeded (or at least, starting of the - * command task succeeded). - */ - - return nsh_saveresult(vtbl, false); - -#ifndef CONFIG_NSH_DISABLEBG -errout_with_redirect: - if (vtbl->np.np_redirect) - { - close(fd); - } -#endif -errout: - return nsh_saveresult(vtbl, true); -} -- cgit v1.2.3