hush: add bash-compatible EPOCH variables
authorRon Yorston <rmy@pobox.com>
Mon, 15 Apr 2019 09:48:29 +0000 (10:48 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 16 Apr 2019 16:29:52 +0000 (18:29 +0200)
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
get_local_var_value                                  207     302     +95
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 95/0)               Total: 95 bytes
   text    data     bss     dec     hex filename
 938702    4203    1888  944793   e6a99 busybox_old
 938797    4203    1888  944888   e6af8 busybox_unstripped

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/hush.c

index fa9afa38ede1daac79143440f332e6c5c15a93aa..d745148f4a3ec8b568884996ca87bc107d0f7344 100644 (file)
 #define BASH_SUBSTR        ENABLE_HUSH_BASH_COMPAT
 #define BASH_SOURCE        ENABLE_HUSH_BASH_COMPAT
 #define BASH_HOSTNAME_VAR  ENABLE_HUSH_BASH_COMPAT
+#define BASH_EPOCH_VARS    ENABLE_HUSH_BASH_COMPAT
 #define BASH_TEST2         (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
 #define BASH_READ_D        ENABLE_HUSH_BASH_COMPAT
 
@@ -1011,6 +1012,9 @@ struct globals {
        int debug_indent;
 #endif
        struct sigaction sa;
+#if BASH_EPOCH_VARS
+       char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
+#endif
 #if ENABLE_FEATURE_EDITING
        char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
 #endif
@@ -2227,6 +2231,22 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
 #if ENABLE_HUSH_RANDOM_SUPPORT
        if (strcmp(name, "RANDOM") == 0)
                return utoa(next_random(&G.random_gen));
+#endif
+#if BASH_EPOCH_VARS
+       {
+               const char *fmt = NULL;
+               if (strcmp(name, "EPOCHSECONDS") == 0)
+                       fmt = "%lu";
+               else if (strcmp(name, "EPOCHREALTIME") == 0)
+                       fmt = "%lu.%06u";
+               if (fmt) {
+                       struct timeval tv;
+                       gettimeofday(&tv, NULL);
+                       sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec,
+                                       (unsigned)tv.tv_usec);
+                       return G.epoch_buf;
+               }
+       }
 #endif
        return NULL;
 }