* [PATCH 1/4] Shell: Handle aborting loops better @ 2019-04-24 10:26 Sascha Hauer 2019-04-24 10:26 ` [PATCH 2/4] console: forbid ctrlc during startup Sascha Hauer ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Sascha Hauer @ 2019-04-24 10:26 UTC (permalink / raw) To: Barebox List It's easy to get stuck in an infinite loop in the hush shell: while true; do sleep 1; done The 'sleep' command will check for ctrl-c with the ctrlc() function. This will abort the sleep command. Hush then checks for ctrl-c again in the loop. The ctrl-c in the buffer has already been eaten by the sleep command, so the loop will continue. With this patch we remember the presence of a ctrl-c character in a variable instead of checking for a new character each time. The variable must be resetted explicitly by calling ctrlc_handled() which will be called by the shell in the outer loop. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/sandbox/os/common.c | 2 +- common/console.c | 28 +++++++++++++++++++++++----- common/hush.c | 3 ++- common/parser.c | 1 + include/common.h | 4 +++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c index 665e8194ef..a7ea8f2d3b 100644 --- a/arch/sandbox/os/common.c +++ b/arch/sandbox/os/common.c @@ -94,7 +94,7 @@ int linux_tstc(int fd) return 0; } -int ctrlc(void) +int arch_ctrlc(void) { char chr; diff --git a/common/console.c b/common/console.c index 47ccf2e54d..b6685ecf6a 100644 --- a/common/console.c +++ b/common/console.c @@ -574,18 +574,36 @@ void console_flush(void) } EXPORT_SYMBOL(console_flush); -#ifndef ARCH_HAS_CTRLC +static int ctrlc_abort; + +void ctrlc_handled(void) +{ + ctrlc_abort = 0; +} + /* test if ctrl-c was pressed */ -int ctrlc (void) +int ctrlc(void) { + int ret = 0; + + if (ctrlc_abort) + return 1; + poller_call(); +#ifdef ARCH_HAS_CTRLC + ret = arch_ctrlc(); +#else if (tstc() && getchar() == 3) - return 1; - return 0; + ret = 1; +#endif + + if (ret) + ctrlc_abort = 1; + + return ret; } EXPORT_SYMBOL(ctrlc); -#endif /* ARCH_HAS_CTRC */ BAREBOX_MAGICVAR_NAMED(global_linux_bootargs_console, global.linux.bootargs.console, "console= argument for Linux from the stdout-path property in /chosen node"); diff --git a/common/hush.c b/common/hush.c index d2f9cc70f5..dab9b04081 100644 --- a/common/hush.c +++ b/common/hush.c @@ -1734,7 +1734,7 @@ static int parse_stream_outer(struct p_context *ctx, struct in_str *inp, int fla return 1; } b_free(&temp); - } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */ + } while (!ctrlc() && rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */ return code; } @@ -1932,6 +1932,7 @@ int run_shell(void) login(); do { + ctrlc_handled(); setup_file_in_str(&input); rcode = parse_stream_outer(&ctx, &input, FLAG_PARSE_SEMICOLON); if (rcode < -1) { diff --git a/common/parser.c b/common/parser.c index 397d268da1..fb9ef42e7f 100644 --- a/common/parser.c +++ b/common/parser.c @@ -283,6 +283,7 @@ int run_shell(void) /* invalid command or not repeatable, forget it */ lastcommand[0] = 0; } + ctrlc_handled(); } } return 0; diff --git a/include/common.h b/include/common.h index 11d26cb3db..723b9c706c 100644 --- a/include/common.h +++ b/include/common.h @@ -68,7 +68,9 @@ int readline (const char *prompt, char *buf, int len); long get_ram_size (volatile long *, long); /* common/console.c */ -int ctrlc (void); +int ctrlc(void); +int arch_ctrlc(void); +void ctrlc_handled(void); #ifdef ARCH_HAS_STACK_DUMP void dump_stack(void); -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/4] console: forbid ctrlc during startup 2019-04-24 10:26 [PATCH 1/4] Shell: Handle aborting loops better Sascha Hauer @ 2019-04-24 10:26 ` Sascha Hauer 2019-04-24 10:26 ` [PATCH 3/4] console_countdown: Add pattern list Sascha Hauer 2019-04-24 10:26 ` [PATCH 4/4] defaultenv: Convert init script to C Sascha Hauer 2 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2019-04-24 10:26 UTC (permalink / raw) To: Barebox List When global.autoboot_abort_key is set to ctrl-c then the user is expected to press ctrl-c to get to the prompt. The user might press ctrl-c before the init script runs the "timeout" command. In this case the init script is aborted at arbitrary places which leads to inconsistent results depending on the place it is aborted. This patch introduces the global.console.ctrlc_allowed variable. When this variable is set to false ctrl-c is ignored entirely. The variable is set to false by default and changed to true in the init script. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- common/console.c | 24 ++++++++++++++++++++++++ defaultenv/defaultenv-2-base/bin/init | 2 ++ include/console.h | 3 +++ 3 files changed, 29 insertions(+) diff --git a/common/console.c b/common/console.c index b6685ecf6a..406722a1da 100644 --- a/common/console.c +++ b/common/console.c @@ -575,6 +575,7 @@ void console_flush(void) EXPORT_SYMBOL(console_flush); static int ctrlc_abort; +static int ctrlc_allowed; void ctrlc_handled(void) { @@ -586,6 +587,9 @@ int ctrlc(void) { int ret = 0; + if (!ctrlc_allowed) + return 0; + if (ctrlc_abort) return 1; @@ -605,5 +609,25 @@ int ctrlc(void) } EXPORT_SYMBOL(ctrlc); +static int console_ctrlc_init(void) +{ + globalvar_add_simple_bool("console.ctrlc_allowed", &ctrlc_allowed); + return 0; +} +device_initcall(console_ctrlc_init); + +void console_ctrlc_allow(void) +{ + ctrlc_allowed = 1; +} + +void console_ctrlc_forbid(void) +{ + ctrlc_allowed = 0; +} + +BAREBOX_MAGICVAR_NAMED(global_console_ctrlc_allowed, global.console.ctrlc_allowed, + "If true, scripts can be aborted with ctrl-c"); + BAREBOX_MAGICVAR_NAMED(global_linux_bootargs_console, global.linux.bootargs.console, "console= argument for Linux from the stdout-path property in /chosen node"); diff --git a/defaultenv/defaultenv-2-base/bin/init b/defaultenv/defaultenv-2-base/bin/init index 8d02e3d3ab..a5d3a984f7 100644 --- a/defaultenv/defaultenv-2-base/bin/init +++ b/defaultenv/defaultenv-2-base/bin/init @@ -60,6 +60,8 @@ if [ "$autoboot" = 0 ]; then autoboot="$?" fi +global.console.ctrlc_allowed=true + if [ "${key}" = "q" ]; then exit fi diff --git a/include/console.h b/include/console.h index 673921331d..4062e5abf6 100644 --- a/include/console.h +++ b/include/console.h @@ -207,4 +207,7 @@ static inline void pbl_set_putc(void (*putcf)(void *ctx, int c), void *ctx) {} bool console_allow_color(void); +void console_ctrlc_allow(void); +void console_ctrlc_forbid(void); + #endif -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/4] console_countdown: Add pattern list 2019-04-24 10:26 [PATCH 1/4] Shell: Handle aborting loops better Sascha Hauer 2019-04-24 10:26 ` [PATCH 2/4] console: forbid ctrlc during startup Sascha Hauer @ 2019-04-24 10:26 ` Sascha Hauer 2019-04-24 10:26 ` [PATCH 4/4] defaultenv: Convert init script to C Sascha Hauer 2 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2019-04-24 10:26 UTC (permalink / raw) To: Barebox List This adds an optional string argument to console_countdown() which can hold a list of keys which also abort the countdown. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- commands/timeout.c | 2 +- common/console_countdown.c | 19 ++++++++++++++++++- include/console_countdown.h | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/commands/timeout.c b/commands/timeout.c index d197cedd8b..db88900287 100644 --- a/commands/timeout.c +++ b/commands/timeout.c @@ -61,7 +61,7 @@ static int do_timeout(int argc, char *argv[]) return COMMAND_ERROR_USAGE; timeout = simple_strtoul(argv[optind], NULL, 0); - ret = console_countdown(timeout, flags, str); + ret = console_countdown(timeout, flags, NULL, str); if (varname && str[0]) setenv(varname, str); diff --git a/common/console_countdown.c b/common/console_countdown.c index 36da1ce577..8d09894c30 100644 --- a/common/console_countdown.c +++ b/common/console_countdown.c @@ -30,7 +30,22 @@ void console_countdown_abort(void) console_countdown_timeout_abort = true; } -int console_countdown(int timeout_s, unsigned flags, char *out_key) +static int key_in_list(char key, const char *keys) +{ + if (!keys) + return false; + + while (*keys) { + if (key == *keys) + return true; + keys++; + } + + return false; +} + +int console_countdown(int timeout_s, unsigned flags, const char *keys, + char *out_key) { uint64_t start, second; int countdown, ret = -EINTR; @@ -48,6 +63,8 @@ int console_countdown(int timeout_s, unsigned flags, char *out_key) if (tstc()) { key = getchar(); if (key >= 0) { + if (key_in_list(key, keys)) + goto out; if (flags & CONSOLE_COUNTDOWN_ANYKEY) goto out; if (flags & CONSOLE_COUNTDOWN_RETURN && key == '\n') diff --git a/include/console_countdown.h b/include/console_countdown.h index c6c2d5c00e..88cadf11ec 100644 --- a/include/console_countdown.h +++ b/include/console_countdown.h @@ -7,7 +7,7 @@ #define CONSOLE_COUNTDOWN_CTRLC (1 << 4) #define CONSOLE_COUNTDOWN_EXTERN (1 << 5) -int console_countdown(int timeout_s, unsigned flags, char *out_key); +int console_countdown(int timeout_s, unsigned flags, const char *keys, char *out_key); void console_countdown_abort(void); #endif /* __CONSOLE_COUNTDOWN_H */ -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/4] defaultenv: Convert init script to C 2019-04-24 10:26 [PATCH 1/4] Shell: Handle aborting loops better Sascha Hauer 2019-04-24 10:26 ` [PATCH 2/4] console: forbid ctrlc during startup Sascha Hauer 2019-04-24 10:26 ` [PATCH 3/4] console_countdown: Add pattern list Sascha Hauer @ 2019-04-24 10:26 ` Sascha Hauer 2019-04-26 12:37 ` Roland Hieber 2 siblings, 1 reply; 6+ messages in thread From: Sascha Hauer @ 2019-04-24 10:26 UTC (permalink / raw) To: Barebox List It's hard to get more complicated things right in hush. This commit converts the /env/bin/init script to C code. With this we get a better error handling and better control what is being done. If /env/bin/init exists in the environment then it is still executed instead of the corresponding C code. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- common/startup.c | 188 +++++++++++++++++++++++--- defaultenv/defaultenv-2-base/bin/init | 79 ----------- 2 files changed, 169 insertions(+), 98 deletions(-) delete mode 100644 defaultenv/defaultenv-2-base/bin/init diff --git a/common/startup.c b/common/startup.c index 28edee4fce..9fac0eabbd 100644 --- a/common/startup.c +++ b/common/startup.c @@ -42,6 +42,9 @@ #include <asm/sections.h> #include <uncompress.h> #include <globalvar.h> +#include <console_countdown.h> +#include <environment.h> +#include <linux/ctype.h> extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[], __barebox_initcalls_end[]; @@ -143,16 +146,172 @@ static int load_environment(void) environment_initcall(load_environment); #endif +static int global_autoboot_abort_key; +static const char * const global_autoboot_abort_keys[] = { + "any", + "ctrl-c", +}; +static int global_autoboot_timeout = 3; +static char *global_boot_default; +static char *global_editcmd; +static char *global_linux_bootargs_base; +static char *global_linux_bootargs_console; +static char *global_linux_bootargs_dyn_ip; +static char *global_linux_bootargs_dyn_root; +static char *global_user; + +static bool test_abort(void) +{ + bool do_abort = false; + int c, ret; + char key; + + while (tstc()) { + c = getchar(); + if (tolower(c) == 'q' || c == 3) + do_abort = true; + } + + if (!do_abort) + return false; + + printf("Abort init sequence? (y/n)\n" + "Will continue with init sequence in:"); + + ret = console_countdown(5, CONSOLE_COUNTDOWN_EXTERN, "yYnN", &key); + if (!ret) + return false; + + if (tolower(key) == 'y') + return true; + + return false; +} + +static int run_init(void) +{ + DIR *dir; + struct dirent *d; + const char *initfile = "/env/bin/init"; + const char *initdir = "/env/init"; + const char *menufile = "/env/menu/mainmenu"; + struct stat s; + unsigned flags = CONSOLE_COUNTDOWN_EXTERN; + unsigned char outkey; + int ret; + bool menu_exists; + bool env_bin_init_exists; + char *abortkeys = NULL; + + setenv("PATH", "/env/bin"); + + /* Run legacy /env/bin/init if it exists */ + env_bin_init_exists = stat(initfile, &s) == 0; + if (env_bin_init_exists) { + pr_info("running %s...\n", initfile); + run_command(initfile); + return 0; + } + + global_editcmd = xstrdup("sedit"); + global_user = xstrdup("none"); + globalvar_add_simple_string("user", &global_user); + global_boot_default = xstrdup("net"); + + globalvar_add_simple_enum("autoboot_abort_key", + &global_autoboot_abort_key, + global_autoboot_abort_keys, + ARRAY_SIZE(global_autoboot_abort_keys)); + globalvar_add_simple_int("autoboot_timeout", + &global_autoboot_timeout, "%u"); + globalvar_add_simple_string("boot.default", &global_boot_default); + globalvar_add_simple_string("editcmd", &global_editcmd); + globalvar_add_simple_string("linux.bootargs.base", + &global_linux_bootargs_base); + globalvar_add_simple_string("linux.bootargs.console", + &global_linux_bootargs_console); + globalvar_add_simple_string("linux.bootargs.dyn.ip", + &global_linux_bootargs_dyn_ip); + globalvar_add_simple_string("linux.bootargs.dyn.root", + &global_linux_bootargs_dyn_root); + + /* Unblank console cursor */ + printf("\e[?25h"); + + if (test_abort()) { + pr_info("Init sequence aborted\n"); + return -EINTR; + } + + /* Run scripts in /env/init/ */ + dir = opendir(initdir); + if (dir) { + char *scr; + + while ((d = readdir(dir))) { + if (*d->d_name == '.') + continue; + + pr_debug("Executing '%s/%s'...\n", initdir, d->d_name); + scr = basprintf("source %s/%s", initdir, d->d_name); + run_command(scr); + free(scr); + } + + closedir(dir); + } + + menu_exists = stat(menufile, &s) == 0; + + if (menu_exists) { + printf("\nHit m for menu or %s to stop autoboot: ", + global_autoboot_abort_keys[global_autoboot_abort_key]); + abortkeys = "m"; + } else { + printf("\nHit %s to stop autoboot: ", + global_autoboot_abort_keys[global_autoboot_abort_key]); + } + + switch (global_autoboot_abort_key) { + case 0: + flags |= CONSOLE_COUNTDOWN_ANYKEY; + break; + case 1: + flags |= CONSOLE_COUNTDOWN_CTRLC; + break; + default: + break; + } + + ret = console_countdown(global_autoboot_timeout, flags, abortkeys, + &outkey); + + if (ret == 0) + run_command("boot"); + + console_ctrlc_allow(); + + if (menu_exists) { + if (outkey == 'm') + run_command(menufile); + + printf("Enter 'exit' to get back to the menu\n"); + run_shell(); + run_command(menufile); + } + + return 0; +} + int (*barebox_main)(void); void __noreturn start_barebox(void) { initcall_t *initcall; int result; - struct stat s; - if (!IS_ENABLED(CONFIG_SHELL_NONE)) - barebox_main = run_shell; + if (!IS_ENABLED(CONFIG_SHELL_NONE) && IS_ENABLED(CONFIG_COMMAND_SUPPORT)) + barebox_main = run_init; for (initcall = __barebox_initcalls_start; initcall < __barebox_initcalls_end; initcall++) { @@ -165,25 +324,16 @@ void __noreturn start_barebox(void) pr_debug("initcalls done\n"); - if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) { - pr_info("running /env/bin/init...\n"); - - if (!stat("/env/bin/init", &s)) - run_command("source /env/bin/init"); - else - pr_err("/env/bin/init not found\n"); - } + if (barebox_main) + barebox_main(); - if (!barebox_main) { - pr_err("No main function! aborting.\n"); + if (IS_ENABLED(CONFIG_SHELL_NONE)) { + pr_err("Nothing left to do\n"); hang(); + } else { + while (1) + run_shell(); } - - /* main_loop() can return to retry autoboot, if so just run it again. */ - for (;;) - barebox_main(); - - /* NOTREACHED - no way out of command loop except booting */ } void __noreturn hang (void) diff --git a/defaultenv/defaultenv-2-base/bin/init b/defaultenv/defaultenv-2-base/bin/init deleted file mode 100644 index a5d3a984f7..0000000000 --- a/defaultenv/defaultenv-2-base/bin/init +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -export PATH=/env/bin - -global hostname -global user -global autoboot_timeout -global autoboot_abort_key -global boot.default -global linux.bootargs.base -global linux.bootargs.console -#linux.bootargs.dyn.* will be cleared at the beginning of boot -global linux.bootargs.dyn.ip -global linux.bootargs.dyn.root -global editcmd - -[ -z "${global.hostname}" ] && global.hostname=generic -[ -z "${global.user}" ] && global.user=none -magicvar -a global.user "username (used in network filenames)" -[ -z "${global.autoboot_timeout}" ] && global.autoboot_timeout=3 -magicvar -a global.autoboot_timeout "timeout in seconds before automatic booting" -[ -z "${global.autoboot_abort_key}" ] && global.autoboot_abort_key=any -magicvar -a global.autoboot_abort_key "key to abort automatic booting (valid options: any, ctrl-c)" -[ -z "${global.boot.default}" ] && global.boot.default=net -[ -z "${global.editcmd}" ] && global.editcmd=sedit - -[ -e /env/config-board ] && /env/config-board -/env/config - -# allow to stop the boot before execute the /env/init/* -# but without waiting -timeout -s -a -v key 0 -autoboot="$?" - -echo -e -n "\e[?25h" -if [ "${key}" = "q" ]; then - exit -fi - -for i in /env/init/*; do - . $i -done - -if [ "${global.autoboot_abort_key}" = "ctrl-c" ]; then - abort_string="ctrl-c" - abort_args="-c" -else - abort_string="any key" - abort_args="-a" -fi - -if [ -e /env/menu ]; then - echo -e -n "\nHit m for menu or $abort_string to stop autoboot: " -else - echo -e -n "\nHit $abort_string to stop autoboot: " -fi - -if [ "$autoboot" = 0 ]; then - timeout $abort_args $global.autoboot_timeout -v key - autoboot="$?" -fi - -global.console.ctrlc_allowed=true - -if [ "${key}" = "q" ]; then - exit -fi - -if [ "$autoboot" = 0 ]; then - boot -fi - -if [ -e /env/menu ]; then - if [ "${key}" != "m" ]; then - echo -e "\ntype exit to get to the menu" - sh - fi - /env/menu/mainmenu -fi -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 4/4] defaultenv: Convert init script to C 2019-04-24 10:26 ` [PATCH 4/4] defaultenv: Convert init script to C Sascha Hauer @ 2019-04-26 12:37 ` Roland Hieber 2019-04-29 6:57 ` Sascha Hauer 0 siblings, 1 reply; 6+ messages in thread From: Roland Hieber @ 2019-04-26 12:37 UTC (permalink / raw) To: Sascha Hauer; +Cc: Barebox List Hi Sascha, small note: one might want to interrupt long-running processes during the init sequence, e.g. if an init script contains a "dhcp" call or does some NFS mount, but the board is currently not connected to the network. Now it is no longer possible to interrupt such processes, even when global.autoboot_abort_key is set to anything else than "ctrl-c". Was this use case considered? - Roland On Wed, Apr 24, 2019 at 12:26:50PM +0200, Sascha Hauer wrote: > It's hard to get more complicated things right in hush. This commit > converts the /env/bin/init script to C code. With this we get a better > error handling and better control what is being done. > > If /env/bin/init exists in the environment then it is still executed > instead of the corresponding C code. > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > --- > common/startup.c | 188 +++++++++++++++++++++++--- > defaultenv/defaultenv-2-base/bin/init | 79 ----------- > 2 files changed, 169 insertions(+), 98 deletions(-) > delete mode 100644 defaultenv/defaultenv-2-base/bin/init > > diff --git a/common/startup.c b/common/startup.c > index 28edee4fce..9fac0eabbd 100644 > --- a/common/startup.c > +++ b/common/startup.c > @@ -42,6 +42,9 @@ > #include <asm/sections.h> > #include <uncompress.h> > #include <globalvar.h> > +#include <console_countdown.h> > +#include <environment.h> > +#include <linux/ctype.h> > > extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[], > __barebox_initcalls_end[]; > @@ -143,16 +146,172 @@ static int load_environment(void) > environment_initcall(load_environment); > #endif > > +static int global_autoboot_abort_key; > +static const char * const global_autoboot_abort_keys[] = { > + "any", > + "ctrl-c", > +}; > +static int global_autoboot_timeout = 3; > +static char *global_boot_default; > +static char *global_editcmd; > +static char *global_linux_bootargs_base; > +static char *global_linux_bootargs_console; > +static char *global_linux_bootargs_dyn_ip; > +static char *global_linux_bootargs_dyn_root; > +static char *global_user; > + > +static bool test_abort(void) > +{ > + bool do_abort = false; > + int c, ret; > + char key; > + > + while (tstc()) { > + c = getchar(); > + if (tolower(c) == 'q' || c == 3) > + do_abort = true; > + } > + > + if (!do_abort) > + return false; > + > + printf("Abort init sequence? (y/n)\n" > + "Will continue with init sequence in:"); > + > + ret = console_countdown(5, CONSOLE_COUNTDOWN_EXTERN, "yYnN", &key); > + if (!ret) > + return false; > + > + if (tolower(key) == 'y') > + return true; > + > + return false; > +} > + > +static int run_init(void) > +{ > + DIR *dir; > + struct dirent *d; > + const char *initfile = "/env/bin/init"; > + const char *initdir = "/env/init"; > + const char *menufile = "/env/menu/mainmenu"; > + struct stat s; > + unsigned flags = CONSOLE_COUNTDOWN_EXTERN; > + unsigned char outkey; > + int ret; > + bool menu_exists; > + bool env_bin_init_exists; > + char *abortkeys = NULL; > + > + setenv("PATH", "/env/bin"); > + > + /* Run legacy /env/bin/init if it exists */ > + env_bin_init_exists = stat(initfile, &s) == 0; > + if (env_bin_init_exists) { > + pr_info("running %s...\n", initfile); > + run_command(initfile); > + return 0; > + } > + > + global_editcmd = xstrdup("sedit"); > + global_user = xstrdup("none"); > + globalvar_add_simple_string("user", &global_user); > + global_boot_default = xstrdup("net"); > + > + globalvar_add_simple_enum("autoboot_abort_key", > + &global_autoboot_abort_key, > + global_autoboot_abort_keys, > + ARRAY_SIZE(global_autoboot_abort_keys)); > + globalvar_add_simple_int("autoboot_timeout", > + &global_autoboot_timeout, "%u"); > + globalvar_add_simple_string("boot.default", &global_boot_default); > + globalvar_add_simple_string("editcmd", &global_editcmd); > + globalvar_add_simple_string("linux.bootargs.base", > + &global_linux_bootargs_base); > + globalvar_add_simple_string("linux.bootargs.console", > + &global_linux_bootargs_console); > + globalvar_add_simple_string("linux.bootargs.dyn.ip", > + &global_linux_bootargs_dyn_ip); > + globalvar_add_simple_string("linux.bootargs.dyn.root", > + &global_linux_bootargs_dyn_root); > + > + /* Unblank console cursor */ > + printf("\e[?25h"); > + > + if (test_abort()) { > + pr_info("Init sequence aborted\n"); > + return -EINTR; > + } > + > + /* Run scripts in /env/init/ */ > + dir = opendir(initdir); > + if (dir) { > + char *scr; > + > + while ((d = readdir(dir))) { > + if (*d->d_name == '.') > + continue; > + > + pr_debug("Executing '%s/%s'...\n", initdir, d->d_name); > + scr = basprintf("source %s/%s", initdir, d->d_name); > + run_command(scr); > + free(scr); > + } > + > + closedir(dir); > + } > + > + menu_exists = stat(menufile, &s) == 0; > + > + if (menu_exists) { > + printf("\nHit m for menu or %s to stop autoboot: ", > + global_autoboot_abort_keys[global_autoboot_abort_key]); > + abortkeys = "m"; > + } else { > + printf("\nHit %s to stop autoboot: ", > + global_autoboot_abort_keys[global_autoboot_abort_key]); > + } > + > + switch (global_autoboot_abort_key) { > + case 0: > + flags |= CONSOLE_COUNTDOWN_ANYKEY; > + break; > + case 1: > + flags |= CONSOLE_COUNTDOWN_CTRLC; > + break; > + default: > + break; > + } > + > + ret = console_countdown(global_autoboot_timeout, flags, abortkeys, > + &outkey); > + > + if (ret == 0) > + run_command("boot"); > + > + console_ctrlc_allow(); > + > + if (menu_exists) { > + if (outkey == 'm') > + run_command(menufile); > + > + printf("Enter 'exit' to get back to the menu\n"); > + run_shell(); > + run_command(menufile); > + } > + > + return 0; > +} > + > int (*barebox_main)(void); > > void __noreturn start_barebox(void) > { > initcall_t *initcall; > int result; > - struct stat s; > > - if (!IS_ENABLED(CONFIG_SHELL_NONE)) > - barebox_main = run_shell; > + if (!IS_ENABLED(CONFIG_SHELL_NONE) && IS_ENABLED(CONFIG_COMMAND_SUPPORT)) > + barebox_main = run_init; > > for (initcall = __barebox_initcalls_start; > initcall < __barebox_initcalls_end; initcall++) { > @@ -165,25 +324,16 @@ void __noreturn start_barebox(void) > > pr_debug("initcalls done\n"); > > - if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) { > - pr_info("running /env/bin/init...\n"); > - > - if (!stat("/env/bin/init", &s)) > - run_command("source /env/bin/init"); > - else > - pr_err("/env/bin/init not found\n"); > - } > + if (barebox_main) > + barebox_main(); > > - if (!barebox_main) { > - pr_err("No main function! aborting.\n"); > + if (IS_ENABLED(CONFIG_SHELL_NONE)) { > + pr_err("Nothing left to do\n"); > hang(); > + } else { > + while (1) > + run_shell(); > } > - > - /* main_loop() can return to retry autoboot, if so just run it again. */ > - for (;;) > - barebox_main(); > - > - /* NOTREACHED - no way out of command loop except booting */ > } > > void __noreturn hang (void) > diff --git a/defaultenv/defaultenv-2-base/bin/init b/defaultenv/defaultenv-2-base/bin/init > deleted file mode 100644 > index a5d3a984f7..0000000000 > --- a/defaultenv/defaultenv-2-base/bin/init > +++ /dev/null > @@ -1,79 +0,0 @@ > -#!/bin/sh > - > -export PATH=/env/bin > - > -global hostname > -global user > -global autoboot_timeout > -global autoboot_abort_key > -global boot.default > -global linux.bootargs.base > -global linux.bootargs.console > -#linux.bootargs.dyn.* will be cleared at the beginning of boot > -global linux.bootargs.dyn.ip > -global linux.bootargs.dyn.root > -global editcmd > - > -[ -z "${global.hostname}" ] && global.hostname=generic > -[ -z "${global.user}" ] && global.user=none > -magicvar -a global.user "username (used in network filenames)" > -[ -z "${global.autoboot_timeout}" ] && global.autoboot_timeout=3 > -magicvar -a global.autoboot_timeout "timeout in seconds before automatic booting" > -[ -z "${global.autoboot_abort_key}" ] && global.autoboot_abort_key=any > -magicvar -a global.autoboot_abort_key "key to abort automatic booting (valid options: any, ctrl-c)" > -[ -z "${global.boot.default}" ] && global.boot.default=net > -[ -z "${global.editcmd}" ] && global.editcmd=sedit > - > -[ -e /env/config-board ] && /env/config-board > -/env/config > - > -# allow to stop the boot before execute the /env/init/* > -# but without waiting > -timeout -s -a -v key 0 > -autoboot="$?" > - > -echo -e -n "\e[?25h" > -if [ "${key}" = "q" ]; then > - exit > -fi > - > -for i in /env/init/*; do > - . $i > -done > - > -if [ "${global.autoboot_abort_key}" = "ctrl-c" ]; then > - abort_string="ctrl-c" > - abort_args="-c" > -else > - abort_string="any key" > - abort_args="-a" > -fi > - > -if [ -e /env/menu ]; then > - echo -e -n "\nHit m for menu or $abort_string to stop autoboot: " > -else > - echo -e -n "\nHit $abort_string to stop autoboot: " > -fi > - > -if [ "$autoboot" = 0 ]; then > - timeout $abort_args $global.autoboot_timeout -v key > - autoboot="$?" > -fi > - > -global.console.ctrlc_allowed=true > - > -if [ "${key}" = "q" ]; then > - exit > -fi > - > -if [ "$autoboot" = 0 ]; then > - boot > -fi > - > -if [ -e /env/menu ]; then > - if [ "${key}" != "m" ]; then > - echo -e "\ntype exit to get to the menu" > - sh > - fi > - /env/menu/mainmenu > -fi > -- > 2.20.1 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Roland Hieber | r.hieber@pengutronix.de | Pengutronix e.K. | https://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim | Phone: +49-5121-206917-5086 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 4/4] defaultenv: Convert init script to C 2019-04-26 12:37 ` Roland Hieber @ 2019-04-29 6:57 ` Sascha Hauer 0 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2019-04-29 6:57 UTC (permalink / raw) To: Roland Hieber; +Cc: Barebox List On Fri, Apr 26, 2019 at 02:37:05PM +0200, Roland Hieber wrote: > Hi Sascha, > > small note: one might want to interrupt long-running processes during > the init sequence, e.g. if an init script contains a "dhcp" call or does > some NFS mount, but the board is currently not connected to the network. Do you have a better example? You shouldn't run dhcp in an init script. > Now it is no longer possible to interrupt such processes, even when > global.autoboot_abort_key is set to anything else than "ctrl-c". Was > this use case considered? You can't abort the init sequence, but you can prevent it from being executed at all. So when you are in such a situation, reset the board and use ctrl-c or 'q' to not run the init sequence. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-04-29 6:57 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-04-24 10:26 [PATCH 1/4] Shell: Handle aborting loops better Sascha Hauer 2019-04-24 10:26 ` [PATCH 2/4] console: forbid ctrlc during startup Sascha Hauer 2019-04-24 10:26 ` [PATCH 3/4] console_countdown: Add pattern list Sascha Hauer 2019-04-24 10:26 ` [PATCH 4/4] defaultenv: Convert init script to C Sascha Hauer 2019-04-26 12:37 ` Roland Hieber 2019-04-29 6:57 ` Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox