top: refresh interval accepts non-locale decimal value

For the past 3 years top has fully honored that locale
LC_NUMERIC setting which impacts his refresh interval.
For the past nearly 5 years top has saved that refresh
value in a locale independent form in his config file.

With this commit we'll intentionally break top so that
a comma or period will be accepted for the radix point
regardless of what that LC_NUMERIC may have suggested.

The current locale LC_NUMERIC will, however, determine
how the delay interval is displayed in the 'd' prompt.

[ This position is better than the approach employed ]
[ by those coreutils 'sleep' and 'timeout' programs. ]
[ Both claim to permit floating point arguments. But ]
[ neither one will accept the comma separator should ]
[ the locale be a country that in fact uses a comma. ]

Reference(s):
https://gitlab.com/procps-ng/procps/merge_requests/50

Prototyped by: Jan Rybar <jrybar@redhat.com>
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jan Rybar 2017-08-06 00:00:00 +02:00 committed by Craig Small
parent ac76e4db2c
commit d9c4b6b011
2 changed files with 17 additions and 6 deletions

1
NEWS
View File

@ -18,6 +18,7 @@ procps-ng-NEXT
* top: provides more accurate cpu usage at startup
* top: display NUMA node under which a thread ran
* top: fix argument parsing quirk resulting in SEGV Redhat #1450429
* top: delay interval accepts non-locale radix point Redhat #1182248
* watch: define HOST_NAME_MAX where not defined Debian #830734
procps-ng-3.3.12

View File

@ -1241,15 +1241,25 @@ static char *ioline (const char *prompt) {
/*
* Make locale aware float (but maybe restrict to whole numbers). */
* Make locale unaware float (but maybe restrict to whole numbers). */
static int mkfloat (const char *str, float *num, int whole) {
char *ep;
char tmp[SMLBUFSIZ], *ep;
if (whole)
if (whole) {
*num = (float)strtol(str, &ep, 0);
else
*num = strtof(str, &ep);
if (ep != str && *ep == '\0' && *num < INT_MAX)
if (ep != str && *ep == '\0' && *num < INT_MAX)
return 1;
return 0;
}
snprintf(tmp, sizeof(tmp), "%s", str);
*num = strtof(tmp, &ep);
if (*ep != '\0') {
// fallback - try to swap the floating point separator
if (*ep == '.') *ep = ',';
else if (*ep == ',') *ep = '.';
*num = strtof(tmp, &ep);
}
if (ep != tmp && *ep == '\0' && *num < INT_MAX)
return 1;
return 0;
} // end: mkfloat