From 6a047cd32e392aab4efd1c0dc6d8d56482d65138 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 8 Feb 2011 12:23:29 -0800 Subject: [PATCH] getloadavg: don't depend on c-strtod, cloexec, fcntl-safer See the thread rooted at . * lib/getloadavg.c: Do not include c-strtod.h, cloexec.h, or fcntl--.h. Include only if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 || (defined LOAD_AVE_TYPE && ! defined __VMS)); previously it was always included (via fcntl--.h). (getloadavg): Do not use c_strtod. Instead, approximate it by hand; this is good enough for load averages. Also, do not use set_cloexec_flag; instead, use the O_CLOEXEC and F_DUPFD_CLOEXEC flags directly if available and don't bother otherwise. (Packages that need the extra reliability should use the modules that define these flags on older platforms that lack them.) * modules/getloadavg (Depends-on): Remove c-strtod, cloexec, fcntl-safer. --- ChangeLog | 18 ++++++++++++++ lib/getloadavg.c | 59 +++++++++++++++++++++++++++++++++------------- modules/getloadavg | 3 --- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5f306b017e..579d16aeb6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2011-02-08 Paul Eggert + + getloadavg: don't depend on c-strtod, cloexec, fcntl-safer + See the thread rooted at + . + * lib/getloadavg.c: Do not include c-strtod.h, cloexec.h, or fcntl--.h. + Include only if (defined __linux__ || defined __CYGWIN__ + || defined SUNOS_5 || (defined LOAD_AVE_TYPE && ! defined + __VMS)); previously it was always included (via fcntl--.h). + (getloadavg): Do not use c_strtod. Instead, approximate it by + hand; this is good enough for load averages. Also, do not use + set_cloexec_flag; instead, use the O_CLOEXEC and F_DUPFD_CLOEXEC + flags directly if available and don't bother otherwise. (Packages + that need the extra reliability should use the modules that define + these flags on older platforms that lack them.) + * modules/getloadavg (Depends-on): Remove c-strtod, cloexec, + fcntl-safer. + 2011-02-08 Jim Meyering di-set.h, ino-map.h: add multiple-inclusion guard diff --git a/lib/getloadavg.c b/lib/getloadavg.c index 18a5960c6f..96a6aa4d49 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c @@ -108,8 +108,6 @@ # include # endif -# include "c-strtod.h" -# include "cloexec.h" # include "intprops.h" /* The existing Emacs configuration files define a macro called @@ -372,7 +370,6 @@ # endif /* NLIST_STRUCT */ # ifdef SUNOS_5 -# include # include # include # endif @@ -461,7 +458,10 @@ # include # endif -# include "fcntl--.h" +# if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 \ + || (defined LOAD_AVE_TYPE && ! defined __VMS)) +# include +# endif /* Avoid static vars inside a function since in HPUX they dump as pure. */ @@ -618,19 +618,30 @@ getloadavg (double loadavg[], int nelem) for (elem = 0; elem < nelem; elem++) { - char *endptr; - double d; + double numerator = 0; + double denominator = 1; + bool have_digit = false; + + while (*ptr == ' ') + ptr++; - errno = 0; - d = c_strtod (ptr, &endptr); - if (ptr == endptr || (d == 0 && errno != 0)) + /* Finish if this number is missing, and report an error if all + were missing. */ + if (! ('0' <= *ptr && *ptr <= '9')) { if (elem == 0) return -1; break; } - loadavg[elem] = d; - ptr = endptr; + + while ('0' <= *ptr && *ptr <= '9') + numerator = 10 * numerator + (*ptr++ - '0'); + + if (*ptr == '.') + for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) + numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; + + loadavg[elem++] = numerator / denominator; } return elem; @@ -940,13 +951,27 @@ getloadavg (double loadavg[], int nelem) if (!getloadavg_initialized) { # ifndef SUNOS_5 - channel = open ("/dev/kmem", O_RDONLY); - if (channel >= 0) + /* Set the channel to close on exec, so it does not + litter any child's descriptor table. */ +# ifndef O_CLOEXEC +# define O_CLOEXEC 0 +# endif + int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC); + if (0 <= fd) { - /* Set the channel to close on exec, so it does not - litter any child's descriptor table. */ - set_cloexec_flag (channel, true); - getloadavg_initialized = true; +# if F_DUPFD_CLOEXEC + if (fd <= STDERR_FILENO) + { + int fd1 = fcntl (fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1); + close (fd); + fd = fd1; + } +# endif + if (0 <= fd) + { + channel = fd; + getloadavg_initialized = true; + } } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names diff --git a/modules/getloadavg b/modules/getloadavg index 7865b8f048..fcbce4f7c5 100644 --- a/modules/getloadavg +++ b/modules/getloadavg @@ -6,10 +6,7 @@ lib/getloadavg.c m4/getloadavg.m4 Depends-on: -c-strtod -cloexec extensions -fcntl-safer intprops stdbool stdlib -- 2.30.2