mirror of
https://github.com/sheumann/hush.git
synced 2024-12-27 01:32:08 +00:00
sleep: if FANCY && DESKTOP, support fractional seconds, minutes,
hours and so on. It's coreutils compat. bloatcheck is atrocious :( function old new delta sleep_main 71 362 +291 bb_strtod - 127 +127 make_device 1269 1294 +25 getoptscmd 708 713 +5 switch_root_main 402 401 -1 display_speed 90 85 -5 show_entry 295 289 -6 parse_expr 841 833 -8 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/4 up/down: 448/-20) Total: 428 bytes
This commit is contained in:
parent
34e8f6a7ac
commit
adbb73bda7
@ -36,28 +36,69 @@ static const struct suffix_mult sfx[] = {
|
||||
int sleep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int sleep_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
#if ENABLE_FEATURE_FANCY_SLEEP && ENABLE_DESKTOP
|
||||
double duration;
|
||||
struct timespec ts;
|
||||
#else
|
||||
unsigned duration;
|
||||
#endif
|
||||
|
||||
++argv;
|
||||
if (!*argv)
|
||||
bb_show_usage();
|
||||
|
||||
#if ENABLE_FEATURE_FANCY_SLEEP
|
||||
#if ENABLE_FEATURE_FANCY_SLEEP && ENABLE_DESKTOP
|
||||
|
||||
duration = 0;
|
||||
do {
|
||||
duration += xatoul_range_sfx(*argv, 0, UINT_MAX-duration, sfx);
|
||||
char *arg = *argv;
|
||||
if (strchr(arg, '.')) {
|
||||
double d;
|
||||
int len = strspn(arg, "0123456789.");
|
||||
char sv = arg[len];
|
||||
arg[len] = '\0';
|
||||
d = bb_strtod(arg, NULL);
|
||||
if (errno)
|
||||
bb_show_usage();
|
||||
arg[len] = sv;
|
||||
len--;
|
||||
sv = arg[len];
|
||||
arg[len] = '1';
|
||||
duration += d * xatoul_sfx(&arg[len], sfx);
|
||||
arg[len] = sv;
|
||||
} else
|
||||
duration += xatoul_sfx(arg, sfx);
|
||||
} while (*++argv);
|
||||
|
||||
#else /* FEATURE_FANCY_SLEEP */
|
||||
ts.tv_sec = MAXINT(typeof(ts.tv_sec));
|
||||
ts.tv_nsec = 0;
|
||||
if (duration >= 0 && duration < ts.tv_sec) {
|
||||
ts.tv_sec = duration;
|
||||
ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
|
||||
}
|
||||
do {
|
||||
errno = 0;
|
||||
nanosleep(&ts, &ts);
|
||||
} while (errno == EINTR);
|
||||
|
||||
#elif ENABLE_FEATURE_FANCY_SLEEP
|
||||
|
||||
duration = 0;
|
||||
do {
|
||||
duration += xatou_range_sfx(*argv, 0, UINT_MAX - duration, sfx);
|
||||
} while (*++argv);
|
||||
sleep(duration);
|
||||
|
||||
#else /* simple */
|
||||
|
||||
duration = xatou(*argv);
|
||||
sleep(duration);
|
||||
// Off. If it's really needed, provide example why
|
||||
//if (sleep(duration)) {
|
||||
// bb_perror_nomsg_and_die();
|
||||
//}
|
||||
|
||||
#endif /* FEATURE_FANCY_SLEEP */
|
||||
|
||||
if (sleep(duration)) {
|
||||
bb_perror_nomsg_and_die();
|
||||
}
|
||||
#endif
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ uint32_t bb_strtou32(const char *arg, char **endp, int base)
|
||||
|
||||
/* Floating point */
|
||||
|
||||
/* double bb_strtod(const char *arg, char **endp); */
|
||||
double bb_strtod(const char *arg, char **endp) FAST_FUNC;
|
||||
|
||||
#if __GNUC_PREREQ(4,1)
|
||||
# pragma GCC visibility pop
|
||||
|
@ -13,6 +13,7 @@ lib-y += bb_basename.o
|
||||
lib-y += bb_do_delay.o
|
||||
lib-y += bb_pwd.o
|
||||
lib-y += bb_qsort.o
|
||||
lib-y += bb_strtod.o
|
||||
lib-y += bb_strtonum.o
|
||||
lib-y += change_identity.o
|
||||
lib-y += chomp.o
|
||||
|
85
libbb/bb_strtod.c
Normal file
85
libbb/bb_strtod.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Utility routines.
|
||||
*
|
||||
* Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
|
||||
*
|
||||
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
||||
*/
|
||||
|
||||
#include "libbb.h"
|
||||
#include <math.h> /* just for HUGE_VAL */
|
||||
|
||||
#define NOT_DIGIT(a) (((unsigned char)(a-'0')) > 9)
|
||||
|
||||
double FAST_FUNC bb_strtod(const char *arg, char **endp)
|
||||
{
|
||||
double v;
|
||||
char *endptr;
|
||||
|
||||
if (arg[0] != '-' && NOT_DIGIT(arg[0]))
|
||||
goto err;
|
||||
errno = 0;
|
||||
v = strtod(arg, &endptr);
|
||||
if (endp)
|
||||
*endp = endptr;
|
||||
if (endptr[0]) {
|
||||
/* "1234abcg" or out-of-range? */
|
||||
if (isalnum(endptr[0]) || errno) {
|
||||
err:
|
||||
errno = ERANGE;
|
||||
return HUGE_VAL;
|
||||
}
|
||||
/* good number, just suspicious terminator */
|
||||
errno = EINVAL;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* String to timespec: "NNNN[.NNNNN]" -> struct timespec.
|
||||
* Can be used for other fixed-point needs.
|
||||
* Returns pointer past last converted char,
|
||||
* and returns errno similar to bb_strtoXX functions.
|
||||
*/
|
||||
char* FAST_FUNC bb_str_to_ts(struct timespec *ts, const char *arg)
|
||||
{
|
||||
if (sizeof(ts->tv_sec) <= sizeof(int))
|
||||
ts->tv_sec = bb_strtou(arg, &arg, 10);
|
||||
else if (sizeof(ts->tv_sec) <= sizeof(long))
|
||||
ts->tv_sec = bb_strtoul(arg, &arg, 10);
|
||||
else
|
||||
ts->tv_sec = bb_strtoull(arg, &arg, 10);
|
||||
ts->tv_nsec = 0;
|
||||
|
||||
if (*arg != '.')
|
||||
return arg;
|
||||
|
||||
/* !EINVAL: number is not ok (alphanumeric ending, overflow etc) */
|
||||
if (errno != EINVAL)
|
||||
return arg;
|
||||
|
||||
if (!*++arg) /* "NNN." */
|
||||
return arg;
|
||||
|
||||
{ /* "NNN.xxx" - parse xxx */
|
||||
int ndigits;
|
||||
char *p;
|
||||
char buf[10]; /* we never use more than 9 digits */
|
||||
|
||||
/* Need to make a copy to avoid false overflow */
|
||||
safe_strncpy(buf, arg, 10);
|
||||
ts->tv_nsec = bb_strtou(buf, &p, 10);
|
||||
ndigits = p - buf;
|
||||
arg += ndigits;
|
||||
/* normalize to nsec */
|
||||
while (ndigits < 9) {
|
||||
ndigits++;
|
||||
ts->tv_nsec *= 10;
|
||||
}
|
||||
while (isdigit(*arg)) /* skip possible 10th plus digits */
|
||||
arg++;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
#endif
|
@ -124,33 +124,3 @@ int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base)
|
||||
return handle_errors(v, endp, endptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Floating point */
|
||||
|
||||
#if 0
|
||||
|
||||
#include <math.h> /* just for HUGE_VAL */
|
||||
#define NOT_DIGIT(a) (((unsigned char)(a-'0')) > 9)
|
||||
double FAST_FUNC bb_strtod(const char *arg, char **endp)
|
||||
{
|
||||
double v;
|
||||
char *endptr;
|
||||
|
||||
if (arg[0] != '-' && NOT_DIGIT(arg[0])) goto err;
|
||||
errno = 0;
|
||||
v = strtod(arg, &endptr);
|
||||
if (endp) *endp = endptr;
|
||||
if (endptr[0]) {
|
||||
/* "1234abcg" or out-of-range? */
|
||||
if (isalnum(endptr[0]) || errno) {
|
||||
err:
|
||||
errno = ERANGE;
|
||||
return HUGE_VAL;
|
||||
}
|
||||
/* good number, just suspicious terminator */
|
||||
errno = EINVAL;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user