summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacek Tomasiak <jtomasiak@arista.com>2023-02-06 13:39:44 +0100
committerPetr Vorel <pvorel@suse.cz>2023-02-07 17:25:59 +0100
commit33e78be2e60ed9ac918dec13271d1bd9dce6e94e (patch)
tree56a05f5d65a8395ad6bb1b6e91ba29125073d7c5
parente123cab36bea386be7daa88a25a3042816feb515 (diff)
downloadiputils-33e78be2e60ed9ac918dec13271d1bd9dce6e94e.tar.gz
ping: Fix the errno handling for strtod
The setlocale(LC_ALL, "") following the strtod() for the '-i' option can fail if the LC_CTYPE is invalid. Hence the errno check following the setlocale(LC_ALL, "") thinks wrongly that strtod() failed with the errno and prints a warning: $ LC_ALL=XXX ping -i 1.9 -c1 8.8.8.8 ping: option argument contains garbage: ping: this will become fatal error in the future PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=1.34 ms The errno got from the execution of strtod() is saved and restored after setlocale() to be checked for any errors. The problem is only on Fedora/CentOS/RHEL with applied patch [1] from 2012 for glibc bug #14247. [1] https://src.fedoraproject.org/rpms/glibc/blob/rawhide/f/glibc-rh827510.patch Link: https://sourceware.org/bugzilla/show_bug.cgi?id=14247 Closes: https://github.com/iputils/iputils/pull/450 Fixes: 918e824 ("ping: add support for sub-second timeouts") Co-Developed-by: Sriram Rajagopalan <sriramr@arista.com> Reviewed-by: Petr Vorel <pvorel@suse.cz> [ pvorel: mention glibc bug and Fedora/CentOS/RHEL ] Signed-off-by: Sriram Rajagopalan <sriramr@arista.com> Signed-off-by: Jacek Tomasiak <jtomasiak@arista.com>
-rw-r--r--ping/ping.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/ping/ping.c b/ping/ping.c
index 89b0fa1..8f44203 100644
--- a/ping/ping.c
+++ b/ping/ping.c
@@ -214,6 +214,7 @@ static double ping_strtod(const char *str, const char *err_msg)
{
double num;
char *end = NULL;
+ int strtod_errno = 0;
if (str == NULL || *str == '\0')
goto err;
@@ -225,7 +226,10 @@ static double ping_strtod(const char *str, const char *err_msg)
*/
setlocale(LC_ALL, "C");
num = strtod(str, &end);
+ strtod_errno = errno;
setlocale(LC_ALL, "");
+ /* Ignore setlocale() errno (e.g. invalid locale in env). */
+ errno = strtod_errno;
if (errno || str == end || (end && *end)) {
error(0, 0, _("option argument contains garbage: %s"), end);