]> granicus.if.org Git - procps-ng/commitdiff
top: refresh interval accepts non-locale decimal value
authorJan Rybar <jrybar@redhat.com>
Sat, 5 Aug 2017 22:00:00 +0000 (00:00 +0200)
committerCraig Small <csmall@enc.com.au>
Sat, 19 Aug 2017 10:46:39 +0000 (20:46 +1000)
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>
NEWS
top/top.c

diff --git a/NEWS b/NEWS
index 3b621d19ad1329981e65ba6121faa0d86e19ede5..f571b37fbbfa1dced1c7e41a75d27cd198eaa359 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
index b4b355ca9b9ff34c6880cde6063384568695cad7..25c124649fa595435e266b9c8d9f2aeaeb1585fe 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -1077,15 +1077,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