X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fmain.c;h=592ce077d214d20243c57209c0e046037c7d69c1;hb=1cc619be8b73abbee2fd6faf2cd4ade27b516531;hp=91e888fd3ce0a3ef54c1996d153538e76e78707c;hpb=e9d44b35beb45869863f3ca6929089d9df4df3e5;p=u-boot diff --git a/common/main.c b/common/main.c index 91e888fd3c..592ce077d2 100644 --- a/common/main.c +++ b/common/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #ifdef CONFIG_MODEM_SUPPORT #include /* for free() prototype */ @@ -113,6 +114,11 @@ int abortboot(int bootdelay) u_int presskey_max = 0; u_int i; +#ifndef CONFIG_ZERO_BOOTDELAY_CHECK + if (bootdelay == 0) + return 0; +#endif + # ifdef CONFIG_AUTOBOOT_PROMPT printf(CONFIG_AUTOBOOT_PROMPT); # endif @@ -216,7 +222,8 @@ int abortboot(int bootdelay) #ifdef CONFIG_MENUPROMPT printf(CONFIG_MENUPROMPT); #else - printf("Hit any key to stop autoboot: %2d ", bootdelay); + if (bootdelay >= 0) + printf("Hit any key to stop autoboot: %2d ", bootdelay); #endif #if defined CONFIG_ZERO_BOOTDELAY_CHECK @@ -267,28 +274,6 @@ int abortboot(int bootdelay) # endif /* CONFIG_AUTOBOOT_KEYED */ #endif /* CONFIG_BOOTDELAY >= 0 */ -/* - * Return 0 on success, or != 0 on error. - */ -#ifndef CONFIG_CMD_PXE -static inline -#endif -int run_command2(const char *cmd, int flag) -{ -#ifndef CONFIG_SYS_HUSH_PARSER - /* - * run_command can return 0 or 1 for success, so clean up its result. - */ - if (run_command(cmd, flag) == -1) - return 1; - - return 0; -#else - return parse_string_outer(cmd, - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); -#endif -} - /****************************************************************************/ void main_loop (void) @@ -355,7 +340,7 @@ void main_loop (void) int prev = disable_ctrlc(1); /* disable Control C checking */ # endif - run_command2(p, 0); + run_command_list(p, -1, 0); # ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ @@ -398,12 +383,12 @@ void main_loop (void) debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : ""); - if (bootdelay >= 0 && s && !abortboot (bootdelay)) { + if (bootdelay != -1 && s && !abortboot(bootdelay)) { # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif - run_command2(s, 0); + run_command_list(s, -1, 0); # ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ @@ -414,7 +399,7 @@ void main_loop (void) if (menukey == CONFIG_MENUKEY) { s = getenv("menucmd"); if (s) - run_command2(s, 0); + run_command_list(s, -1, 0); } #endif /* CONFIG_MENUKEY */ #endif /* CONFIG_BOOTDELAY */ @@ -460,7 +445,7 @@ void main_loop (void) if (len == -1) puts ("\n"); else - rc = run_command (lastcommand, flag); + rc = run_command(lastcommand, flag); if (rc <= 0) { /* invalid command or not repeatable, forget it */ @@ -520,13 +505,13 @@ void reset_cmd_timeout(void) #define HIST_MAX 20 #define HIST_SIZE CONFIG_SYS_CBSIZE -static int hist_max = 0; -static int hist_add_idx = 0; +static int hist_max; +static int hist_add_idx; static int hist_cur = -1; -unsigned hist_num = 0; +static unsigned hist_num; -char* hist_list[HIST_MAX]; -char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */ +static char *hist_list[HIST_MAX]; +static char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */ #define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1) @@ -995,7 +980,6 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout) #ifdef CONFIG_SHOW_ACTIVITY while (!tstc()) { - extern void show_activity(int arg); show_activity(0); WATCHDOG_RESET(); } @@ -1154,6 +1138,7 @@ int parse_line (char *line, char *argv[]) /****************************************************************************/ +#ifndef CONFIG_SYS_HUSH_PARSER static void process_macros (const char *input, char *output) { char c, prev; @@ -1280,10 +1265,8 @@ static void process_macros (const char *input, char *output) * the environment data, which may change magicly when the command we run * creates or modifies environment variables (like "bootp" does). */ - -int run_command (const char *cmd, int flag) +static int builtin_run_command(const char *cmd, int flag) { - cmd_tbl_t *cmdtp; char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ @@ -1361,49 +1344,124 @@ int run_command (const char *cmd, int flag) continue; } - /* Look up command in command table */ - if ((cmdtp = find_cmd(argv[0])) == NULL) { - printf ("Unknown command '%s' - try 'help'\n", argv[0]); - rc = -1; /* give up after bad command */ - continue; - } - - /* found - check max args */ - if (argc > cmdtp->maxargs) { - cmd_usage(cmdtp); + if (cmd_process(flag, argc, argv, &repeatable)) rc = -1; - continue; - } -#if defined(CONFIG_CMD_BOOTD) - /* avoid "bootd" recursion */ - if (cmdtp->cmd == do_bootd) { -#ifdef DEBUG_PARSER - printf ("[%s]\n", finaltoken); + /* Did the user stop this? */ + if (had_ctrlc ()) + return -1; /* if stopped then not repeatable */ + } + + return rc ? rc : repeatable; +} #endif - if (flag & CMD_FLAG_BOOTD) { - puts ("'bootd' recursion detected\n"); - rc = -1; - continue; - } else { - flag |= CMD_FLAG_BOOTD; - } - } + +/* + * Run a command using the selected parser. + * + * @param cmd Command to run + * @param flag Execution flags (CMD_FLAG_...) + * @return 0 on success, or != 0 on error. + */ +int run_command(const char *cmd, int flag) +{ +#ifndef CONFIG_SYS_HUSH_PARSER + /* + * builtin_run_command can return 0 or 1 for success, so clean up + * its result. + */ + if (builtin_run_command(cmd, flag) == -1) + return 1; + + return 0; +#else + return parse_string_outer(cmd, + FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif +} - /* OK - call function to do the command */ - if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { - rc = -1; +#ifndef CONFIG_SYS_HUSH_PARSER +/** + * Execute a list of command separated by ; or \n using the built-in parser. + * + * This function cannot take a const char * for the command, since if it + * finds newlines in the string, it replaces them with \0. + * + * @param cmd String containing list of commands + * @param flag Execution flags (CMD_FLAG_...) + * @return 0 on success, or != 0 on error. + */ +static int builtin_run_command_list(char *cmd, int flag) +{ + char *line, *next; + int rcode = 0; + + /* + * Break into individual lines, and execute each line; terminate on + * error. + */ + line = next = cmd; + while (*next) { + if (*next == '\n') { + *next = '\0'; + /* run only non-empty commands */ + if (*line) { + debug("** exec: \"%s\"\n", line); + if (builtin_run_command(line, 0) < 0) { + rcode = 1; + break; + } + } + line = next + 1; } + ++next; + } + if (rcode == 0 && *line) + rcode = (builtin_run_command(line, 0) >= 0); - repeatable &= cmdtp->repeatable; + return rcode; +} +#endif - /* Did the user stop this? */ - if (had_ctrlc ()) - return -1; /* if stopped then not repeatable */ +int run_command_list(const char *cmd, int len, int flag) +{ + int need_buff = 1; + char *buff = (char *)cmd; /* cast away const */ + int rcode = 0; + + if (len == -1) { + len = strlen(cmd); +#ifdef CONFIG_SYS_HUSH_PARSER + /* hush will never change our string */ + need_buff = 0; +#else + /* the built-in parser will change our string if it sees \n */ + need_buff = strchr(cmd, '\n') != NULL; +#endif } + if (need_buff) { + buff = malloc(len + 1); + if (!buff) + return 1; + memcpy(buff, cmd, len); + buff[len] = '\0'; + } +#ifdef CONFIG_SYS_HUSH_PARSER + rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON); +#else + /* + * This function will overwrite any \n it sees with a \0, which + * is why it can't work with a const char *. Here we are making + * using of internal knowledge of this function, to avoid always + * doing a malloc() which is actually required only in a case that + * is pretty rare. + */ + rcode = builtin_run_command_list(buff, flag); + if (need_buff) + free(buff); +#endif - return rc ? rc : repeatable; + return rcode; } /****************************************************************************/ @@ -1414,7 +1472,7 @@ int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) int i; if (argc < 2) - return cmd_usage(cmdtp); + return CMD_RET_USAGE; for (i=1; i