timeout,top,watch,ping: parse NN.N fractional duration in locales with other separators

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2021-03-23 13:50:02 +01:00
parent 14ed4ec8a4
commit c2bd0b6806
6 changed files with 16 additions and 6 deletions

View File

@ -122,6 +122,7 @@ static void FAST_FUNC conv_strtod(const char *arg, void *result)
char *end; char *end;
/* Well, this one allows leading whitespace... so what? */ /* Well, this one allows leading whitespace... so what? */
/* What I like much less is that "-" accepted too! :( */ /* What I like much less is that "-" accepted too! :( */
//TODO: needs setlocale(LC_NUMERIC, "C")?
*(double*)result = strtod(arg, &end); *(double*)result = strtod(arg, &end);
if (end[0]) { if (end[0]) {
errno = ERANGE; errno = ERANGE;

View File

@ -74,10 +74,6 @@ int sleep_main(int argc UNUSED_PARAM, char **argv)
sleep(INT_MAX); sleep(INT_MAX);
#if ENABLE_FEATURE_FANCY_SLEEP #if ENABLE_FEATURE_FANCY_SLEEP
# if ENABLE_FLOAT_DURATION
/* undo busybox.c setlocale */
setlocale(LC_NUMERIC, "C");
# endif
duration = 0; duration = 0;
do { do {
duration += parse_duration_str(*argv); duration += parse_duration_str(*argv);

View File

@ -295,6 +295,7 @@ static int compare_keys(const void *xarg, const void *yarg)
#if ENABLE_FEATURE_SORT_BIG #if ENABLE_FEATURE_SORT_BIG
case FLAG_g: { case FLAG_g: {
char *xx, *yy; char *xx, *yy;
//TODO: needs setlocale(LC_NUMERIC, "C")?
double dx = strtod(x, &xx); double dx = strtod(x, &xx);
double dy = strtod(y, &yy); double dy = strtod(y, &yy);
/* not numbers < NaN < -infinity < numbers < +infinity) */ /* not numbers < NaN < -infinity < numbers < +infinity) */

View File

@ -37,8 +37,18 @@ duration_t FAST_FUNC parse_duration_str(char *str)
if (strchr(str, '.')) { if (strchr(str, '.')) {
double d; double d;
char *pp; char *pp;
int len = strspn(str, "0123456789."); int len;
char sv = str[len]; char sv;
# if ENABLE_LOCALE_SUPPORT
/* Undo busybox.c: on input, we want to use dot
* as fractional separator in strtod(),
* regardless of current locale
*/
setlocale(LC_NUMERIC, "C");
# endif
len = strspn(str, "0123456789.");
sv = str[len];
str[len] = '\0'; str[len] = '\0';
errno = 0; errno = 0;
d = strtod(str, &pp); d = strtod(str, &pp);

View File

@ -229,6 +229,7 @@ static void stack_machine(const char *argument)
const struct op *o; const struct op *o;
next: next:
//TODO: needs setlocale(LC_NUMERIC, "C")?
number = strtod(argument, &end); number = strtod(argument, &end);
if (end != argument) { if (end != argument) {
argument = end; argument = end;

View File

@ -89,6 +89,7 @@ static unsigned str_to_jiffies(const char *time_str)
{ {
double dd; double dd;
char *endptr; char *endptr;
//TODO: needs setlocale(LC_NUMERIC, "C")?
dd = /*bb_*/strtod(time_str, &endptr); dd = /*bb_*/strtod(time_str, &endptr);
if (endptr == time_str || dd < 0) if (endptr == time_str || dd < 0)
bb_error_msg_and_die(bb_msg_invalid_arg_to, time_str, "timespec"); bb_error_msg_and_die(bb_msg_invalid_arg_to, time_str, "timespec");