diff options
author | Jacek Tomasiak <jtomasiak@arista.com> | 2023-02-06 13:39:44 +0100 |
---|---|---|
committer | Petr Vorel <pvorel@suse.cz> | 2023-02-07 17:25:59 +0100 |
commit | 33e78be2e60ed9ac918dec13271d1bd9dce6e94e (patch) | |
tree | 56a05f5d65a8395ad6bb1b6e91ba29125073d7c5 | |
parent | e123cab36bea386be7daa88a25a3042816feb515 (diff) | |
download | iputils-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.c | 4 |
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); |