busybox/libbb/duration.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Utility routines.
   4 *
   5 * Copyright (C) 2018 Denys Vlasenko
   6 *
   7 * Licensed under GPLv2, see file LICENSE in this source tree.
   8 */
   9//config:config FLOAT_DURATION
  10//config:       bool "Enable fractional duration arguments"
  11//config:       default y
  12//config:       help
  13//config:       Allow sleep N.NNN, top -d N.NNN etc.
  14
  15//kbuild:lib-$(CONFIG_SLEEP)   += duration.o
  16//kbuild:lib-$(CONFIG_TOP)     += duration.o
  17//kbuild:lib-$(CONFIG_TIMEOUT) += duration.o
  18//kbuild:lib-$(CONFIG_PING)    += duration.o
  19//kbuild:lib-$(CONFIG_PING6)   += duration.o
  20
  21#include "libbb.h"
  22
  23static const struct suffix_mult duration_suffixes[] = {
  24        { "s", 1 },
  25        { "m", 60 },
  26        { "h", 60*60 },
  27        { "d", 24*60*60 },
  28        { "", 0 }
  29};
  30
  31#if ENABLE_FLOAT_DURATION
  32duration_t FAST_FUNC parse_duration_str(char *str)
  33{
  34        duration_t duration;
  35
  36        if (strchr(str, '.')) {
  37                double d;
  38                char *pp;
  39                int len = strspn(str, "0123456789.");
  40                char sv = str[len];
  41                str[len] = '\0';
  42                errno = 0;
  43                d = strtod(str, &pp);
  44                if (errno || *pp)
  45                        bb_show_usage();
  46                str += len;
  47                *str-- = sv;
  48                sv = *str;
  49                *str = '1';
  50                duration = d * xatoul_sfx(str, duration_suffixes);
  51                *str = sv;
  52        } else {
  53                duration = xatoul_sfx(str, duration_suffixes);
  54        }
  55
  56        return duration;
  57}
  58void FAST_FUNC sleep_for_duration(duration_t duration)
  59{
  60        struct timespec ts;
  61
  62        ts.tv_sec = MAXINT(typeof(ts.tv_sec));
  63        ts.tv_nsec = 0;
  64        if (duration >= 0 && duration < ts.tv_sec) {
  65                ts.tv_sec = duration;
  66                ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
  67        }
  68        do {
  69                errno = 0;
  70                nanosleep(&ts, &ts);
  71        } while (errno == EINTR);
  72}
  73#else
  74duration_t FAST_FUNC parse_duration_str(char *str)
  75{
  76        return xatou_range_sfx(str, 0, UINT_MAX, duration_suffixes);
  77}
  78#endif
  79