Dear all, Denys Vlasenko, the maintainer of BusyBox, asked me to organise a task to synchronise busybox ash and dash in such a way the future developments could benefit from each other's contributions. In particular this need raised after these patches has been applied: ash: add bash-like ERR trap and set -E https://git.busybox.net/busybox/commit/?id=e0bf3df0205d5ccef52df67b1760b8b54f15ec6e ash: fix LINENO in functions https://git.busybox.net/busybox/commit/?id=d6c9cbc0727cc3875672ae280ec129514a9d8594 ash: LINENO starts from 0 in -c SCRIPT mode https://git.busybox.net/busybox/commit/?id=64aa86b720641cb50be9636e6c20d4dbbea6fed0 ash: introduce bash-like $FUNCNAME https://git.busybox.net/busybox/commit/?id=704c596563a5b4da4349b272d0c9c71aacea34a7 These patches derive from a larger patch that I developed to improve the error management/debug in busybox ash. In brief these patches add the following functionalities: - trap ERR and set -E added - LINENO became a global variable - FUNCNAME global variable added Developing these patches we realised that the use of EXEXIT and EXEND exceptions complicates the code and do not add any value. Moreover, the code that these exceptions trigger (everywhere the setjmp() returns true) restores some values and frees some memory but the traps need the information before the restore, not the restored values. For these reason I developed three patches here in attachment: 1. get rid of EXEXIT in exitcmd() and fix a bug about return value 2. get rid of EXEND at the end of evaltree() 3. remove the EXEXIT and EXEND altogether The description of these patches are simply arbitrary and temporary. I hope we will agree on these details once we are going to port them to dash. Applying these patches the output printed by trap ERR and trap EXIT is what was expected to be demonstrating that to avoid these exceptions the code became straightforward. We are here to check your interest in porting these patches to dash and your will to apply. Our focus is related to the patches listed above but in the long run it is not limited to them but also includes the following patches. These patches have been applied in the meantime that others made changes to ash.c as well. The full list of patches and their order is listed here: https://git.busybox.net/busybox/log/ Other patches that have been applied that might be a convenience to port in dash are the following: ash: eval: Check nflag in evaltree instead of cmdloop https://git.busybox.net/busybox/commit/?id=41beb53787ec798a27f336c4758cb5ebd8f0c75a ash: eval: Do not cache value of eflag in evaltree https://git.busybox.net/busybox/commit/?id=f415e21a7dce1d4f4b760fddfaba85c551681e11 ash: parser: Fix handling of empty aliases https://git.busybox.net/busybox/commit/?id=30af5938afad076e12b8ece123cab0b8bc92a596 ash: parser: Save and restore heredoclist in expandstr https://git.busybox.net/busybox/commit/?id=1c06ddd8bbbd6906e5bf00ec93e04d5090718be9 ash: use pgetc_eatbnl() in more places, take 3 https://git.busybox.net/busybox/commit/?id=c54025612711a6b1997efd99206b9fbcaa5a29cf ash: parser: Fix alias expansion after heredoc or newlines https://git.busybox.net/busybox/commit/?id=8c68ae8416c8b54222eb3cd1d4908a570147e134 ash: parser: Get rid of PEOA https://git.busybox.net/busybox/commit/?id=48cb983b136fb74c61db594a30e18bdc42b7264c ash: eval: Prevent recursive PS4 expansion https://git.busybox.net/busybox/commit/?id=eb607777697f4c5eb2dfd86e5837a8c379f65979 ash: fix ignoreeof option https://git.busybox.net/busybox/commit/?id=0beee209778870888c3a80a9ae57e74888bc8e7b ash: stopped jobs should only prevent exit from interactive shell https://git.busybox.net/busybox/commit/?id=50239a665c88f5a95ce41146804500f5da90b19e ash: let ignoreeof only affect interactive shells https://git.busybox.net/busybox/commit/?id=5726df5f94f973eaa097d9853ceff2bd6b748d97 I wish to receive your feedback and I hope you are interested in the porting. Best regards, -- Roberto A. Foglietta +39.349.33.30.697
From 4ae8e1a35d69e5090f882f9919bbf9b6ebe24aaf Mon Sep 17 00:00:00 2001 From: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Date: Wed, 15 Sep 2021 13:34:34 +0200 Subject: [PATCH 3/3] EXEND and EXEXIT removed --- shell/ash.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 54814ab89..2fbf51df0 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -428,8 +428,6 @@ struct globals_misc { smallint exception_type; /* kind of exception: */ #define EXINT 0 /* SIGINT received */ #define EXERROR 1 /* a generic error */ -#define EXEND 3 /* exit the shell */ -#define EXEXIT 4 /* exit the shell via exitcmd */ char nullstr[1]; /* zero length string */ @@ -8346,7 +8344,11 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) exitstatus = exerrno; TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n", prog, e, suppress_int)); - ash_msg_and_raise(EXEND, "%s: %s", prog, errmsg(e, "not found")); + + ash_msg(msg, "%s: %s", prog, errmsg(e, "not found")); + flush_stdout_stderr(); + exitshell(); + /* NOTREACHED */ } @@ -9211,7 +9213,6 @@ static int evalstring(char *s, int flags); /* Called to execute a trap. * Single callsite - at the end of evaltree(). - * If we return non-zero, evaltree raises EXEXIT exception. * * Perhaps we should avoid entering new trap handlers * while we are executing a trap handler. [is it a TODO?] @@ -14323,7 +14324,7 @@ exitreset(void) { /* from eval.c: */ if (savestatus >= 0) { - if (exception_type == EXEXIT || evalskip == SKIPFUNCDEF) + if (evalskip == SKIPFUNCDEF) exitstatus = savestatus; savestatus = -1; } @@ -14609,7 +14610,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) e = exception_type; s = state; - if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) { + if (s == 0 || iflag == 0 || shlvl) { exitshell(); } -- 2.25.1
From 8c7a3761843cbbf951046302fa5236f341f1ef43 Mon Sep 17 00:00:00 2001 From: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Date: Wed, 15 Sep 2021 09:26:40 +0200 Subject: [PATCH 1/3] fix a bug in exitcmd() raised by Harald with s/EXEXIT/exitshell/ --- shell/ash.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 4bc4f55d0..9f35b0261 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -13648,19 +13648,15 @@ dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM) static int FAST_FUNC exitcmd(int argc UNUSED_PARAM, char **argv) { + if (argv[1]) + exitstatus = number(argv[1]); + else + exitstatus = 0; + if (stoppedjobs()) - return 0; + return exitstatus; - if (argv[1]) - savestatus = number(argv[1]); - -//TODO: this script -// trap 'echo trap:$FUNCNAME' EXIT -// f() { exit; } -// f -//prints "trap:f" in bash. We can call exitshell() here to achieve this. -//For now, keeping dash code: - raise_exception(EXEXIT); + exitshell(); /* NOTREACHED */ } -- 2.25.1
From 562a0767dec53fe25e235622c8d72b2826c1a189 Mon Sep 17 00:00:00 2001 From: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Date: Wed, 15 Sep 2021 09:32:03 +0200 Subject: [PATCH 2/3] FUNCNAME bugfix with s/EXEND/exitshell/ --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/ash.c b/shell/ash.c index 9f35b0261..54814ab89 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9427,7 +9427,7 @@ evaltree(union node *n, int flags) } if (flags & EV_EXIT) { exexit: - raise_exception(EXEND); + exitshell(); } popstackmark(&smark); -- 2.25.1