[PATCH v2 2/2] ash: add bash-compatible EPOCH variables

Denys Vlasenko vda.linux at googlemail.com
Tue Apr 16 16:32:23 UTC 2019


Applied all three patches. Thanks!

On Mon, Apr 15, 2019 at 11:52 AM Ron Yorston <rmy at pobox.com> wrote:
>
> 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                                           -      78     +78
> .rodata                                           175167  175235     +68
> varinit_data                                         264     312     +48
> change_seconds                                         -      24     +24
> change_realtime                                        -      24     +24
> ------------------------------------------------------------------------------
> (add/remove: 3/0 grow/shrink: 2/0 up/down: 242/0)             Total: 242 bytes
>    text    data     bss     dec     hex filename
>  938508    4203    1888  944599   e69d7 busybox_old
>  938702    4203    1888  944793   e6a99 busybox_unstripped
>
> v2: Cast tv_sec and tv_usec to unsigned quantities.
>     Add brackets to macros.
>
> 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..b707d00d0 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[sizeof("%lu.nnnnnn") + sizeof(long)*3];
> +
> +       gettimeofday(&tv, NULL);
> +       sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)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, "%lu");
> +}
> +
> +static void FAST_FUNC
> +change_realtime(const char *value UNUSED_PARAM)
> +{
> +       change_epoch(&vepochr, "%lu.%06u");
> +}
> +#endif
> +
>  #if ENABLE_ASH_GETOPTS
>  static int
>  getopts(char *optstr, char *optvar, char **optfirst)
> --
> 2.20.1
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list