[PATCH] ash: add bash-compatible EPOCH variables
Ron Yorston
rmy at pobox.com
Tue Apr 9 07:28:07 UTC 2019
Bash 5.0 added the dynamic variable EPOCHSECONDS and EPOCHREALTIME
which return the number of seconds since the Unix Epoch as an
integer or float. These are useful for logging or tracing.
function old new delta
change_epoch - 76 +76
.rodata 174183 174252 +69
varinit_data 264 312 +48
change_seconds - 24 +24
change_realtime - 24 +24
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 2/0 up/down: 241/0) Total: 241 bytes
text data bss dec hex filename
930384 4191 1888 936463 e4a0f busybox_old
930577 4191 1888 936656 e4ad0 busybox_unstripped
193 bytes of bloat, not 241.
Signed-off-by: Ron Yorston <rmy at pobox.com>
---
shell/ash.c | 77 ++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 56 insertions(+), 21 deletions(-)
diff --git a/shell/ash.c b/shell/ash.c
index 255d57e62..623ab4103 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -220,6 +220,7 @@
#define BASH_SOURCE ENABLE_ASH_BASH_COMPAT
#define BASH_PIPEFAIL ENABLE_ASH_BASH_COMPAT
#define BASH_HOSTNAME_VAR ENABLE_ASH_BASH_COMPAT
+#define BASH_EPOCH_VARS ENABLE_ASH_BASH_COMPAT
#define BASH_SHLVL_VAR ENABLE_ASH_BASH_COMPAT
#define BASH_XTRACEFD ENABLE_ASH_BASH_COMPAT
#define BASH_READ_D ENABLE_ASH_BASH_COMPAT
@@ -2053,6 +2054,10 @@ static void changepath(const char *) FAST_FUNC;
#if ENABLE_ASH_RANDOM_SUPPORT
static void change_random(const char *) FAST_FUNC;
#endif
+#if BASH_EPOCH_VARS
+static void change_seconds(const char *) FAST_FUNC;
+static void change_realtime(const char *) FAST_FUNC;
+#endif
static const struct {
int flags;
@@ -2079,6 +2084,10 @@ static const struct {
#if ENABLE_ASH_RANDOM_SUPPORT
{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
#endif
+#if BASH_EPOCH_VARS
+ { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHSECONDS", change_seconds },
+ { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHREALTIME", change_realtime },
+#endif
#if ENABLE_LOCALE_SUPPORT
{ VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL" , change_lc_all },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE" , change_lc_ctype },
@@ -2110,26 +2119,26 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
#define linenovar (G_var.linenovar )
#define vifs varinit[0]
#if ENABLE_ASH_MAIL
-# define vmail (&vifs)[1]
-# define vmpath (&vmail)[1]
-# define vpath (&vmpath)[1]
-#else
-# define vpath (&vifs)[1]
-#endif
-#define vps1 (&vpath)[1]
-#define vps2 (&vps1)[1]
-#define vps4 (&vps2)[1]
+# define vmail varinit[1]
+# define vmpath varinit[2]
+#endif
+#define VAR_OFFSET1 ENABLE_ASH_MAIL*2
+#define vpath varinit[VAR_OFFSET1 + 1]
+#define vps1 varinit[VAR_OFFSET1 + 2]
+#define vps2 varinit[VAR_OFFSET1 + 3]
+#define vps4 varinit[VAR_OFFSET1 + 4]
#if ENABLE_ASH_GETOPTS
-# define voptind (&vps4)[1]
-# define vlineno (&voptind)[1]
-# if ENABLE_ASH_RANDOM_SUPPORT
-# define vrandom (&vlineno)[1]
-# endif
-#else
-# define vlineno (&vps4)[1]
-# if ENABLE_ASH_RANDOM_SUPPORT
-# define vrandom (&vlineno)[1]
-# endif
+# define voptind varinit[VAR_OFFSET1 + 5]
+#endif
+#define VAR_OFFSET2 VAR_OFFSET1 + ENABLE_ASH_GETOPTS
+#define vlineno varinit[VAR_OFFSET2 + 5]
+#if ENABLE_ASH_RANDOM_SUPPORT
+# define vrandom varinit[VAR_OFFSET2 + 6]
+#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]
#endif
#define INIT_G_var() do { \
unsigned i; \
@@ -2268,7 +2277,7 @@ lookupvar(const char *name)
v = *findvar(hashvar(name), name);
if (v) {
-#if ENABLE_ASH_RANDOM_SUPPORT
+#if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS
/*
* Dynamic variables are implemented roughly the same way they are
* in bash. Namely, they're "special" so long as they aren't unset.
@@ -2364,7 +2373,7 @@ setvareq(char *s, int flags)
}
flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
-#if ENABLE_ASH_RANDOM_SUPPORT
+#if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS
if (flags & VUNSET)
flags &= ~VDYNAMIC;
#endif
@@ -11249,6 +11258,32 @@ change_random(const char *value)
}
#endif
+#if BASH_EPOCH_VARS
+static void FAST_FUNC
+change_epoch(struct var *vepoch, const char *fmt)
+{
+ struct timeval tv;
+ char buffer[32];
+
+ gettimeofday(&tv, NULL);
+ sprintf(buffer, fmt, tv.tv_sec, tv.tv_usec);
+ setvar(vepoch->var_text, buffer, VNOFUNC);
+ vepoch->flags &= ~VNOFUNC;
+}
+
+static void FAST_FUNC
+change_seconds(const char *value UNUSED_PARAM)
+{
+ change_epoch(&vepochs, "%ld");
+}
+
+static void FAST_FUNC
+change_realtime(const char *value UNUSED_PARAM)
+{
+ change_epoch(&vepochr, "%ld.%06ld");
+}
+#endif
+
#if ENABLE_ASH_GETOPTS
static int
getopts(char *optstr, char *optvar, char **optfirst)
--
2.20.1
More information about the busybox
mailing list