Commit d51004a832a9784f4c6af5482d4dace6bfd938c4

Authored by Simon Glass
Committed by Wolfgang Denk
1 parent 213adf6dff
Exists in master and in 55 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

Add run_command_list() to run a list of commands

This new function runs a list of commands separated by semicolon or newline.
We move this out of cmd_source so that it can be used by other code. The
PXE code also uses the new function.

Suggested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 4 changed files with 102 additions and 65 deletions Side-by-side Diff

... ... @@ -554,33 +554,19 @@
554 554 */
555 555 static int label_localboot(struct pxe_label *label)
556 556 {
557   - char *localcmd, *dupcmd;
558   - int ret;
  557 + char *localcmd;
559 558  
560 559 localcmd = from_env("localcmd");
561 560  
562 561 if (!localcmd)
563 562 return -ENOENT;
564 563  
565   - /*
566   - * dup the command to avoid any issues with the version of it existing
567   - * in the environment changing during the execution of the command.
568   - */
569   - dupcmd = strdup(localcmd);
570   -
571   - if (!dupcmd)
572   - return -ENOMEM;
573   -
574 564 if (label->append)
575 565 setenv("bootargs", label->append);
576 566  
577   - printf("running: %s\n", dupcmd);
  567 + debug("running: %s\n", localcmd);
578 568  
579   - ret = run_command(dupcmd, 0);
580   -
581   - free(dupcmd);
582   -
583   - return ret;
  569 + return run_command_list(localcmd, strlen(localcmd), 0);
584 570 }
585 571  
586 572 /*
... ... @@ -39,9 +39,6 @@
39 39 #if defined(CONFIG_8xx)
40 40 #include <mpc8xx.h>
41 41 #endif
42   -#ifdef CONFIG_SYS_HUSH_PARSER
43   -#include <hush.h>
44   -#endif
45 42  
46 43 int
47 44 source (ulong addr, const char *fit_uname)
... ... @@ -49,8 +46,6 @@
49 46 ulong len;
50 47 image_header_t *hdr;
51 48 ulong *data;
52   - char *cmd;
53   - int rcode = 0;
54 49 int verify;
55 50 #if defined(CONFIG_FIT)
56 51 const void* fit_hdr;
... ... @@ -151,49 +146,7 @@
151 146 }
152 147  
153 148 debug ("** Script length: %ld\n", len);
154   -
155   - if ((cmd = malloc (len + 1)) == NULL) {
156   - return 1;
157   - }
158   -
159   - /* make sure cmd is null terminated */
160   - memmove (cmd, (char *)data, len);
161   - *(cmd + len) = 0;
162   -
163   -#ifdef CONFIG_SYS_HUSH_PARSER /*?? */
164   - rcode = parse_string_outer (cmd, FLAG_PARSE_SEMICOLON);
165   -#else
166   - {
167   - char *line = cmd;
168   - char *next = cmd;
169   -
170   - /*
171   - * break into individual lines,
172   - * and execute each line;
173   - * terminate on error.
174   - */
175   - while (*next) {
176   - if (*next == '\n') {
177   - *next = '\0';
178   - /* run only non-empty commands */
179   - if (*line) {
180   - debug ("** exec: \"%s\"\n",
181   - line);
182   - if (run_command(line, 0) < 0) {
183   - rcode = 1;
184   - break;
185   - }
186   - }
187   - line = next + 1;
188   - }
189   - ++next;
190   - }
191   - if (rcode == 0 && *line)
192   - rcode = (run_command(line, 0) >= 0);
193   - }
194   -#endif
195   - free (cmd);
196   - return rcode;
  149 + return run_command_list((char *)data, len, 0);
197 150 }
198 151  
199 152 /**************************************************/
... ... @@ -30,6 +30,7 @@
30 30 #include <common.h>
31 31 #include <watchdog.h>
32 32 #include <command.h>
  33 +#include <malloc.h>
33 34 #include <version.h>
34 35 #ifdef CONFIG_MODEM_SUPPORT
35 36 #include <malloc.h> /* for free() prototype */
... ... @@ -1371,6 +1372,90 @@
1371 1372 return parse_string_outer(cmd,
1372 1373 FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
1373 1374 #endif
  1375 +}
  1376 +
  1377 +#ifndef CONFIG_SYS_HUSH_PARSER
  1378 +/**
  1379 + * Execute a list of command separated by ; or \n using the built-in parser.
  1380 + *
  1381 + * This function cannot take a const char * for the command, since if it
  1382 + * finds newlines in the string, it replaces them with \0.
  1383 + *
  1384 + * @param cmd String containing list of commands
  1385 + * @param flag Execution flags (CMD_FLAG_...)
  1386 + * @return 0 on success, or != 0 on error.
  1387 + */
  1388 +static int builtin_run_command_list(char *cmd, int flag)
  1389 +{
  1390 + char *line, *next;
  1391 + int rcode = 0;
  1392 +
  1393 + /*
  1394 + * Break into individual lines, and execute each line; terminate on
  1395 + * error.
  1396 + */
  1397 + line = next = cmd;
  1398 + while (*next) {
  1399 + if (*next == '\n') {
  1400 + *next = '\0';
  1401 + /* run only non-empty commands */
  1402 + if (*line) {
  1403 + debug("** exec: \"%s\"\n", line);
  1404 + if (builtin_run_command(line, 0) < 0) {
  1405 + rcode = 1;
  1406 + break;
  1407 + }
  1408 + }
  1409 + line = next + 1;
  1410 + }
  1411 + ++next;
  1412 + }
  1413 + if (rcode == 0 && *line)
  1414 + rcode = (builtin_run_command(line, 0) >= 0);
  1415 +
  1416 + return rcode;
  1417 +}
  1418 +#endif
  1419 +
  1420 +int run_command_list(const char *cmd, int len, int flag)
  1421 +{
  1422 + int need_buff = 1;
  1423 + char *buff = (char *)cmd; /* cast away const */
  1424 + int rcode = 0;
  1425 +
  1426 + if (len == -1) {
  1427 + len = strlen(cmd);
  1428 +#ifdef CONFIG_SYS_HUSH_PARSER
  1429 + /* hush will never change our string */
  1430 + need_buff = 0;
  1431 +#else
  1432 + /* the built-in parser will change our string if it sees \n */
  1433 + need_buff = strchr(cmd, '\n') != NULL;
  1434 +#endif
  1435 + }
  1436 + if (need_buff) {
  1437 + buff = malloc(len + 1);
  1438 + if (!buff)
  1439 + return 1;
  1440 + memcpy(buff, cmd, len);
  1441 + buff[len] = '\0';
  1442 + }
  1443 +#ifdef CONFIG_SYS_HUSH_PARSER
  1444 + rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON);
  1445 +#else
  1446 + /*
  1447 + * This function will overwrite any \n it sees with a \0, which
  1448 + * is why it can't work with a const char *. Here we are making
  1449 + * using of internal knowledge of this function, to avoid always
  1450 + * doing a malloc() which is actually required only in a case that
  1451 + * is pretty rare.
  1452 + */
  1453 + rcode = builtin_run_command_list(buff, flag);
  1454 + if (need_buff)
  1455 + free(buff);
  1456 +#endif
  1457 +
  1458 + return rcode;
1374 1459 }
1375 1460  
1376 1461 /****************************************************************************/
... ... @@ -286,6 +286,19 @@
286 286 /* common/main.c */
287 287 void main_loop (void);
288 288 int run_command(const char *cmd, int flag);
  289 +
  290 +/**
  291 + * Run a list of commands separated by ; or even \0
  292 + *
  293 + * Note that if 'len' is not -1, then the command does not need to be nul
  294 + * terminated, Memory will be allocated for the command in that case.
  295 + *
  296 + * @param cmd List of commands to run, each separated bu semicolon
  297 + * @param len Length of commands excluding terminator if known (-1 if not)
  298 + * @param flag Execution flags (CMD_FLAG_...)
  299 + * @return 0 on success, or != 0 on error.
  300 + */
  301 +int run_command_list(const char *cmd, int len, int flag);
289 302 int readline (const char *const prompt);
290 303 int readline_into_buffer(const char *const prompt, char *buffer,
291 304 int timeout);