summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-02-08 12:23:29 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2011-02-08 12:28:27 -0800
commit6a047cd32e392aab4efd1c0dc6d8d56482d65138 (patch)
tree6a85b92147a36f007cc9d0c20ff230f50e0de4dd
parentd9f5da66f7c95f84b6b28b17cfa4c5248ad2b591 (diff)
downloadgnulib-6a047cd32e392aab4efd1c0dc6d8d56482d65138.tar.gz
getloadavg: don't depend on c-strtod, cloexec, fcntl-safer
See the thread rooted at <http://lists.gnu.org/archive/html/bug-gnulib/2011-02/msg00090.html>. * lib/getloadavg.c: Do not include c-strtod.h, cloexec.h, or fcntl--.h. Include <fcntl.h> 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.
-rw-r--r--ChangeLog18
-rw-r--r--lib/getloadavg.c59
-rw-r--r--modules/getloadavg3
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 <eggert@cs.ucla.edu>
+
+ getloadavg: don't depend on c-strtod, cloexec, fcntl-safer
+ See the thread rooted at
+ <http://lists.gnu.org/archive/html/bug-gnulib/2011-02/msg00090.html>.
+ * lib/getloadavg.c: Do not include c-strtod.h, cloexec.h, or fcntl--.h.
+ Include <fcntl.h> 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 <meyering@redhat.com>
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 <sys/param.h>
# 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 <fcntl.h>
# include <kvm.h>
# include <kstat.h>
# endif
@@ -461,7 +458,10 @@
# include <sys/dg_sys_info.h>
# endif
-# include "fcntl--.h"
+# if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 \
+ || (defined LOAD_AVE_TYPE && ! defined __VMS))
+# include <fcntl.h>
+# 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