[PATCH] ash: add bash-compatible EPOCH variables
Denys Vlasenko
vda.linux at googlemail.com
Sun Apr 14 14:09:14 UTC 2019
On Tue, Apr 9, 2019 at 9:28 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.
Thanks!
Can you add them to hush too?
> 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
To protect from incorrect operator pairing after
macro expansion, use (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
and here too, use ()
> +#if BASH_EPOCH_VARS
> +static void FAST_FUNC
> +change_epoch(struct var *vepoch, const char *fmt)
> +{
> + struct timeval tv;
> + char buffer[32];
It's not immediately clear that 32 is enough.
(It theoretically wouldn't be if/when longs are >64 bits).
How about
char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3];
> + gettimeofday(&tv, NULL);
> + sprintf(buffer, fmt, tv.tv_sec, tv.tv_usec);
I propose
sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec);
(Unsigned long, not signed, because people do not acutely need
to support negative (before epoch) times, whereas people do prefer
their 32-bit systems to overflow and show garbage not in the year 2038,
but in the year 2106).
> + setvar(vepoch->var_text, buffer, VNOFUNC);
> + vepoch->flags &= ~VNOFUNC;
> +}
> +
> +static void FAST_FUNC
> +change_seconds(const char *value UNUSED_PARAM)
> +{
> + change_epoch(&vepochs, "%ld");
"%lu"
> +}
> +
> +static void FAST_FUNC
> +change_realtime(const char *value UNUSED_PARAM)
> +{
> + change_epoch(&vepochr, "%ld.%06ld");
"%lu.%06u"
More information about the busybox
mailing list