bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New MILLISECONDS “special” variable?


From: Eduardo A . Bustamante López
Subject: Re: New MILLISECONDS “special” variable?
Date: Wed, 1 Nov 2017 20:48:29 -0600
User-agent: NeoMutt/20170609 (1.8.3)

On Wed, Nov 01, 2017 at 01:19:08PM -0700, Alan Dipert wrote:
[...]
> I can imagine many reasons not to add a new variable, including the fact
> that it could change the behavior of existing scripts. It may also be the
> case that there’s already a method to get sub-second times without shelling
> out, and so I’d be grateful for pointers to any existing solutions.
[...]

Probably the easiest option is to implement this as a loadable builtin:

$ src=~/src/gnu; gcc -fPIC -g -O0 -I $src/bash/ -I $src/bash/include -I 
$src/build-bash-devel/ -I $src/bash/examples/loadables/ -I $src/bash/builtins/ 
-c -o timer.o timer.c
$ gcc -shared -Wl,-soname,timer -o timer timer.o
$ enable -f ./timer timer
$ timer current delta
$ echo $current, $delta
1509589044.350954, 0.0
$ timer current delta
$ echo $current, $delta
1509589059.42946, 14.691992
$ timer current delta; sleep 3.14; timer current delta; echo $delta
3.143473

Given this, I don't see a reason to add this functionality to bash itself.

Below is the (buggy and ugly) implementation of the `timer' loadable builtin:

---
#include <config.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

#include "loadables.h"

/* FIXME: do better validation */
static int parse_timeval (const char *s, struct timeval *tv) {
  char *ds;
  timerclear(tv);
  tv->tv_sec = strtol(s, &ds, 10);
  if (ds && *ds == '.') {
    tv->tv_usec = strtol(ds + 1, NULL, 10);
  }
  return 0;
}

int timer_builtin (WORD_LIST *list) {
  struct timeval tv1, tv2, tv3;
  char *s, *current, *delta;
  char b1[64], b2[64]; /* FIXME */

  if (0 == list) {
    return (EXECUTION_FAILURE);
  }

  current = list->word->word;
  if (0 == current || 0 == *current) {
    return (EXECUTION_FAILURE);
  }

  if (0 == list->next) {
    return (EXECUTION_FAILURE);
  }

  delta = list->next->word->word;
  if (0 == delta || 0 == *delta) {
    return (EXECUTION_FAILURE);
  }

  if (-1 == gettimeofday(&tv1, NULL)) {
    return (EXECUTION_FAILURE);
  }

  s = get_string_value (current);
  if (0 == s) {
    bind_variable (delta, "0.0", 0);
    goto update_value;
  }

  parse_timeval (s, &tv2);
  timersub (&tv1, &tv2, &tv3);
  snprintf (b2, 64, "%ld.%ld", tv3.tv_sec, tv3.tv_usec);
  bind_variable (delta, b2, 0);

  update_value:
  snprintf (b1, 64, "%ld.%ld", tv1.tv_sec, tv1.tv_usec);
  bind_variable (current, b1, 0);

  return (EXECUTION_SUCCESS);
}

char *timer_doc[] = {
  "...",
  "",
  "...",
  (char *)NULL
};

struct builtin timer_struct = {
  "timer",
  timer_builtin,
  BUILTIN_ENABLED,
  timer_doc,
  "timer CURRENT DELTA",
  0
};



reply via email to

[Prev in Thread] Current Thread [Next in Thread]