summaryrefslogtreecommitdiffhomepage
path: root/shell/ash.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-09-15 19:31:44 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-09-15 19:31:44 +0200
commit704c596563a5b4da4349b272d0c9c71aacea34a7 (patch)
tree126cb27fb1980deeedb76a6f2227eb1840f0d4d0 /shell/ash.c
parent3512ef801839feeb20d178776fff999e1da532fd (diff)
ash: introduce bash-like $FUNCNAME
Patch adapted from Roberto A. Foglietta <roberto.foglietta@gmail.com> work. function old new delta lookupvar 106 150 +44 evalfun 369 408 +39 ash_main 1218 1242 +24 varinit_data 156 168 +12 .rodata 104162 104172 +10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 129/0) Total: 129 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/shell/ash.c b/shell/ash.c
index b12b859d5..4bc4f55d0 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2158,6 +2158,7 @@ static const struct {
{ VSTRFIXED|VTEXTFIXED , defoptindvar, getoptsreset },
#endif
{ VSTRFIXED|VTEXTFIXED , NULL /* inited to linenovar */, NULL },
+ { VSTRFIXED|VTEXTFIXED , NULL /* inited to funcnamevar */, NULL },
#if ENABLE_ASH_RANDOM_SUPPORT
{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
#endif
@@ -2184,6 +2185,8 @@ struct globals_var {
struct var varinit[ARRAY_SIZE(varinit_data)];
int lineno;
char linenovar[sizeof("LINENO=") + sizeof(int)*3];
+ char funcnamevar[sizeof("FUNCNAME=") + 64];
+ char *funcname;
unsigned trap_depth;
bool in_trap_ERR; /* ERR cannot recurse, no need to be a counter */
};
@@ -2196,6 +2199,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
#define varinit (G_var.varinit )
#define lineno (G_var.lineno )
#define linenovar (G_var.linenovar )
+#define funcnamevar (G_var.funcnamevar )
+#define funcname (G_var.funcname )
#define trap_depth (G_var.trap_depth )
#define in_trap_ERR (G_var.in_trap_ERR )
#define vifs varinit[0]
@@ -2213,13 +2218,14 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
#endif
#define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS)
#define vlineno varinit[VAR_OFFSET2 + 5]
+#define vfuncname varinit[VAR_OFFSET2 + 6]
#if ENABLE_ASH_RANDOM_SUPPORT
-# define vrandom varinit[VAR_OFFSET2 + 6]
+# define vrandom varinit[VAR_OFFSET2 + 7]
#endif
#define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT)
#if BASH_EPOCH_VARS
-# define vepochs varinit[VAR_OFFSET3 + 6]
-# define vepochr varinit[VAR_OFFSET3 + 7]
+# define vepochs varinit[VAR_OFFSET3 + 7]
+# define vepochr varinit[VAR_OFFSET3 + 8]
#endif
#define INIT_G_var() do { \
unsigned i; \
@@ -2232,6 +2238,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
} \
strcpy(linenovar, "LINENO="); \
vlineno.var_text = linenovar; \
+ strcpy(funcnamevar, "FUNCNAME="); \
+ vfuncname.var_text = funcnamevar; \
} while (0)
/*
@@ -2371,6 +2379,9 @@ lookupvar(const char *name)
if (!(v->flags & VUNSET)) {
if (v->var_text == linenovar) {
fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
+ } else
+ if (v->var_text == funcnamevar) {
+ safe_strncpy(funcnamevar+9, funcname ? funcname : "", sizeof(funcnamevar)-9);
}
return var_end(v->var_text);
}
@@ -9875,6 +9886,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
int e;
int savelineno;
int savefuncline;
+ char *savefuncname;
char *savetrap = NULL;
if (!Eflag) {
@@ -9884,6 +9896,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
savelineno = lineno;
saveparam = shellparam;
savefuncline = funcline;
+ savefuncname = funcname;
savehandler = exception_handler;
e = setjmp(jmploc.loc);
if (e) {
@@ -9893,6 +9906,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
exception_handler = &jmploc;
shellparam.malloced = 0;
func->count++;
+ funcname = func->n.ndefun.text;
funcline = func->n.ndefun.linno;
INT_ON;
shellparam.nparam = argc - 1;
@@ -9904,6 +9918,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
evaltree(func->n.ndefun.body, flags & EV_TESTED);
funcdone:
INT_OFF;
+ funcname = savefuncname;
if (savetrap) {
if (!trap[NTRAP_ERR])
trap[NTRAP_ERR] = savetrap;
@@ -13639,6 +13654,12 @@ exitcmd(int argc UNUSED_PARAM, char **argv)
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);
/* NOTREACHED */
}